commit 95a3e76ee006f02d4e4f9bfa265b75e081e2b4cd
parent 7747f400627024c08922761106a945ca448f3e18
Author: vaplv <vaplv@free.fr>
Date: Wed, 18 Sep 2013 14:18:24 +0200
Add minimalist signals management
Diffstat:
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);