rsys

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

commit 90f0538814464a5b981e75f1fe1fd9cd37d066fd
parent 97eb60e24ec1a4b7caa1cd028e6dc6a2c4f6ef75
Author: vaplv <vaplv@free.fr>
Date:   Sat, 25 Jan 2014 00:48:13 +0100

Several adjustments of the rsys library

Diffstat:
Msrc/CMakeLists.txt | 9++-------
Msrc/atomic.h | 96++++++++++++++++++++++++++++++++++++++++++++-----------------------------------
Msrc/free_list.h | 3+--
Msrc/mem_allocator.c | 15++++++++-------
Msrc/ref_count.h | 2+-
Msrc/rsys.h | 41++++++++++++++++++++++++++++-------------
Msrc/test_atomic.c | 26+++++---------------------
Msrc/test_free_list.c | 12++++++------
Msrc/test_mem_allocator.c | 1-
9 files changed, 104 insertions(+), 101 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -31,11 +31,6 @@ set(VERSION_MINOR 0) set(VERSION_PATCH 0) configure_file(rsys_version.h.in ${CMAKE_CURRENT_SOURCE_DIR}/rsys_version.h) -string(TOUPPER ${CMAKE_BUILD_TYPE} BUILD_TYPE) -set(LIB_SUFFIX ${CMAKE_${BUILD_TYPE}_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX}) -set(LIB_PREFIX ${CMAKE_SHARED_LIBRARY_PREFIX}) -configure_file(platform.h.in ${CMAKE_CURRENT_SOURCE_DIR}/platform.h) - set(RSYS_VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH}) message(STATUS "Current library version: ${RSYS_VERSION}") @@ -59,8 +54,8 @@ set(RSYS_FILES_INC_COMMON rsys.h signal.h) -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) +set(RSYS_FILES_INC_INSTALL ${RSYS_FILES_INC_COMMON} rsys_version.h) +set(RSYS_FILES_INC_EDIT ${RSYS_FILES_INC_COMMON} rsys_version.h.in) add_library(rsys SHARED ${RSYS_FILES_SRC} ${RSYS_FILES_INC}) target_link_libraries(rsys dl ${CMAKE_THREAD_LIBS_INIT}) diff --git a/src/atomic.h b/src/atomic.h @@ -3,54 +3,64 @@ #include "rsys.h" -/******************************************************************************* +/* * GCC implementation - ******************************************************************************/ + */ #ifdef COMPILER_GCC -typedef int atomic_int_T; -typedef size_t atomic_size_T; - -#define ATOMIC_INCR(Atom) __sync_add_and_fetch((Atom), 1) -#define ATOMIC_DECR(Atom) __sync_sub_and_fetch((Atom), 1) -#define ATOMIC_ADD(Atom, Val) __sync_add_and_fetch((Atom), (Val)) -#define ATOMIC_SUB(Atom, Val) __sync_sub_and_fetch((Atom), (Val)) -#define ATOMIC_FETCH_AND_INCR(Atom) __sync_fetch_and_add((Atom), 1) -#define ATOMIC_FETCH_AND_DECR(Atom) __sync_fetch_and_sub((Atom), 1) -#define ATOMIC_FETCH_AND_ADD(Atom, Val) __sync_fetch_and_add((Atom), (Val)) -#define ATOMIC_FETCH_AND_SUB(Atom, Val) __sync_fetch_and_sub((Atom), (Val)) -#define ATOMIC_CMP_AND_SWAP(Atom, NewVal, Comparand) \ - __sync_val_compare_and_swap(Atom, Comparand, NewVal) - -/******************************************************************************* - * Other implementation - ******************************************************************************/ -#else -typedef int atomic_int_T; -typedef size_t atomic_size_T; - -#define ATOMIC_INCR(Atom) ASSERT(0), (void)0 -#define ATOMIC_DECR(Atom) ASSERT(0), (void)0 -#define ATOMIC_ADD(Atom, Val) ASSERT(0), (void)0 -#define ATOMIC_SUB(Atom, Val) ASSERT(0), (void)0 -#define ATOMIC_FETCH_AND_INCR(Atom) ASSERT(0), (void)0 -#define ATOMIC_FETCH_AND_DECR(Atom) ASSERT(0), (void)0 -#define ATOMIC_FETCH_AND_ADD(Atom, Val) ASSERT(0), (void)0 -#define ATOMIC_FETCH_AND_SUB(Atom, Val) ASSERT(0), (void)0 -#define ATOMIC_CMP_AND_SWAP(Atom, NewVal, Comparand) ASSERT(0), (void)0 +typedef int32_t atomic32_T; +typedef int64_t atomic64_T; -#endif /* COMPILER_XXX */ +#define ATOMIC_INCR(A) __sync_add_and_fetch((A), 1) +#define ATOMIC_DECR(A) __sync_sub_and_fetch((A), 1) +#define ATOMIC_ADD(A, V) __sync_fetch_and_add((A), (int32_t)V) +#define ATOMIC_SUB(A, V) __sync_fetch_and_sub((A), (int32_t)V) +#define ATOMIC_CAS(Atom, NewVal, Comparand) /* Return the initial value */ \ + __sync_val_compare_and_swap((Atom), (int32_t)(Comparand), (int32_t)(NewVal)) +#define ATOMIC_SET(A, V) ATOMIC_CAS((A), V, (*A)) /*Return the initial value*/ + +/* + * MSVC implementation + */ +#elif defined COMPILER_MSVC +# include <Windows.h> + +typedef long atomic32_T; +typedef LONGLONG atomic64_T; -/******************************************************************************* - * Generic implementation - ******************************************************************************/ -#define ATOMIC_FETCH_AND_STORE(Atom, Val, Res) \ - for(;;) { \ - *Res = *Atom; \ - if(ATOMIC_CMP_AND_SWAP(Atom, Val, *Res) == *Res) \ - break; \ - /* TODO add a yield/pause operation */ \ - } +#define ATOMIC_INCR(A) \ + sizeof(*A) == 32 ? _InterlockedIncrement(A) \ +: (sizeof(*A) == 64 ? _InterlockedIncrement64(A) \ +: FATAL("Unexpected atomic type"), (void)0) +#define ATOMIC_DECR(A) \ + sizeof(*A) == 32 ? _InterlockedDecrement(A) \ +: (sizeof(*A) == 64 ? _InterlockedDecrement64(A) \ +: FATAL("Unexpected atomic type"), (void)0) +#define ATOMIC_ADD(A, V) \ + sizeof(*A) == 32 ? _InterlockedExchangeAdd((A), (long)(V)) \ +: (sizeof(*A) == 64 ? _InterlockedExchangeAdd64((A), (LONGLONG)(V)) \ +: FATAL("Unexpected atomic type"), (void)0) +#define ATOMIC_SUB(A, V) \ + sizeof(*A) == 32 ? _InterlockedExchangeAdd((A), -(long)(V)) \ +: (sizeof(*A) == 64 ? _InterlockedExchangeAdd64((A), -(LONGLONG)(V)) \ +: FATAL("Unexpected atomic type"), (void)0) +#define ATOMIC_CAS(Atom, NewVal, Cmp) \ + sizeof(*A) == 32 \ +? _InterlockedCompareExchange((Atom), (long)(NewVal), (long)(Cmp)) \ +: (sizeof(*A) == 64 \ +? _InterlockedCompareExchange64((A), -(LONGLONG)(NewVal), (LONGLONG)(Cmp)) \ +: FATAL("Unexpected atomic type"), (void)0) +#define ATOMIC_SET(A, V) \ + sizeof(*A) == 32 ? _InterlockedExchange((A), (long)(V)) \ +: (sizeof(*A) == 64 ? _InterlockedExchange64((A), (LONGLONG)(V)) \ +: FATAL("Unexpected atomic type"), (void)0) + +/* + * Terra incognita + */ +#else +# error "Unsupported compiler" +#endif /* COMPILER_XXX */ #endif /* ATOMIC_H */ diff --git a/src/free_list.h b/src/free_list.h @@ -27,7 +27,6 @@ static const struct fid FID_NULL = { UINT32_MAX, UINT32_MAX }; #define FLIST_TYPE__ CONCAT(flist_, FITEM_TYPE) #include "mem_allocator.h" -#include <stdbool.h> #include <string.h> struct FLIST_TYPE__ { @@ -58,7 +57,7 @@ FLIST_FUNC__(release)(struct FLIST_TYPE__* list) MEM_FREE(list->allocator, list->items); } -static FINLINE bool +static FINLINE char FLIST_FUNC__(hold)(struct FLIST_TYPE__* list, struct fid id) { ASSERT(list); diff --git a/src/mem_allocator.c b/src/mem_allocator.c @@ -2,6 +2,7 @@ #include "atomic.h" #include "mem_allocator.h" #include "math.h" + #include <errno.h> #include <malloc.h> #include <string.h> @@ -9,8 +10,8 @@ #define IS_POWER_OF_2(i) ((i) > 0 && ((i) & ((i)-1)) == 0) struct alloc_counter { - atomic_size_T nb_allocs; - atomic_size_T allocated_size; + atomic64_T nb_allocs; + atomic64_T allocated_size; }; /******************************************************************************* @@ -65,7 +66,7 @@ mem_realloc(void* mem, const size_t size) ASSERT ( old_size < (size_t)INT64_MAX - && g_alloc_counter.allocated_size >= old_size); + && g_alloc_counter.allocated_size >= (int64_t)old_size); ATOMIC_SUB( &g_alloc_counter.allocated_size, old_size); #if defined(COMPILER_MSVC) @@ -117,7 +118,7 @@ mem_free(void* mem) ASSERT ( g_alloc_counter.nb_allocs != 0 && mem_size(mem) < SIZE_MAX - && g_alloc_counter.allocated_size >= mem_size(mem)); + && g_alloc_counter.allocated_size >= (int64_t)mem_size(mem)); ATOMIC_SUB(&g_alloc_counter.allocated_size, mem_size(mem)); ATOMIC_DECR(&g_alloc_counter.nb_allocs); #if defined(COMPILER_MSVC) @@ -196,7 +197,7 @@ default_free(void* data, void* mem) ASSERT ( (data != NULL) & (counter->nb_allocs != 0) - & (counter->allocated_size >= size_mem)); + & (counter->allocated_size >= (int64_t)size_mem)); ATOMIC_SUB(&counter->allocated_size, size_mem); ATOMIC_DECR(&counter->nb_allocs); @@ -250,7 +251,7 @@ default_realloc const size_t size_old = mem_size(mem); size_t size_new = 0; - ASSERT(counter->allocated_size >= size_old); + ASSERT(counter->allocated_size >= (int64_t)size_old); ATOMIC_SUB(&counter->allocated_size, size_old); new_mem = mem_realloc(mem, size); @@ -308,7 +309,7 @@ default_allocated_size(const void* data) #else const struct alloc_counter* counter = data; ASSERT(counter != NULL); - return counter->allocated_size; + return (size_t)counter->allocated_size; #endif /* TRACK_DEFAULT_ALLOC */ } diff --git a/src/ref_count.h b/src/ref_count.h @@ -4,7 +4,7 @@ #include "atomic.h" #include "rsys.h" -typedef atomic_int_T ref_T; +typedef atomic32_T ref_T; static FINLINE void ref_init(ref_T* ref) diff --git a/src/rsys.h b/src/rsys.h @@ -9,7 +9,6 @@ #error "Unsupported compiler" #endif -#include "platform.h" #include <stdint.h> #include <stddef.h> #include <stdlib.h> @@ -38,17 +37,27 @@ #endif /******************************************************************************* - * Shared library - ******************************************************************************/ -#define SHARED_LIBRARY_NAME(Name) \ - SHARED_LIBRARY_PREFIX Name SHARED_LIBRARY_SUFFIX - -/******************************************************************************* * Symbol visibility ******************************************************************************/ -#define EXPORT_SYM __attribute__((visibility("default"))) -#define IMPORT_SYM -#define LOCAL_SYM __attribute__((visibility("hidden"))) +#if defined(COMPILER_GCC) + #define EXPORT_SYM __attribute__((visibility("default"))) + #define IMPORT_SYM + #define LOCAL_SYM __attribute__((visibility("hidden"))) +#elif defined(COMPILER_MSVC) + #define FDN_SYMBOL_EXPORT __declspec(dllexport) + #define FDN_SYMBOL_IMPORT __declspec(dllimport) + #define FDN_SYMBOL_LOCAL +#endif + +#if defined(OS_UNIX) + #define SHARED_LIBRARY_PREFIX "lib" + #define SHARED_LIBRARY_SUFFIX ".so" +#elif defined(OS_WINDOWS) + #define SHARED_LIBRARY_PREFIX + #define SHARED_LIBRARY_SUFFIX ".dll" +#endif + +#define SHARED_LIBRARY_NAME(Lib) SHARED_LIBRARY_PREFIX Lib SHARED_LIBRARY_SUFFIX #if defined(RSYS_SHARED_BUILD) #define RSYS_API extern EXPORT_SYM @@ -59,9 +68,15 @@ /******************************************************************************* * Code inlining ******************************************************************************/ -#define FINLINE __inline__ __attribute__((always_inline)) -#define INLINE __inline__ -#define NOINLINE __attribute__((noinline)) +#if defined(COMPILER_GCC) + #define FINLINE __inline__ __attribute__((always_inline)) + #define INLINE __inline__ + #define NOINLINE __attribute__((noinline)) +#elif defined(COMPILER_MSVC) + #define FINLINE __forceinline + #define INLINE __inline + #define NOINLINE __declspec(noinline) +#endif /******************************************************************************* * Data alignment diff --git a/src/test_atomic.c b/src/test_atomic.c @@ -4,46 +4,30 @@ int main(int argc, char** argv) { - atomic_int_T atom = 0; + atomic32_T atom = 0; int tmp; - (void)argc, (void)argv; - tmp = ATOMIC_INCR(&atom); CHECK(atom, 1); CHECK(tmp, 1); tmp = ATOMIC_ADD(&atom, 5); CHECK(atom, 6); - CHECK(tmp, 6); + CHECK(tmp, 1); tmp = ATOMIC_DECR(&atom); CHECK(atom, 5); CHECK(tmp, 5); tmp = ATOMIC_SUB(&atom, 7); CHECK(atom, -2); - CHECK(tmp, -2); - - atom = 0; - tmp = ATOMIC_FETCH_AND_INCR(&atom); - CHECK(atom, 1); - CHECK(tmp, 0); - tmp = ATOMIC_FETCH_AND_ADD(&atom, 5); - CHECK(atom, 6); - CHECK(tmp, 1); - tmp = ATOMIC_FETCH_AND_DECR(&atom); - CHECK(atom, 5); - CHECK(tmp, 6); - tmp = ATOMIC_FETCH_AND_SUB(&atom, 7); - CHECK(atom, -2); CHECK(tmp, 5); - tmp = ATOMIC_CMP_AND_SWAP(&atom, 0, -1); + tmp = ATOMIC_CAS(&atom, 0, -1); CHECK(atom, -2); CHECK(tmp, -2); - tmp = ATOMIC_CMP_AND_SWAP(&atom, 0, -2); + tmp = ATOMIC_CAS(&atom, 0, -2); CHECK(atom, 0); CHECK(tmp, -2); - ATOMIC_FETCH_AND_STORE(&atom, 9, &tmp); + tmp = ATOMIC_SET(&atom, 9); CHECK(atom, 9); CHECK(tmp, 0); diff --git a/src/test_free_list.c b/src/test_free_list.c @@ -24,16 +24,16 @@ main(int argc, char** argv) } flist_object_init(NULL, &list); - CHECK(flist_object_hold(&list, id[0]), false); + CHECK(flist_object_hold(&list, id[0]), 0); CHECK(flist_object_get(&list, id[0]), NULL); FOR_EACH(i, 0, NB_OBJ / 2) { struct fid tmp_id; id[i] = flist_object_add(&list); - CHECK(flist_object_hold(&list, id[i]), true); + CHECK(flist_object_hold(&list, id[i]), 1); obj = flist_object_get(&list, id[i]); tmp_id = object_id_get(obj); - CHECK(FID_EQ(tmp_id, id[i]), true); + CHECK(FID_EQ(tmp_id, id[i]), 1); NCHECK(obj, NULL); obj->i = 0xDECAF000 + (unsigned)i; } @@ -47,7 +47,7 @@ main(int argc, char** argv) FOR_EACH(i, NB_OBJ / 2, NB_OBJ) { id[i] = flist_object_add(&list); - CHECK(flist_object_hold(&list, id[i]), true); + CHECK(flist_object_hold(&list, id[i]), 1); obj = flist_object_get(&list, id[i]); NCHECK(obj, NULL); obj->i = 0xDECAF000 + (unsigned)i; @@ -55,10 +55,10 @@ main(int argc, char** argv) FOR_EACH(i, 0, NB_OBJ) { if(IS_FID_NULL(id[i])) { - CHECK(flist_object_hold(&list, id[i]), false); + CHECK(flist_object_hold(&list, id[i]), 0); CHECK(flist_object_get(&list, id[i]), NULL); } else { - CHECK(flist_object_hold(&list, id[i]), true); + CHECK(flist_object_hold(&list, id[i]), 1); obj = flist_object_get(&list, id[i]); CHECK(obj->i, 0xDECAF000 + (unsigned)i); } diff --git a/src/test_mem_allocator.c b/src/test_mem_allocator.c @@ -1,6 +1,5 @@ #include "mem_allocator.h" #include "rsys.h" -#include <stdbool.h> #include <stdio.h> #include <stdlib.h> #include <string.h>