/* * SPDX-FileCopyrightText: 2021-2024 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 *//* ... */#include<time.h>#include<errno.h>#include<pthread.h>#include<string.h>#include<stdatomic.h>#include"esp_err.h"#include"esp_attr.h"#include"sys/queue.h"#include"freertos/FreeRTOS.h"#include"freertos/task.h"#include"freertos/semphr.h"#include"soc/soc_memory_layout.h"#include"pthread_internal.h"#include"esp_pthread.h"#include"esp_log.h"15 includesconststaticchar*TAG="pthread_rw_lock";/** pthread rw_mutex FreeRTOS wrapper */typedefstruct{/** * *//* ... */pthread_cond_tcv;pthread_mutex_tresource_mutex;/** * Number of current readers holding this lock, negative number means waiting readers *//* ... */int8_tactive_readers;uint8_tactive_writers;uint8_twaiting_writers;}{ ... }esp_pthread_rwlock_t;#defineWRITER_QUEUE_SIZE4#defineREADER_QUEUE_SIZE4intpthread_rwlock_init(pthread_rwlock_t*rwlock,constpthread_rwlockattr_t*attr){intresult;if(!rwlock){returnEINVAL;}{...}if(attr){// TODO: implement attributes in IDF-4284returnENOSYS;}{...}esp_pthread_rwlock_t*esp_rwlock=(esp_pthread_rwlock_t*)calloc(1,sizeof(esp_pthread_rwlock_t));if(esp_rwlock==NULL){returnENOMEM;}{...}result=pthread_mutex_init(&esp_rwlock->resource_mutex,NULL);if(result!=0){free(esp_rwlock);returnENOMEM;}{...}result=pthread_cond_init(&esp_rwlock->cv,NULL);if(result!=0){pthread_mutex_destroy(&esp_rwlock->resource_mutex);free(esp_rwlock);returnENOMEM;}{...}esp_rwlock->active_readers=0;esp_rwlock->active_writers=0;esp_rwlock->waiting_writers=0;*rwlock=(pthread_rwlock_t)esp_rwlock;return0;}{ ... }staticintpthread_rwlock_init_if_static(pthread_rwlock_t*rwlock){intres=0;if((intptr_t)*rwlock==PTHREAD_RWLOCK_INITIALIZER){portENTER_CRITICAL(&pthread_lazy_init_lock);if((intptr_t)*rwlock==PTHREAD_RWLOCK_INITIALIZER){res=pthread_rwlock_init(rwlock,NULL);}{...}portEXIT_CRITICAL(&pthread_lazy_init_lock);}{...}returnres;}{ ... }intpthread_rwlock_destroy(pthread_rwlock_t*rwlock){esp_pthread_rwlock_t*esp_rwlock;ESP_LOGV(TAG,"%s %p",__FUNCTION__,rwlock);if(!rwlock){returnEINVAL;}{...}if((intptr_t)*rwlock==PTHREAD_RWLOCK_INITIALIZER){return0;// Static rwlock was never initialized}{...}esp_rwlock=(esp_pthread_rwlock_t*)*rwlock;if(esp_rwlock==NULL){returnEINVAL;}{...}// TODO: necessary?pthread_mutex_lock(&esp_rwlock->resource_mutex);if(esp_rwlock->active_readers!=0||esp_rwlock->active_writers>0||esp_rwlock->waiting_writers>0){pthread_mutex_unlock(&esp_rwlock->resource_mutex);returnEBUSY;}{...}// delete whole lockpthread_cond_destroy(&esp_rwlock->cv);pthread_mutex_unlock(&esp_rwlock->resource_mutex);pthread_mutex_destroy(&esp_rwlock->resource_mutex);free(esp_rwlock);return0;}{ ... }staticintcheckrw_lock(pthread_rwlock_t*rwlock){esp_pthread_rwlock_t*esp_rwlock;intres;if(rwlock==NULL){returnEINVAL;}{...}res=pthread_rwlock_init_if_static(rwlock);if(res!=0){returnres;}{...}esp_rwlock=(esp_pthread_rwlock_t*)*rwlock;if(esp_rwlock==NULL){returnEINVAL;}{...}return0;}{ ... }intpthread_rwlock_rdlock(pthread_rwlock_t*rwlock){esp_pthread_rwlock_t*esp_rwlock;intres;res=checkrw_lock(rwlock);if(res!=0){returnres;}{...}esp_rwlock=(esp_pthread_rwlock_t*)*rwlock;res=pthread_mutex_lock(&esp_rwlock->resource_mutex);if(res!=0){returnres;}{...}if(esp_rwlock->active_writers==0){esp_rwlock->active_readers++;}{...}else{while(true){pthread_cond_wait(&esp_rwlock->cv,&esp_rwlock->resource_mutex);if(esp_rwlock->active_writers==0&&esp_rwlock->waiting_writers==0){esp_rwlock->active_readers++;break;}{...}}{...}}{...}pthread_mutex_unlock(&esp_rwlock->resource_mutex);return0;}{ ... }intpthread_rwlock_tryrdlock(pthread_rwlock_t*rwlock){esp_pthread_rwlock_t*esp_rwlock;intres;res=checkrw_lock(rwlock);if(res!=0){returnres;}{...}esp_rwlock=(esp_pthread_rwlock_t*)*rwlock;res=pthread_mutex_trylock(&esp_rwlock->resource_mutex);if(res!=0){returnres;}{...}if(esp_rwlock->active_writers==0){esp_rwlock->active_readers++;res=0;}{...}else{res=EBUSY;}{...}pthread_mutex_unlock(&esp_rwlock->resource_mutex);returnres;}{ ... }intpthread_rwlock_wrlock(pthread_rwlock_t*rwlock){esp_pthread_rwlock_t*esp_rwlock;intres;res=checkrw_lock(rwlock);if(res!=0){returnres;}{...}esp_rwlock=(esp_pthread_rwlock_t*)*rwlock;res=pthread_mutex_lock(&esp_rwlock->resource_mutex);if(res!=0){returnres;}{...}esp_rwlock->waiting_writers++;while(esp_rwlock->active_readers>0||esp_rwlock->active_writers>0){pthread_cond_wait(&esp_rwlock->cv,&esp_rwlock->resource_mutex);}{...}esp_rwlock->waiting_writers--;esp_rwlock->active_writers++;pthread_mutex_unlock(&esp_rwlock->resource_mutex);return0;}{ ... }intpthread_rwlock_trywrlock(pthread_rwlock_t*rwlock){esp_pthread_rwlock_t*esp_rwlock;intres;res=checkrw_lock(rwlock);if(res!=0){returnres;}{...}esp_rwlock=(esp_pthread_rwlock_t*)*rwlock;res=pthread_mutex_trylock(&esp_rwlock->resource_mutex);if(res!=0){returnres;}{...}if(esp_rwlock->active_readers>0||esp_rwlock->active_writers>0||esp_rwlock->waiting_writers>0){// the last check for waiting_writers is to avoid skipping the queueres=EBUSY;}{...}else{esp_rwlock->active_writers++;res=0;}{...}pthread_mutex_unlock(&esp_rwlock->resource_mutex);returnres;}{ ... }intpthread_rwlock_unlock(pthread_rwlock_t*rwlock){esp_pthread_rwlock_t*esp_rwlock;intres;res=checkrw_lock(rwlock);if(res!=0){returnres;}{...}esp_rwlock=(esp_pthread_rwlock_t*)*rwlock;res=pthread_mutex_lock(&esp_rwlock->resource_mutex);if(res!=0){returnres;}{...}assert(!(esp_rwlock->active_readers>0&&esp_rwlock->active_writers>0));if(esp_rwlock->active_readers>0){// we are a readeresp_rwlock->active_readers--;if(esp_rwlock->active_readers==0){pthread_cond_broadcast(&esp_rwlock->cv);}{...}}{...}else{// we are a writeresp_rwlock->active_writers=0;pthread_cond_broadcast(&esp_rwlock->cv);}{...}pthread_mutex_unlock(&esp_rwlock->resource_mutex);return0;}{ ... }/* Hook function to force linking this file */voidpthread_include_pthread_rwlock_impl(void){}{ ... }
Details
Show: from
Types: Columns:
All items filtered out
All items filtered out
This file uses the notable symbols shown below. Click anywhere in the file to view more details.