rsys

Basic data structures and low-level features
git clone git://git.meso-star.fr/rsys.git
Log | Files | Refs | README | LICENSE

commit 4280b69061b7ee042fed6418da65e63a52ed112e
parent edaf3a772e3fa62d7a526e7a29402838a3c52006
Author: vaplv <vaplv@free.fr>
Date:   Sat, 11 Jan 2014 22:54:02 +0100

Change the condition API and its pthread implementation

Diffstat:
Msrc/CMakeLists.txt | 9++++-----
Msrc/condition.h | 17++++++-----------
Msrc/mutex.h | 75+++++++++++++--------------------------------------------------------------
Dsrc/pthread/condition.h | 47-----------------------------------------------
Asrc/pthread/pthread_condition.c | 50++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/pthread/pthread_mutex.c | 2--
Msrc/test_condition.c | 79+++++++++++++++++++++++++++++++++++++++++++++----------------------------------
Msrc/test_mutex.c | 2+-
8 files changed, 119 insertions(+), 162 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -44,6 +44,7 @@ set(RSYS_FILES_SRC image.c library.c mem_allocator.c + pthread/pthread_condition.c pthread/pthread_mutex.c) set(RSYS_FILES_INC_COMMON atomic.h @@ -96,12 +97,10 @@ new_test(test_time rsys) if(NOT OPENMP_FOUND) message(STATUS "No OpenMP support: multi-threaded tests cannot be generated") else() -# new_test(test_condition) + new_test(test_condition rsys) new_test(test_mutex rsys) - set_target_properties(test_mutex PROPERTIES COMPILE_FLAGS ${OpenMP_C_FLAGS}) - set_target_properties(test_mutex PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) -# set_target_properties(test_mutex test_condition PROPERTIES COMPILE_FLAGS ${OpenMP_C_FLAGS}) -# set_target_properties(test_mutex test_condition PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) + set_target_properties(test_mutex test_condition PROPERTIES COMPILE_FLAGS ${OpenMP_C_FLAGS}) + set_target_properties(test_mutex test_condition PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) endif() ################################################################################ diff --git a/src/condition.h b/src/condition.h @@ -5,18 +5,13 @@ #include "mutex.h" struct cond; +struct mutex; -static FINLINE void cond_init(struct cond* cond); -static FINLINE void cond_destroy(struct cond* cond); -static FINLINE void cond_wait(struct cond* cond, struct mutex* mutex); -static FINLINE void cond_signal(struct cond* cond); -static FINLINE void cond_broadcast(struct cond* cond); - -#ifdef RSYS_USE_PTHREADS - #include "pthread/condition.h" -#else - #error "No supported thread library is defined" -#endif +RSYS_API struct cond* cond_create(void); /* NULL <=> error */ +RSYS_API void cond_destroy(struct cond* cond); +RSYS_API void cond_wait(struct cond* cond, struct mutex* mutex); +RSYS_API void cond_signal(struct cond* cond); +RSYS_API void cond_broadcast(struct cond* cond); #endif /* CONDITION_H */ diff --git a/src/mutex.h b/src/mutex.h @@ -7,72 +7,24 @@ extern "C" { #endif -/******************************************************************************* - * Common mutex - ******************************************************************************/ struct mutex; +RSYS_API struct mutex* mutex_create(void); /* NULL <=> error */ +RSYS_API void mutex_destroy(struct mutex* mutex); +RSYS_API void mutex_lock(struct mutex* mutex); +RSYS_API void mutex_unlock(struct mutex* mutex); -RSYS_API struct mutex* -mutex_create /* Return NULL if an error occur */ - (void); - -RSYS_API void -mutex_destroy - (struct mutex* mutex); - -RSYS_API void -mutex_lock - (struct mutex* mutex); - -RSYS_API void -mutex_unlock - (struct mutex* mutex); - -/******************************************************************************* - * Spin lock mutex - ******************************************************************************/ struct mutex_spin; +RSYS_API struct mutex_spin* mutex_spin_create(void); /* NULL <=> error */ +RSYS_API void mutex_spin_destroy(struct mutex_spin* mutex); +RSYS_API void mutex_spin_lock(struct mutex_spin* mutex); +RSYS_API void mutex_spin_unlock(struct mutex_spin* mutex); -RSYS_API struct mutex_spin* -mutex_spin_create - (void); - -RSYS_API void -mutex_spin_destroy - (struct mutex_spin* mutex); - -RSYS_API void -mutex_spin_lock - (struct mutex_spin* mutex); - -RSYS_API void -mutex_spin_unlock - (struct mutex_spin* mutex); - -/******************************************************************************* - * Read write mutex - ******************************************************************************/ struct mutex_rw; - -RSYS_API struct mutex_rw* -mutex_rw_create - (void); - -RSYS_API void -mutex_rw_destroy - (struct mutex_rw* mutex); - -RSYS_API void -mutex_rw_rlock - (struct mutex_rw* mutex); - -RSYS_API void -mutex_rw_wlock - (struct mutex_rw* mutex); - -RSYS_API void -mutex_rw_unlock - (struct mutex_rw* mutex); +RSYS_API struct mutex_rw* mutex_rw_create(void);/* NULL <=> error */ +RSYS_API void mutex_rw_destroy(struct mutex_rw* mutex); +RSYS_API void mutex_rw_rlock(struct mutex_rw* mutex); +RSYS_API void mutex_rw_wlock(struct mutex_rw* mutex); +RSYS_API void mutex_rw_unlock(struct mutex_rw* mutex); #ifdef __cplusplus } /* extern "C" */ @@ -80,4 +32,3 @@ mutex_rw_unlock #endif /* MUTEX_H */ - diff --git a/src/pthread/condition.h b/src/pthread/condition.h @@ -1,47 +0,0 @@ -#include <pthread.h> - -#ifdef NDEBUG - #define PTHREAD__(Func) pthread_##Func -#else - #define PTHREAD__(Func) ASSERT(pthread_##Func == 0) -#endif - -struct cond { pthread_cond_t cond__; }; - -void -cond_init(struct cond* cond) -{ - ASSERT(cond); - PTHREAD__(cond_init(&cond->cond__, NULL)); -} - -void -cond_destroy(struct cond* cond) -{ - ASSERT(cond); - PTHREAD__(cond_destroy(&cond->cond__)); -} - -void -cond_wait(struct cond* cond, struct mutex* mutex) -{ - ASSERT(cond); - PTHREAD__(cond_wait(&cond->cond__, &mutex->mutex__)); -} - -void -cond_signal(struct cond* cond) -{ - ASSERT(cond); - PTHREAD__(cond_signal(&cond->cond__)); -} - -void -cond_broadcast(struct cond* cond) -{ - ASSERT(cond); - PTHREAD__(cond_broadcast(&cond->cond__)); -} - -#undef PTHREAD__ - diff --git a/src/pthread/pthread_condition.c b/src/pthread/pthread_condition.c @@ -0,0 +1,50 @@ +#include "../condition.h" +#include "../mem_allocator.h" +#include <pthread.h> + +#ifdef NDEBUG + #define PTHREAD(Func) pthread_##Func +#else + #define PTHREAD(Func) ASSERT(pthread_##Func == 0) +#endif + +struct cond* +cond_create(void) +{ + pthread_cond_t* cond = mem_alloc(sizeof(pthread_cond_t)); + if(cond) + PTHREAD(cond_init(cond, NULL)); + return (struct cond*)cond; +} + +void +cond_destroy(struct cond* cond) +{ + ASSERT(cond); + PTHREAD(cond_destroy((pthread_cond_t*)cond)); + mem_free(cond); +} + +void +cond_wait(struct cond* cond, struct mutex* mutex) +{ + ASSERT(cond); + PTHREAD(cond_wait((pthread_cond_t*)cond, (pthread_mutex_t*)mutex)); +} + +void +cond_signal(struct cond* cond) +{ + ASSERT(cond); + PTHREAD(cond_signal((pthread_cond_t*)cond)); +} + +void +cond_broadcast(struct cond* cond) +{ + ASSERT(cond); + PTHREAD(cond_broadcast((pthread_cond_t*)cond)); +} + +#undef PTHREAD + diff --git a/src/pthread/pthread_mutex.c b/src/pthread/pthread_mutex.c @@ -80,8 +80,6 @@ mutex_spin_unlock(struct mutex_spin* mutex) /******************************************************************************* * Read Write mutex ******************************************************************************/ -struct mutex_rw { pthread_rwlock_t mutex__; }; - struct mutex_rw* mutex_rw_create(void) { diff --git a/src/test_condition.c b/src/test_condition.c @@ -5,7 +5,7 @@ static const char* src_str[] = { "Rcvfbqr 1, XARR-QRRC VA GUR QRNQ:\n\ ----------------------------------\n\ +----------------------------------\ \n\ BAPR LBH ORNG GUR OVT ONQNFFRF NAQ PYRNA BHG GUR ZBBA ONFR LBH'ER FHCCBFRQ GB\n\ JVA, NERA'G LBH? NERA'G LBH? JURER'F LBHE SNG ERJNEQ NAQ GVPXRG UBZR? JUNG\n\ @@ -18,7 +18,7 @@ GB PBAGVAHR GUR QBBZ RKCREVRAPR, CYNL GUR FUBERF BS URYY NAQ VGF NZNMVAT\n\ FRDHRY, VASREAB!", "Rcvfbqr 2, GUR FUBERF BS URYY:\n\ -------------------------------\n\ +-------------------------------\ \n\ LBH'IR QBAR VG! GUR UVQRBHF PLORE- QRZBA YBEQ GUNG EHYRQ GUR YBFG QRVZBF ZBBA\n\ ONFR UNF ORRA FYNVA NAQ LBH NER GEVHZCUNAG! OHG ... JURER NER LBH? LBH\n\ @@ -31,12 +31,12 @@ ENCCRY QBJA GB GUR FHESNPR BS URYY.\n\ ABJ, VG'F BA GB GUR SVANY PUNCGRE BS QBBZ! -- VASREAB.", "Rcvfbqr 3, VASREAB:\n\ --------------------\n\ +--------------------\ \n\ GUR YBNGUFBZR FCVQREQRZBA GUNG ZNFGREZVAQRQ GUR VAINFVBA BS GUR ZBBA ONFRF\n\ NAQ PNHFRQ FB ZHPU QRNGU UNF UNQ VGF NFF XVPXRQ SBE NYY GVZR.\n\ \n\ -N UVQQRA QBBEJNL BCRAF NAQ LBH RAGRE. LBH'IR CEBIRA GBB GBHTU SBE URYY GB\n\ +N UVQQRA QBBEJNL BCRAF NAQ LBH RAGRE. LBH'IR CEBIRA GBB GBHTU SBE URYY GB\n\ PBAGNVA, NAQ ABJ URYY NG YNFG CYNLF SNVE -- SBE LBH RZRETR SEBZ GUR QBBE GB\n\ FRR GUR TERRA SVRYQF BS RNEGU! UBZR NG YNFG.\n\ \n\ @@ -45,7 +45,7 @@ HAYRNFURQ. VG'F TBBQ GUNG AB URYY- FCNJA PBHYQ UNIR PBZR GUEBHTU GUNG QBBE\n\ JVGU LBH ...", "Rcvfbqr 4, GUL SYRFU PBAFHZRQ:\n\ -------------------------------\n\ +-------------------------------\ \n\ GUR FCVQRE ZNFGREZVAQ ZHFG UNIR FRAG SBEGU VGF YRTVBAF BS URYYFCNJA ORSBER\n\ LBHE SVANY PBASEBAGNGVBA JVGU GUNG GREEVOYR ORNFG SEBZ URYY. OHG LBH FGRCCRQ\n\ @@ -64,9 +64,9 @@ struct stream { struct list_node list_fill; struct list_node list_flush; - struct mutex mutex; - struct cond cond_fill; - struct cond cond_flush; + struct mutex* mutex; + struct cond* cond_fill; + struct cond* cond_flush; }; struct buff @@ -78,67 +78,78 @@ struct buff static void read(struct stream* stream) { + size_t i = 0; ASSERT(stream); - for(size_t i = 0; i < sizeof(src_str)/sizeof(const char*); ++i) { - mutex_lock(&stream->mutex); + FOR_EACH(i, 0, sizeof(src_str)/sizeof(const char*)) { + struct list_node* buff_node = NULL; + struct buff* buff = NULL; + + mutex_lock(stream->mutex); if(is_list_empty(&stream->list_flush)) { - cond_wait(&stream->cond_flush, &stream->mutex); + cond_wait(stream->cond_flush, stream->mutex); } - mutex_unlock(&stream->mutex); + mutex_unlock(stream->mutex); - struct list_node* buff_node = list_head(&stream->list_flush); - struct buff* buff = CONTAINER_OF(buff_node, struct buff, node); + buff_node = list_head(&stream->list_flush); + buff = CONTAINER_OF(buff_node, struct buff, node); CHECK(strcmp(buff->scratch, src_str[i]), 0); printf("\n%s\n", buff->scratch); - mutex_lock(&stream->mutex); + mutex_lock(stream->mutex); list_move_tail(buff_node, &stream->list_fill); - mutex_unlock(&stream->mutex); + mutex_unlock(stream->mutex); - cond_broadcast(&stream->cond_fill); + cond_broadcast(stream->cond_fill); } } static void write(struct stream* stream) { + size_t i = 0; ASSERT(stream); - for(size_t i = 0; i < sizeof(src_str)/sizeof(const char*); ++i) { - mutex_lock(&stream->mutex); + FOR_EACH(i, 0, sizeof(src_str)/sizeof(const char*)) { + struct list_node* buff_node = NULL; + struct buff* buff = NULL; + + mutex_lock(stream->mutex); if(is_list_empty(&stream->list_fill)) { - cond_wait(&stream->cond_fill, &stream->mutex); + cond_wait(stream->cond_fill, stream->mutex); } - mutex_unlock(&stream->mutex); + mutex_unlock(stream->mutex); - struct list_node* buff_node = list_head(&stream->list_fill); - struct buff* buff = CONTAINER_OF(buff_node, struct buff, node); + buff_node = list_head(&stream->list_fill); + buff = CONTAINER_OF(buff_node, struct buff, node); ASSERT(sizeof(buff->scratch)/sizeof(char) > strlen(src_str[i])); strcpy(buff->scratch, src_str[i]); - mutex_lock(&stream->mutex); + mutex_lock(stream->mutex); list_move_tail(buff_node, &stream->list_flush); - mutex_unlock(&stream->mutex); + mutex_unlock(stream->mutex); - cond_broadcast(&stream->cond_flush); + cond_broadcast(stream->cond_flush); } } int main(int argc, char** argv) { + struct buff buff[2]; + struct stream stream; (void)argc, (void)argv; - struct stream stream; list_init(&stream.list_fill); list_init(&stream.list_flush); - mutex_init(&stream.mutex); - cond_init(&stream.cond_flush); - cond_init(&stream.cond_fill); + stream.mutex = mutex_create(); + NCHECK(stream.mutex, NULL); + stream.cond_flush = cond_create(); + NCHECK(stream.cond_flush, NULL); + stream.cond_fill = cond_create(); + NCHECK(stream.cond_fill, NULL); - struct buff buff[2]; list_init(&buff[0].node); list_init(&buff[1].node); list_add(&stream.list_fill, &buff[0].node); @@ -151,9 +162,9 @@ main(int argc, char** argv) #pragma omp section write(&stream); } - mutex_destroy(&stream.mutex); - cond_destroy(&stream.cond_flush); - cond_destroy(&stream.cond_fill); + mutex_destroy(stream.mutex); + cond_destroy(stream.cond_flush); + cond_destroy(stream.cond_fill); return 0; } diff --git a/src/test_mutex.c b/src/test_mutex.c @@ -6,7 +6,7 @@ static const char src_str[] = "Rcvfbqr 1, XARR-QRRC VA GUR QRNQ:\n\ ----------------------------------\n\ +----------------------------------\n\ \n\ BAPR LBH ORNG GUR OVT ONQNFFRF NAQ PYRNA BHG GUR ZBBA ONFR LBH'ER FHCCBFRQ GB\n\ JVA, NERA'G LBH? NERA'G LBH? JURER'F LBHE SNG ERJNEQ NAQ GVPXRG UBZR? JUNG\n\