rsys

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

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:
Msrc/CMakeLists.txt | 9++++++---
Msrc/mem_allocator.c | 2+-
Msrc/mutex.h | 6+++---
Dsrc/pthread/mutex.h | 117-------------------------------------------------------------------------------
Asrc/pthread/pthread_mutex.c | 124+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Msrc/test_mutex.c | 65+++++++++++++++++++++++++++++++++++++++--------------------------
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; } }