rsys

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

commit 95a3e76ee006f02d4e4f9bfa265b75e081e2b4cd
parent 7747f400627024c08922761106a945ca448f3e18
Author: vaplv <vaplv@free.fr>
Date:   Wed, 18 Sep 2013 14:18:24 +0200

Add minimalist signals management

Diffstat:
Msrc/CMakeLists.txt | 39+++++++++++++++++++--------------------
Msrc/image.c | 2+-
Msrc/image.h | 4++--
Msrc/math.h | 6+++---
Msrc/rsys.h | 2+-
Msrc/signal.h | 100++++++++++++++++++++++++++++++++++++++++---------------------------------------
Msrc/test_signal.c | 79++++++++++++++++++++++++++++++++++++++-----------------------------------------
7 files changed, 115 insertions(+), 117 deletions(-)

diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt @@ -25,21 +25,20 @@ add_definitions(-D_POSIX_C_SOURCE=200112L) ################################################################################ # Define targets ################################################################################ -set(RSYS_FILES_SRC - clock_time.c -#image.c +set(RSYS_FILES_SRC + clock_time.c + image.c mem_allocator.c) set(RSYS_FILES_INC - atomic.h - clock_time.h -# image.h - list.h -# math.h - mem_allocator.h -# ref_count.h -# signal.h - rsys.h) + atomic.h + clock_time.h + image.h + list.h + mem_allocator.h + ref_count.h + signal.h + rsys.h) add_library(rsys SHARED ${RSYS_FILES_SRC} ${RSYS_FILES_INC}) set_target_properties(rsys PROPERTIES DEFINE_SYMBOL RSYS_SHARED_BUILD) @@ -65,23 +64,23 @@ if(NOT OPENMP_FOUND) message(STATUS "No OpenMP support: multi-threaded tests cannot be generated") else() add_executable(test_mutex test_mutex.c) - set_target_properties(test_mutex PROPERTIES COMPILE_FLAGS ${OpenMP_C_FLAGS}) - set_target_properties(test_mutex PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) target_link_libraries(test_mutex rsys) add_test(test_mutex test_mutex) add_executable(test_condition test_condition.c) - set_target_properties(test_condition PROPERTIES COMPILE_FLAGS ${OpenMP_C_FLAGS}) - set_target_properties(test_condition PROPERTIES LINK_FLAGS ${OpenMP_C_FLAGS}) add_test(test_condition test_condition) + + 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() -#add_executable(test_signal test_signal.c) -#target_link_libraries(test_signal snlsys) -#add_test(test_signal test_signal) +add_executable(test_signal test_signal.c) +target_link_libraries(test_signal rsys) +add_test(test_signal test_signal) ################################################################################ # Define output & install directories ################################################################################ -#install(TARGETS rsys LIBRARY DESTINATION lib) +install(TARGETS rsys LIBRARY DESTINATION lib) install(FILES ${RSYS_FILES_INC} DESTINATION include/rsys) + diff --git a/src/image.c b/src/image.c @@ -31,7 +31,7 @@ image_ppm_write } (void)0 #define SNPRINTF(b, sz, ...) \ { \ - UNUSED const int i = snprintf(b, sz, __VA_ARGS__); \ + const int i = snprintf(b, sz, __VA_ARGS__); \ if( i >= BUFSIZ ) { \ goto error; \ } \ diff --git a/src/image.h b/src/image.h @@ -1,13 +1,13 @@ #ifndef IMAGE_H #define IMAGE_H -#include "snlsys.h" +#include "rsys.h" #ifdef __cplusplus extern "C" { #endif -SNLSYS_API int +RSYS_API int image_ppm_write (const char* path, int width, diff --git a/src/math.h b/src/math.h @@ -1,5 +1,5 @@ -#ifndef SYS_MATH_H -#define SYS_MATH_H +#ifndef RSYS_MATH_H +#define RSYS_MATH_H #define PI 3.14159265358979323846 @@ -28,5 +28,5 @@ #define MIN(a, b) \ ((a) < (b) ? (a) : (b)) -#endif /* SYS_MATH_H */ +#endif /* RSYS_MATH_H */ diff --git a/src/rsys.h b/src/rsys.h @@ -123,7 +123,7 @@ #define COUNTER __COUNTER__ #define FOR_EACH(Type, Id, Start, End) \ - for(Type (Var) = (Start); (Var) < (End); ++(Var)) + for(Type (Id) = (Start); (Id) < (End); ++(Id)) #define IS_MEMORY_OVERLAPPED(D0, Sz0, D1, Sz1) \ (((intptr_t)(D0) >= (intptr_t)(D1) && \ diff --git a/src/signal.h b/src/signal.h @@ -2,64 +2,66 @@ #define SIGNAL_H #include "list.h" -#include "snlsys.h" +#include "rsys.h" -/******************************************************************************* - * - * Signal declaration and functions - * +/****************************************************************************** + * Simple callback data structure ******************************************************************************/ -#define SIGNALS_LIST(Slst, ClbkType, Count) \ - struct { \ - ClbkType callbacks_list[(Count)]; \ - } Slst +struct callback { + struct list_node node; + void (*func)(void* args, void* data); + void* data; +}; -#define SIGNALS_LIST_INIT(Slst) \ - { \ - unsigned i = 0; \ - for(i = 0; \ - i < sizeof((Slst)->callbacks_list) / sizeof((Slst)->callbacks_list[0]);\ - ++i ) { \ - list_init(&(Slst)->callbacks_list[i].node); \ - } \ - } (void)0 +static FINLINE void +callback_init(struct callback* clbk) +{ + ASSERT(clbk); + list_init(&clbk->node); +} -#define SIGNAL_CONNECT_CALLBACK(Slst, Signal, Clbk) \ - list_add(&(Slst)->callbacks_list[(Signal)].node, &(Clbk)->node) +static FINLINE void +callback_setup(struct callback* clbk, void (*func)(void*, void*), void* data) +{ + ASSERT(clbk); + clbk->func = func; + clbk->data = data; +} -#define SIGNAL_INVOKE(Slst, Signal, ...) \ - { \ - struct list_node* pos = NULL; \ - typedef TYPEOF((Slst)->callbacks_list[0]) ClbkType; \ - LIST_FOR_EACH(pos, &(Slst)->callbacks_list[(Signal)].node) { \ - ClbkType* clbk = CONTAINER_OF(pos, ClbkType, node); \ - clbk->func(__VA_ARGS__, clbk->data); \ - } \ - } (void)0 +static FINLINE void +callback_disconnect(struct callback* clbk) +{ + ASSERT(clbk); + list_del(&clbk->node); +} -/******************************************************************************* - * - * Callback data structure that may be connected to a signal - * +/****************************************************************************** + * Minimalist signal data structure ******************************************************************************/ -#define CALLBACK(Name, ...) \ - typedef struct { \ - struct list_node node; \ - void (*func)(__VA_ARGS__, void* data); \ - void* data; \ - } Name +typedef struct list_node signal_T; -#define CALLBACK_INIT(Clbk) \ - list_init(&(Clbk)->node) +static FINLINE void +signal_init(signal_T* signal) +{ + ASSERT(signal); + list_init(signal); +} -#define CALLBACK_SETUP(Clbk, Func, Data) \ - { \ - (Clbk)->func = Func; \ - (Clbk)->data = Data; \ - } (void)0 +static FINLINE void +signal_connect_callback(signal_T* signal, struct callback* clbk) +{ + ASSERT(signal && clbk); + list_add(signal, &clbk->node); +} -#define CALLBACK_DISCONNECT(Clbk) \ - list_del(&(Clbk)->node) +static FINLINE void +signal_invoke(signal_T* signal, void* args) +{ + LIST_FOR_EACH(pos, signal) { + struct callback* clbk = CONTAINER_OF(pos, struct callback, node); + clbk->func(args, clbk->data); + } +} -#endif /* CALLBACK_H */ +#endif /* SIGNAL_H */ diff --git a/src/test_signal.c b/src/test_signal.c @@ -7,8 +7,6 @@ struct ctxt { int sig1_func_sum; }; -CALLBACK(clbk_T, struct ctxt*); - enum test_signal { SIG0, SIG1, @@ -16,96 +14,95 @@ enum test_signal { }; static void -sig0_func1(struct ctxt* ctxt, void* data) +sig0_func1(void* arg, void* data) { CHECK(data, NULL); - ctxt->sig0_func1_invoked = 1; + ((struct ctxt*)arg)->sig0_func1_invoked = 1; } static void -sig0_func2(struct ctxt* ctxt, void* data) +sig0_func2(void* arg, void* data) { NCHECK(data, NULL); - ctxt->sig0_func2_sum += *((int*)data); + ((struct ctxt*)arg)->sig0_func2_sum += *((int*)data); } static void -sig1_func(struct ctxt* ctxt, void* data) +sig1_func(void* arg, void* data) { NCHECK(data, NULL); - ctxt->sig1_func_sum += *(int*)data; + ((struct ctxt*)arg)->sig1_func_sum += *(int*)data; } int main(int argc, char** argv) { - (void)argc; - (void)argv; + (void)argc, (void)argv; struct ctxt ctxt; - SIGNALS_LIST(slst, clbk_T, SIGNALS_COUNT); - SIGNALS_LIST_INIT(&slst); - - clbk_T clbk0_a; - clbk_T clbk0_b; - clbk_T clbk0_c; - clbk_T clbk1_a; - clbk_T clbk1_b; - CALLBACK_INIT(&clbk0_a); - CALLBACK_INIT(&clbk0_b); - CALLBACK_INIT(&clbk0_c); - CALLBACK_INIT(&clbk1_a); - CALLBACK_INIT(&clbk1_b); - CALLBACK_SETUP(&clbk0_a, sig0_func1, NULL); - CALLBACK_SETUP(&clbk0_b, sig0_func2, (int[]){12}); - CALLBACK_SETUP(&clbk0_c, sig0_func2, (int[]){-1}); - CALLBACK_SETUP(&clbk1_a, sig1_func, (int[]){2}); - CALLBACK_SETUP(&clbk1_b, sig1_func, (int[]){1}); + signal_T signals[SIGNALS_COUNT]; + FOR_EACH(int, i, 0, SIGNALS_COUNT) signal_init(&signals[i]); + + struct callback clbk0_a; + struct callback clbk0_b; + struct callback clbk0_c; + struct callback clbk1_a; + struct callback clbk1_b; + callback_init(&clbk0_a); + callback_init(&clbk0_b); + callback_init(&clbk0_c); + callback_init(&clbk1_a); + callback_init(&clbk1_b); + callback_setup(&clbk0_a, sig0_func1, NULL); + callback_setup(&clbk0_b, sig0_func2, (int[]){12}); + callback_setup(&clbk0_c, sig0_func2, (int[]){-1}); + callback_setup(&clbk1_a, sig1_func, (int[]){2}); + callback_setup(&clbk1_b, sig1_func, (int[]){1}); ctxt.sig0_func1_invoked = 0; ctxt.sig0_func2_sum = 0; ctxt.sig1_func_sum = 0; - SIGNAL_INVOKE(&slst, SIG0, &ctxt); + signal_invoke(&signals[SIG0], &ctxt); CHECK(ctxt.sig0_func1_invoked, 0); CHECK(ctxt.sig0_func2_sum, 0); CHECK(ctxt.sig1_func_sum, 0); - SIGNAL_INVOKE(&slst, SIG1, &ctxt); + signal_invoke(&signals[SIG1], &ctxt); CHECK(ctxt.sig0_func1_invoked, 0); CHECK(ctxt.sig0_func2_sum, 0); CHECK(ctxt.sig1_func_sum, 0); - SIGNAL_CONNECT_CALLBACK(&slst, SIG0, &clbk0_a); - SIGNAL_CONNECT_CALLBACK(&slst, SIG0, &clbk0_b); - SIGNAL_CONNECT_CALLBACK(&slst, SIG0, &clbk0_c); - SIGNAL_INVOKE(&slst, SIG0, &ctxt); + signal_connect_callback(&signals[SIG0], &clbk0_a); + signal_connect_callback(&signals[SIG0], &clbk0_b); + signal_connect_callback(&signals[SIG0], &clbk0_c); + signal_invoke(&signals[SIG0], &ctxt); CHECK(ctxt.sig0_func1_invoked, 1); CHECK(ctxt.sig0_func2_sum, 11); CHECK(ctxt.sig1_func_sum, 0); - CALLBACK_DISCONNECT(&clbk0_c); + callback_disconnect(&clbk0_c); ctxt.sig0_func1_invoked = 0; ctxt.sig0_func2_sum = 0; ctxt.sig1_func_sum = 0; - SIGNAL_INVOKE(&slst, SIG0, &ctxt); + signal_invoke(&signals[SIG0], &ctxt); CHECK(ctxt.sig0_func1_invoked, 1); CHECK(ctxt.sig0_func2_sum, 12); CHECK(ctxt.sig1_func_sum, 0); - SIGNAL_CONNECT_CALLBACK(&slst, SIG1, &clbk1_a); - SIGNAL_INVOKE(&slst, SIG0, &ctxt); + signal_connect_callback(&signals[SIG1], &clbk1_a); + signal_invoke(&signals[SIG0], &ctxt); CHECK(ctxt.sig0_func1_invoked, 1); CHECK(ctxt.sig0_func2_sum, 24); CHECK(ctxt.sig1_func_sum, 0); - SIGNAL_INVOKE(&slst, SIG1, &ctxt); + signal_invoke(&signals[SIG1], &ctxt); CHECK(ctxt.sig0_func1_invoked, 1); CHECK(ctxt.sig0_func2_sum, 24); CHECK(ctxt.sig1_func_sum, 2); - SIGNAL_CONNECT_CALLBACK(&slst, SIG1, &clbk1_b); - SIGNAL_INVOKE(&slst, SIG1, &ctxt); + signal_connect_callback(&signals[SIG1], &clbk1_b); + signal_invoke(&signals[SIG1], &ctxt); CHECK(ctxt.sig0_func1_invoked, 1); CHECK(ctxt.sig0_func2_sum, 24); CHECK(ctxt.sig1_func_sum, 5);