commit edaf3a772e3fa62d7a526e7a29402838a3c52006
parent dbdd22f1e8a0a64aa106c44291cef3c0060d125b
Author: vaplv <vaplv@free.fr>
Date: Sat, 11 Jan 2014 17:28:10 +0100
Rewrite the pthread API and adjust its pthread implementation
Diffstat:
6 files changed, 173 insertions(+), 150 deletions(-)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
@@ -43,7 +43,8 @@ set(RSYS_FILES_SRC
clock_time.c
image.c
library.c
- mem_allocator.c)
+ mem_allocator.c
+ pthread/pthread_mutex.c)
set(RSYS_FILES_INC_COMMON
atomic.h
clock_time.h
@@ -61,7 +62,7 @@ set(RSYS_FILES_INC_INSTALL ${RSYS_FILES_INC_COMMON} platform.h rsys_version.h)
set(RSYS_FILES_INC_EDIT ${RSYS_FILES_INC_COMMON} platform.h.in rsys_version.h.in)
add_library(rsys SHARED ${RSYS_FILES_SRC} ${RSYS_FILES_INC})
-target_link_libraries(rsys dl rt)
+target_link_libraries(rsys dl ${CMAKE_THREAD_LIBS_INIT})
set_target_properties(rsys PROPERTIES
DEFINE_SYMBOL RSYS_SHARED_BUILD
VERSION ${RSYS_VERSION}
@@ -96,7 +97,9 @@ if(NOT OPENMP_FOUND)
message(STATUS "No OpenMP support: multi-threaded tests cannot be generated")
else()
# new_test(test_condition)
-# new_test(test_mutex 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})
endif()
diff --git a/src/mem_allocator.c b/src/mem_allocator.c
@@ -98,7 +98,7 @@ mem_alloc_aligned(const size_t size, const size_t alignment)
const int result = posix_memalign
(&mem, (alignment < sizeof(void*)) ? sizeof(void*) : alignment, size);
(void)result; /* avoid warning in Release */
- /* The following assert may not occur due to previous condition */
+ /* The following assert may not occur due to previous conditions */
ASSERT(result != EINVAL);
ASSERT((result != ENOMEM) || (mem == NULL));
#endif
diff --git a/src/mutex.h b/src/mutex.h
@@ -54,9 +54,9 @@ mutex_spin_unlock
******************************************************************************/
struct mutex_rw;
-RSYS_API void
-mutex_rw_init
- (struct mutex_rw* mutex);
+RSYS_API struct mutex_rw*
+mutex_rw_create
+ (void);
RSYS_API void
mutex_rw_destroy
diff --git a/src/pthread/mutex.h b/src/pthread/mutex.h
@@ -1,117 +0,0 @@
-#include "mem_allocator.h"
-#include <pthread.h>
-
-#ifdef NDEBUG
- #define PTHREAD__(Func) pthread_##Func
-#else
- #define PTHREAD__(Func) ASSERT(pthread_##Func == 0)
-#endif
-
-/*******************************************************************************
- * Mutex
- ******************************************************************************/
-struct mutex { pthread_mutex_t mutex__; };
-
-struct mutex*
-mutex_create(void)
-{
- PTHREAD__(mutex_init(&mutex->mutex__, NULL));
-}
-
-void
-mutex_destroy(struct mutex* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(mutex_destroy(&mutex->mutex__));
-}
-
-void
-mutex_lock(struct mutex* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(mutex_lock(&mutex->mutex__));
-}
-
-void
-mutex_unlock(struct mutex* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(mutex_unlock(&mutex->mutex__));
-}
-
-/*******************************************************************************
- * Spinlock
- ******************************************************************************/
-struct mutex_spin { pthread_spinlock_t mutex__; };
-
-void
-mutex_spin_init(struct mutex_spin* mutex)
-{
- ASSERT(mutex);
- pthread_spin_init
- PTHREAD__(spin_init(&mutex->mutex__, PTHREAD_PROCESS_PRIVATE));
-}
-
-void
-mutex_spin_destroy(struct mutex_spin* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(spin_destroy(&mutex->mutex__));
-}
-
-void
-mutex_spin_lock(struct mutex_spin* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(spin_lock(&mutex->mutex__));
-}
-
-void
-mutex_spin_unlock(struct mutex_spin* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(spin_unlock(&mutex->mutex__));
-}
-
-/*******************************************************************************
- * Read Write mutex
- ******************************************************************************/
-struct mutex_rw { pthread_rwlock_t mutex__; };
-
-static FINLINE void
-mutex_rw_init(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(rwlock_init(&mutex->mutex__, NULL));
-}
-
-static FINLINE void
-mutex_rw_destroy(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(rwlock_destroy(&mutex->mutex__));
-}
-
-static FINLINE void
-mutex_rw_rlock(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(rwlock_rdlock(&mutex->mutex__));
-}
-
-static FINLINE void
-mutex_rw_wlock(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(rwlock_wrlock(&mutex->mutex__));
-}
-
-static FINLINE void
-mutex_rw_unlock(struct mutex_rw* mutex)
-{
- ASSERT(mutex);
- PTHREAD__(rwlock_unlock(&mutex->mutex__));
-}
-
-#undef PTHREAD__
-
diff --git a/src/pthread/pthread_mutex.c b/src/pthread/pthread_mutex.c
@@ -0,0 +1,124 @@
+#define _POSIX_C_SOURCE 200112L /* Spin lock and mutex rw */
+#include "../mem_allocator.h"
+#include "../mutex.h"
+#include <pthread.h>
+
+#ifdef NDEBUG
+ #define PTHREAD(Func) pthread_##Func
+#else
+ #define PTHREAD(Func) ASSERT(pthread_##Func == 0)
+#endif
+
+/*******************************************************************************
+ * Mutex
+ ******************************************************************************/
+struct mutex*
+mutex_create(void)
+{
+ pthread_mutex_t* mutex = mem_alloc(sizeof(pthread_mutex_t));
+ if(mutex)
+ PTHREAD(mutex_init(mutex, NULL));
+ return (struct mutex*)mutex;
+}
+
+void
+mutex_destroy(struct mutex* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(mutex_destroy((pthread_mutex_t*)mutex));
+ mem_free(mutex);
+}
+
+void
+mutex_lock(struct mutex* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(mutex_lock((pthread_mutex_t*)mutex));
+}
+
+void
+mutex_unlock(struct mutex* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(mutex_unlock((pthread_mutex_t*)mutex));
+}
+
+/*******************************************************************************
+ * Spinlock
+ ******************************************************************************/
+struct mutex_spin*
+mutex_spin_create(void)
+{
+ pthread_spinlock_t* spin = mem_alloc(sizeof(pthread_spinlock_t));
+ if(spin)
+ PTHREAD(spin_init(spin, PTHREAD_PROCESS_PRIVATE));
+ return (struct mutex_spin*)spin;
+}
+
+void
+mutex_spin_destroy(struct mutex_spin* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(spin_destroy((pthread_spinlock_t*)mutex));
+ mem_free(mutex);
+}
+
+void
+mutex_spin_lock(struct mutex_spin* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(spin_lock((pthread_spinlock_t*)mutex));
+}
+
+void
+mutex_spin_unlock(struct mutex_spin* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(spin_unlock((pthread_spinlock_t*)mutex));
+}
+
+/*******************************************************************************
+ * Read Write mutex
+ ******************************************************************************/
+struct mutex_rw { pthread_rwlock_t mutex__; };
+
+struct mutex_rw*
+mutex_rw_create(void)
+{
+ pthread_rwlock_t* mutex = mem_alloc(sizeof(pthread_rwlock_t));
+ if(mutex)
+ PTHREAD(rwlock_init(mutex, NULL));
+ return (struct mutex_rw*)mutex;
+}
+
+void
+mutex_rw_destroy(struct mutex_rw* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(rwlock_destroy((pthread_rwlock_t*)mutex));
+ mem_free(mutex);
+}
+
+void
+mutex_rw_rlock(struct mutex_rw* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(rwlock_rdlock((pthread_rwlock_t*)mutex));
+}
+
+void
+mutex_rw_wlock(struct mutex_rw* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(rwlock_wrlock((pthread_rwlock_t*)mutex));
+}
+
+void
+mutex_rw_unlock(struct mutex_rw* mutex)
+{
+ ASSERT(mutex);
+ PTHREAD(rwlock_unlock((pthread_rwlock_t*)mutex));
+}
+
+#undef PTHREAD
+
diff --git a/src/test_mutex.c b/src/test_mutex.c
@@ -68,9 +68,9 @@ enum mutex_type {
struct string
{
- struct mutex mutex;
- struct mutex_spin mutex_spin;
- struct mutex_rw mutex_rw;
+ struct mutex* mutex;
+ struct mutex_spin* mutex_spin;
+ struct mutex_rw* mutex_rw;
char str[sizeof(src_str)/sizeof(char) + 1 /* +1 <=< '\0'*/ ];
int i;
};
@@ -84,48 +84,48 @@ string_write(struct string* string, const enum mutex_type type)
case MUTEX_COMMON:
{
for(;;) {
- mutex_lock(&string->mutex);
+ mutex_lock(string->mutex);
if((unsigned)string->i >= sizeof(src_str)/sizeof(char) + 1) {
- mutex_unlock(&string->mutex);
+ mutex_unlock(string->mutex);
break;
}
string->str[string->i] = src_str[string->i];
++string->i;
- mutex_unlock(&string->mutex);
+ mutex_unlock(string->mutex);
}
}
break;
case MUTEX_SPIN:
{
for(;;) {
- mutex_spin_lock(&string->mutex_spin);
+ mutex_spin_lock(string->mutex_spin);
if((unsigned)string->i >= sizeof(src_str)/sizeof(char) + 1) {
- mutex_spin_unlock(&string->mutex_spin);
+ mutex_spin_unlock(string->mutex_spin);
break;
}
string->str[string->i] = src_str[string->i];
++string->i;
- mutex_spin_unlock(&string->mutex_spin);
+ mutex_spin_unlock(string->mutex_spin);
}
}
break;
case MUTEX_RW:
{
for(;;) {
- mutex_rw_wlock(&string->mutex_rw);
+ mutex_rw_wlock(string->mutex_rw);
if((unsigned)string->i >= sizeof(src_str)/sizeof(char) + 1) {
- mutex_rw_unlock(&string->mutex_rw);
+ mutex_rw_unlock(string->mutex_rw);
break;
}
string->str[string->i] = src_str[string->i];
++string->i;
- mutex_rw_unlock(&string->mutex_rw);
+ mutex_rw_unlock(string->mutex_rw);
}
}
break;
@@ -136,33 +136,47 @@ string_write(struct string* string, const enum mutex_type type)
static void
string_read(struct string* string)
{
- ASSERT(string);
int i = 0;
+ ASSERT(string);
do {
- mutex_rw_rlock(&string->mutex_rw);
+ mutex_rw_rlock(string->mutex_rw);
i = string->i;
- mutex_rw_unlock(&string->mutex_rw);
+ mutex_rw_unlock(string->mutex_rw);
} while( (unsigned)i < sizeof(src_str)/sizeof(char));
- mutex_rw_rlock(&string->mutex_rw);
+ mutex_rw_rlock(string->mutex_rw);
printf("%s\n", string->str);
- mutex_rw_unlock(&string->mutex_rw);
+ mutex_rw_unlock(string->mutex_rw);
}
static void
test_mutex(const enum mutex_type type)
{
- struct string string = { .str = { [0] = '\0' }, .i = 0 };
+ struct string string;
+ struct time time_start, time_end, time_res;
+ char dump[32];
+
+ string.str[0] = '\0';
+ string.i = 0;
+
switch(type) {
- case MUTEX_COMMON: mutex_init(&string.mutex); break;
- case MUTEX_SPIN: mutex_spin_init(&string.mutex_spin); break;
- case MUTEX_RW: mutex_rw_init(&string.mutex_rw); break;
+ case MUTEX_COMMON:
+ string.mutex = mutex_create();
+ NCHECK(string.mutex, NULL);
+ break;
+ case MUTEX_SPIN:
+ string.mutex_spin = mutex_spin_create();
+ NCHECK(string.mutex_spin, NULL);
+ break;
+ case MUTEX_RW:
+ string.mutex_rw = mutex_rw_create();
+ NCHECK(string.mutex_rw, NULL);
+ break;
default: ASSERT(0); break;
}
- time_T time_start, time_end, time_res;
time_current(&time_start);
#pragma omp parallel
@@ -186,7 +200,6 @@ test_mutex(const enum mutex_type type)
time_current(&time_end);
time_sub(&time_res, &time_end, &time_start);
- char dump[32];
time_dump
(&time_res,
TIME_MSEC|TIME_USEC,
@@ -203,9 +216,9 @@ test_mutex(const enum mutex_type type)
}
switch(type) {
- case MUTEX_COMMON: mutex_destroy(&string.mutex); break;
- case MUTEX_SPIN: mutex_spin_destroy(&string.mutex_spin); break;
- case MUTEX_RW: mutex_rw_destroy(&string.mutex_rw); break;
+ case MUTEX_COMMON: mutex_destroy(string.mutex); break;
+ case MUTEX_SPIN: mutex_spin_destroy(string.mutex_spin); break;
+ case MUTEX_RW: mutex_rw_destroy(string.mutex_rw); break;
default: ASSERT(0); break;
}
}