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:
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\