From 1b206931df49c00b9542ac0f8bf997c81e5009ce Mon Sep 17 00:00:00 2001 From: Patrick Pelissier Date: Wed, 22 Jul 2020 20:51:45 +0200 Subject: [PATCH] Transform TAB into SPACE --- m-mempool.h | 182 +++++++++++++++++----------------- m-prioqueue.h | 60 ++++++------ m-rbtree.h | 96 +++++++++--------- m-shared.h | 230 +++++++++++++++++++++---------------------- m-snapshot.h | 263 +++++++++++++++++++++++++------------------------- 5 files changed, 416 insertions(+), 415 deletions(-) diff --git a/m-mempool.h b/m-mempool.h index 6e1576b7..7fd43086 100644 --- a/m-mempool.h +++ b/m-mempool.h @@ -49,106 +49,106 @@ the minimun number of elements. */ #ifndef MEMPOOL_MAX_PER_SEGMENT -#define MEMPOOL_MAX_PER_SEGMENT(type) \ +#define MEMPOOL_MAX_PER_SEGMENT(type) \ M_MAX((16*1024-sizeof(unsigned int) - 2*sizeof(void*)) / sizeof (type), 256U) #endif /********************************** INTERNAL ************************************/ -#define MEMPOOL_DEF_P2(name, type) \ - \ - typedef union M_C(name,_union_s) { \ - type t; \ - union M_C(name,_union_s) *next; \ - } M_C(name,_union_t); \ - \ - typedef struct M_C(name,_segment_s) { \ - unsigned int count; \ - struct M_C(name,_segment_s) *next; \ - M_C(name,_union_t) tab[MEMPOOL_MAX_PER_SEGMENT(type)]; \ - } M_C(name,_segment_t); \ - \ - typedef struct M_C(name, _s) { \ - M_C(name,_union_t) *free_list; \ - M_C(name,_segment_t) *current_segment; \ - } M_C(name,_t)[1]; \ - \ - static inline void \ - M_C(name,_init)(M_C(name,_t) mem) \ - { \ - mem->free_list = NULL; \ - mem->current_segment = M_MEMORY_ALLOC(M_C(name,_segment_t)); \ - if (mem->current_segment == NULL) { \ - M_MEMORY_FULL(sizeof (M_C(name,_segment_t))); \ - return; \ - } \ - mem->current_segment->next = NULL; \ - mem->current_segment->count = 0; \ - MEMPOOLI_CONTRACT(mem, type); \ - } \ - \ - static inline void \ - M_C(name,_clear)(M_C(name,_t) mem) \ - { \ - MEMPOOLI_CONTRACT(mem, type); \ - M_C(name,_segment_t) *segment = mem->current_segment; \ - while (segment != NULL) { \ - M_C(name,_segment_t) *next = segment->next; \ - M_MEMORY_DEL (segment); \ - segment = next; \ - } \ - /* Clean pointers to be safer */ \ - mem->free_list = NULL; \ - mem->current_segment = NULL; \ - } \ - \ - static inline type * \ - M_C(name,_alloc)(M_C(name,_t) mem) \ - { \ - MEMPOOLI_CONTRACT(mem, type); \ - M_C(name,_union_t) *ret = mem->free_list; \ - if (ret != NULL) { \ - mem->free_list = ret->next; \ - return &ret->t; \ - } \ - M_C(name,_segment_t) *segment = mem->current_segment; \ - assert(segment != NULL); \ - unsigned int count = segment->count; \ - if (M_UNLIKELY (count >= MEMPOOL_MAX_PER_SEGMENT(type))) { \ +#define MEMPOOL_DEF_P2(name, type) \ + \ + typedef union M_C(name,_union_s) { \ + type t; \ + union M_C(name,_union_s) *next; \ + } M_C(name,_union_t); \ + \ + typedef struct M_C(name,_segment_s) { \ + unsigned int count; \ + struct M_C(name,_segment_s) *next; \ + M_C(name,_union_t) tab[MEMPOOL_MAX_PER_SEGMENT(type)]; \ + } M_C(name,_segment_t); \ + \ + typedef struct M_C(name, _s) { \ + M_C(name,_union_t) *free_list; \ + M_C(name,_segment_t) *current_segment; \ + } M_C(name,_t)[1]; \ + \ + static inline void \ + M_C(name,_init)(M_C(name,_t) mem) \ + { \ + mem->free_list = NULL; \ + mem->current_segment = M_MEMORY_ALLOC(M_C(name,_segment_t)); \ + if (mem->current_segment == NULL) { \ + M_MEMORY_FULL(sizeof (M_C(name,_segment_t))); \ + return; \ + } \ + mem->current_segment->next = NULL; \ + mem->current_segment->count = 0; \ + MEMPOOLI_CONTRACT(mem, type); \ + } \ + \ + static inline void \ + M_C(name,_clear)(M_C(name,_t) mem) \ + { \ + MEMPOOLI_CONTRACT(mem, type); \ + M_C(name,_segment_t) *segment = mem->current_segment; \ + while (segment != NULL) { \ + M_C(name,_segment_t) *next = segment->next; \ + M_MEMORY_DEL (segment); \ + segment = next; \ + } \ + /* Clean pointers to be safer */ \ + mem->free_list = NULL; \ + mem->current_segment = NULL; \ + } \ + \ + static inline type * \ + M_C(name,_alloc)(M_C(name,_t) mem) \ + { \ + MEMPOOLI_CONTRACT(mem, type); \ + M_C(name,_union_t) *ret = mem->free_list; \ + if (ret != NULL) { \ + mem->free_list = ret->next; \ + return &ret->t; \ + } \ + M_C(name,_segment_t) *segment = mem->current_segment; \ + assert(segment != NULL); \ + unsigned int count = segment->count; \ + if (M_UNLIKELY (count >= MEMPOOL_MAX_PER_SEGMENT(type))) { \ M_C(name,_segment_t) *new_segment = M_MEMORY_ALLOC (M_C(name,_segment_t)); \ - if (M_UNLIKELY (new_segment == NULL)) { \ - M_MEMORY_FULL(sizeof (M_C(name,_segment_t))); \ - return NULL; \ - } \ - new_segment->next = segment; \ - new_segment->count = 0; \ - mem->current_segment = new_segment; \ - segment = new_segment; \ - count = 0; \ - } \ - ret = &segment->tab[count]; \ - segment->count = count + 1; \ - MEMPOOLI_CONTRACT(mem, type); \ - return &ret->t; \ - } \ - \ - static inline void \ - M_C(name,_free)(M_C(name,_t) mem, type *ptr) \ - { \ - MEMPOOLI_CONTRACT(mem, type); \ - /* NOTE: Unsafe cast: suppose that the given pointer \ - was allocated by the previous alloc function. */ \ - M_C(name,_union_t) *ret = (M_C(name,_union_t) *)(uintptr_t)ptr; \ - ret->next = mem->free_list; \ - mem->free_list = ret; \ - MEMPOOLI_CONTRACT(mem, type); \ - } \ + if (M_UNLIKELY (new_segment == NULL)) { \ + M_MEMORY_FULL(sizeof (M_C(name,_segment_t))); \ + return NULL; \ + } \ + new_segment->next = segment; \ + new_segment->count = 0; \ + mem->current_segment = new_segment; \ + segment = new_segment; \ + count = 0; \ + } \ + ret = &segment->tab[count]; \ + segment->count = count + 1; \ + MEMPOOLI_CONTRACT(mem, type); \ + return &ret->t; \ + } \ + \ + static inline void \ + M_C(name,_free)(M_C(name,_t) mem, type *ptr) \ + { \ + MEMPOOLI_CONTRACT(mem, type); \ + /* NOTE: Unsafe cast: suppose that the given pointer \ + was allocated by the previous alloc function. */ \ + M_C(name,_union_t) *ret = (M_C(name,_union_t) *)(uintptr_t)ptr; \ + ret->next = mem->free_list; \ + mem->free_list = ret; \ + MEMPOOLI_CONTRACT(mem, type); \ + } \ -#define MEMPOOLI_CONTRACT(mempool, type) do { \ - assert((mempool) != NULL); \ - assert((mempool)->current_segment != NULL); \ +#define MEMPOOLI_CONTRACT(mempool, type) do { \ + assert((mempool) != NULL); \ + assert((mempool)->current_segment != NULL); \ assert((mempool)->current_segment->count <= MEMPOOL_MAX_PER_SEGMENT(type)); \ } while (0) diff --git a/m-prioqueue.h b/m-prioqueue.h index 7e59cbca..b5191eed 100644 --- a/m-prioqueue.h +++ b/m-prioqueue.h @@ -56,31 +56,31 @@ #define PRIOQUEUEI_OPLIST_P1(arg) PRIOQUEUEI_OPLIST_P2 arg /* Validation of the given oplist */ -#define PRIOQUEUEI_OPLIST_P2(name, oplist) \ +#define PRIOQUEUEI_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(PRIOQUEUEI_OPLIST_P3, PRIOQUEUEI_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define PRIOQUEUEI_OPLIST_FAILURE(name, oplist) \ +#define PRIOQUEUEI_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_PRIOQUEUE_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) /* Define oplist of a priority queue */ -#define PRIOQUEUEI_OPLIST_P3(name, oplist) \ - (INIT(M_C(name, _init)) \ - ,INIT_SET(M_C(name, _init_set)) \ - ,INIT_WITH(API_1(M_INIT_VAI)) \ - ,SET(M_C(name, _set)) \ - ,CLEAR(M_C(name, _clear)) \ - ,INIT_MOVE(M_C(name, _init_move)) \ - ,MOVE(M_C(name, _move)) \ - ,SWAP(M_C(name, _swap)) \ - ,TYPE(M_C(name,_t)) \ - ,SUBTYPE(M_C(name, _type_t)) \ - ,CLEAN(M_C(name,_clean)) \ - ,PUSH(M_C(name,_push)) \ - ,POP(M_C(name,_pop)) \ - ,OPLIST(oplist) \ - ,TEST_EMPTY(M_C(name, _empty_p)), \ - ,GET_SIZE(M_C(name, _size)) \ +#define PRIOQUEUEI_OPLIST_P3(name, oplist) \ + (INIT(M_C(name, _init)) \ + ,INIT_SET(M_C(name, _init_set)) \ + ,INIT_WITH(API_1(M_INIT_VAI)) \ + ,SET(M_C(name, _set)) \ + ,CLEAR(M_C(name, _clear)) \ + ,INIT_MOVE(M_C(name, _init_move)) \ + ,MOVE(M_C(name, _move)) \ + ,SWAP(M_C(name, _swap)) \ + ,TYPE(M_C(name,_t)) \ + ,SUBTYPE(M_C(name, _type_t)) \ + ,CLEAN(M_C(name,_clean)) \ + ,PUSH(M_C(name,_push)) \ + ,POP(M_C(name,_pop)) \ + ,OPLIST(oplist) \ + ,TEST_EMPTY(M_C(name, _empty_p)), \ + ,GET_SIZE(M_C(name, _size)) \ ) @@ -89,11 +89,11 @@ #define PRIOQUEUEI_DEF_P1(arg) PRIOQUEUEI_DEF_P2 arg /* Validate the oplist before going further */ -#define PRIOQUEUEI_DEF_P2(name, type, oplist, prioqueue_t, it_t) \ +#define PRIOQUEUEI_DEF_P2(name, type, oplist, prioqueue_t, it_t) \ M_IF_OPLIST(oplist)(PRIOQUEUEI_DEF_P3, PRIOQUEUEI_DEF_FAILURE)(name, type, oplist, prioqueue_t, it_t) /* Stop processing with a compilation failure */ -#define PRIOQUEUEI_DEF_FAILURE(name, type, oplist, prioqueue_t, it_t) \ +#define PRIOQUEUEI_DEF_FAILURE(name, type, oplist, prioqueue_t, it_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(PRIOQUEUE_DEF): the given argument is not a valid oplist: " #oplist) /* Define the priority queue: @@ -106,8 +106,8 @@ #define PRIOQUEUEI_DEF_P3(name, type, oplist, prioqueue_t, it_t) \ ARRAY_DEF(M_C(name, _array), type, oplist) \ \ - typedef type M_C(name, _type_t); \ - \ + typedef type M_C(name, _type_t); \ + \ typedef struct M_C(name, _s) { \ M_C(name, _array_t) array; \ } prioqueue_t[1]; \ @@ -256,13 +256,13 @@ } \ \ static inline void \ - M_C(name, _it_last)(it_t it, prioqueue_t const v) \ + M_C(name, _it_last)(it_t it, prioqueue_t const v) \ { \ M_C(name, _array_it_last)(it, v->array); \ } \ \ static inline void \ - M_C(name, _it_end)(it_t it, prioqueue_t const v) \ + M_C(name, _it_end)(it_t it, prioqueue_t const v) \ { \ M_C(name, _array_it_end)(it, v->array); \ } \ @@ -286,8 +286,8 @@ } \ \ static inline bool \ - M_C(name, _it_equal_p)(const it_t it1, \ - const it_t it2) \ + M_C(name, _it_equal_p)(const it_t it1, \ + const it_t it2) \ { \ return M_C(name, _array_it_equal_p)(it1, it2); \ } \ @@ -305,7 +305,7 @@ } \ \ static inline type const * \ - M_C(name, _cref)(const it_t it) \ + M_C(name, _cref)(const it_t it) \ { \ return M_C(name, _array_cref)(it); \ } \ @@ -378,8 +378,8 @@ } \ } \ \ - , /* No EQUAL */ ) \ - + , /* No EQUAL */ ) \ + // TODO: set all & remove all function diff --git a/m-rbtree.h b/m-rbtree.h index a606d5d8..eb0351da 100644 --- a/m-rbtree.h +++ b/m-rbtree.h @@ -43,7 +43,7 @@ USAGE: RBTREE_OPLIST(name [, oplist_of_the_type]) */ #define RBTREE_OPLIST(...) \ RBTREEI_OPLIST_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((__VA_ARGS__, M_DEFAULT_OPLIST), \ + ((__VA_ARGS__, M_DEFAULT_OPLIST), \ (__VA_ARGS__ ))) @@ -54,54 +54,54 @@ #define RBTREEI_OPLIST_P1(arg) RBTREEI_OPLIST_P2 arg /* Validation of the given oplist */ -#define RBTREEI_OPLIST_P2(name, oplist) \ +#define RBTREEI_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(RBTREEI_OPLIST_P3, RBTREEI_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define RBTREEI_OPLIST_FAILURE(name, oplist) \ +#define RBTREEI_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_RBTREE_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) /* OPLIST definition of a rbtree NOTE: IT_REF is not exported so that the contained appears as not modifiable by algorithm.*/ -#define RBTREEI_OPLIST_P3(name, oplist) \ - (INIT(M_C(name, _init)), \ - INIT_SET(M_C(name, _init_set)), \ - INIT_WITH(API_1(M_INIT_VAI)), \ - SET(M_C(name, _set)), \ - CLEAR(M_C(name, _clear)), \ - INIT_MOVE(M_C(name, _init_move)), \ - MOVE(M_C(name, _move)), \ - SWAP(M_C(name, _swap)), \ - TYPE(M_C(name,_t)), \ - SUBTYPE(M_C(name, _type_t)), \ - TEST_EMPTY(M_C(name,_empty_p)), \ - GET_SIZE(M_C(name, _size)), \ - IT_TYPE(M_C(name, _it_t)), \ - IT_FIRST(M_C(name,_it)), \ - IT_SET(M_C(name,_it_set)), \ - IT_LAST(M_C(name,_it_last)), \ - IT_END(M_C(name,_it_end)), \ - IT_END_P(M_C(name,_end_p)), \ - IT_LAST_P(M_C(name,_last_p)), \ - IT_EQUAL_P(M_C(name,_it_equal_p)), \ - IT_NEXT(M_C(name,_next)), \ - IT_CREF(M_C(name,_cref)), \ - CLEAN(M_C(name,_clean)), \ - PUSH(M_C(name,_push)), \ - GET_MIN(M_C(name,_min)), \ - GET_MAX(M_C(name,_max)), \ - M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),), \ - M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),), \ - M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),), \ - M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),), \ - M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),), \ - M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),), \ - M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),), \ - M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \ - ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ - ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \ - ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ +#define RBTREEI_OPLIST_P3(name, oplist) \ + (INIT(M_C(name, _init)), \ + INIT_SET(M_C(name, _init_set)), \ + INIT_WITH(API_1(M_INIT_VAI)), \ + SET(M_C(name, _set)), \ + CLEAR(M_C(name, _clear)), \ + INIT_MOVE(M_C(name, _init_move)), \ + MOVE(M_C(name, _move)), \ + SWAP(M_C(name, _swap)), \ + TYPE(M_C(name,_t)), \ + SUBTYPE(M_C(name, _type_t)), \ + TEST_EMPTY(M_C(name,_empty_p)), \ + GET_SIZE(M_C(name, _size)), \ + IT_TYPE(M_C(name, _it_t)), \ + IT_FIRST(M_C(name,_it)), \ + IT_SET(M_C(name,_it_set)), \ + IT_LAST(M_C(name,_it_last)), \ + IT_END(M_C(name,_it_end)), \ + IT_END_P(M_C(name,_end_p)), \ + IT_LAST_P(M_C(name,_last_p)), \ + IT_EQUAL_P(M_C(name,_it_equal_p)), \ + IT_NEXT(M_C(name,_next)), \ + IT_CREF(M_C(name,_cref)), \ + CLEAN(M_C(name,_clean)), \ + PUSH(M_C(name,_push)), \ + GET_MIN(M_C(name,_min)), \ + GET_MAX(M_C(name,_max)), \ + M_IF_METHOD(GET_STR, oplist)(GET_STR(M_C(name, _get_str)),), \ + M_IF_METHOD(PARSE_STR, oplist)(PARSE_STR(M_C(name, _parse_str)),), \ + M_IF_METHOD(OUT_STR, oplist)(OUT_STR(M_C(name, _out_str)),), \ + M_IF_METHOD(IN_STR, oplist)(IN_STR(M_C(name, _in_str)),), \ + M_IF_METHOD(OUT_SERIAL, oplist)(OUT_SERIAL(M_C(name, _out_serial)),), \ + M_IF_METHOD(IN_SERIAL, oplist)(IN_SERIAL(M_C(name, _in_serial)),), \ + M_IF_METHOD(EQUAL, oplist)(EQUAL(M_C(name, _equal_p)),), \ + M_IF_METHOD(HASH, oplist)(HASH(M_C(name, _hash)),) \ + ,M_IF_METHOD(NEW, oplist)(NEW(M_GET_NEW oplist),) \ + ,M_IF_METHOD(REALLOC, oplist)(REALLOC(M_GET_REALLOC oplist),) \ + ,M_IF_METHOD(DEL, oplist)(DEL(M_GET_DEL oplist),) \ ) /* Max depth of the binary tree @@ -139,8 +139,8 @@ typedef enum { assert((node) != NULL); \ assert(RBTREEI_IS_BLACK(node) || RBTREEI_IS_RED(node)); \ assert(RBTREEI_IS_BLACK(node) \ - || (((node)->child[0] == NULL || RBTREEI_IS_BLACK(node->child[0])) \ - && ((node)->child[1] == NULL || RBTREEI_IS_BLACK(node->child[1])))); \ + || (((node)->child[0] == NULL || RBTREEI_IS_BLACK(node->child[0])) \ + && ((node)->child[1] == NULL || RBTREEI_IS_BLACK(node->child[1])))); \ } while (0) //TODO: UPDATE method shall be a separate method than push method @@ -870,7 +870,7 @@ typedef enum { s = p->child[!nbChild]; \ /* if sibling is red, perform a rotation to move sibling up */ \ if (!M_C(name, _int_is_black)(s)) { \ - p = M_C(name, _int_rotate) (p, tab[cpt-1], !nbChild); \ + p = M_C(name, _int_rotate) (p, tab[cpt-1], !nbChild); \ RBTREEI_SET_BLACK(p); /* was sibling */ \ tab[cpt] = p; \ which[cpt++] = nbChild; \ @@ -930,7 +930,7 @@ typedef enum { M_DO_MOVE(oplist, *data_ptr, n->data); \ else \ M_CALL_CLEAR(oplist, n->data); \ - M_C(name,_int_del) (n); \ + M_C(name,_int_del) (n); \ tree->size --; \ RBTREEI_CONTRACT (tree); \ return true; \ @@ -982,7 +982,7 @@ typedef enum { \ M_IF_METHOD(GET_STR, oplist)( \ static inline void M_C(name, _get_str)(string_t str, \ - tree_t const t1, bool append) { \ + tree_t const t1, bool append) { \ RBTREEI_CONTRACT(t1); \ assert(str != NULL); \ (append ? string_cat_str : string_set_str) (str, "["); \ @@ -1118,7 +1118,7 @@ typedef enum { size_t estimated_size = 0; \ type key; \ M_C(name,_clean)(t1); \ - ret = f->m_interface->read_array_start(local, f, &estimated_size); \ + ret = f->m_interface->read_array_start(local, f, &estimated_size); \ if (M_UNLIKELY (ret != M_SERIAL_OK_CONTINUE)) return ret; \ M_CALL_INIT(oplist, key); \ do { \ @@ -1130,7 +1130,7 @@ typedef enum { return ret; \ } \ , /* no in_serial */ ) \ - \ + \ \ // TODO: specialized _sort shall do nothing, but shall check the requested order. How ? diff --git a/m-shared.h b/m-shared.h index 6b5b9e24..f28e05f0 100644 --- a/m-shared.h +++ b/m-shared.h @@ -75,11 +75,11 @@ M_BEGIN_PROTECTED_CODE #define SHAREDI_PTR_OPLIST_P1(arg) SHAREDI_PTR_OPLIST_P2 arg /* Validation of the given oplist */ -#define SHAREDI_PTR_OPLIST_P2(name, oplist) \ +#define SHAREDI_PTR_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(SHAREDI_PTR_OPLIST_P3, SHAREDI_PTR_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define SHAREDI_PTR_OPLIST_FAILURE(name, oplist) \ +#define SHAREDI_PTR_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_SHARED_PTR_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) #define SHAREDI_PTR_OPLIST_P3(name, oplist) ( \ @@ -136,97 +136,97 @@ static inline int sharedi_integer_cref(int *p) { return *p; } /* Code generation */ #define SHAREDI_PTR_DEF_P3(name, type, oplist, cpt_oplist) \ - \ - typedef struct M_C(name, _s){ \ - type *data; /* Pointer to the data */ \ + \ + typedef struct M_C(name, _s){ \ + type *data; /* Pointer to the data */ \ M_GET_TYPE cpt_oplist cpt; /* Counter of how many points to the data */ \ bool combineAlloc; /* Does the data and the ptr share the slot? */ \ - } *M_C(name, _t)[1]; \ + } *M_C(name, _t)[1]; \ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ - \ + \ typedef struct M_C(name, combine_s) { \ type data; \ - struct M_C(name, _s) ptr; \ - } M_C(name, combine_t)[1]; \ + struct M_C(name, _s) ptr; \ + } M_C(name, combine_t)[1]; \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ - static inline void \ + static inline void \ M_C(name, _init)(M_C(name, _t) shared) \ - { \ + { \ *shared = NULL; \ } \ \ - static inline void \ - M_C(name, _init2)(M_C(name, _t) shared, type *data) \ - { \ + static inline void \ + M_C(name, _init2)(M_C(name, _t) shared, type *data) \ + { \ assert (shared != NULL); \ /* The shared ptr get exclusive access to data */ \ - struct M_C(name, _s) *ptr; \ + struct M_C(name, _s) *ptr; \ if (M_UNLIKELY (data == NULL)) { \ *shared = NULL; \ return; \ } \ - ptr = M_CALL_NEW(oplist, struct M_C(name, _s)); \ + ptr = M_CALL_NEW(oplist, struct M_C(name, _s)); \ if (M_UNLIKELY (ptr == NULL)) { \ - M_MEMORY_FULL(sizeof(struct M_C(name, _s))); \ + M_MEMORY_FULL(sizeof(struct M_C(name, _s))); \ return; \ } \ - ptr->data = data; \ + ptr->data = data; \ M_CALL_INIT_SET(cpt_oplist, &ptr->cpt, 1); \ ptr->combineAlloc = false; \ - *shared = ptr; \ + *shared = ptr; \ SHAREDI_CONTRACT(shared, cpt_oplist); \ - } \ - \ - static inline void \ - M_C(name, _init_new)(M_C(name, _t) shared) \ - { \ + } \ + \ + static inline void \ + M_C(name, _init_new)(M_C(name, _t) shared) \ + { \ /* NOTE: Alloc 1 struct with both structures. */ \ - struct M_C(name, combine_s) *p = \ - M_CALL_NEW(oplist, struct M_C(name, combine_s)); \ + struct M_C(name, combine_s) *p = \ + M_CALL_NEW(oplist, struct M_C(name, combine_s)); \ if (M_UNLIKELY (p == NULL)) { \ - M_MEMORY_FULL(sizeof(struct M_C(name, combine_s))); \ - return; \ + M_MEMORY_FULL(sizeof(struct M_C(name, combine_s))); \ + return; \ } \ - struct M_C(name, _s) *ptr = &p->ptr; \ + struct M_C(name, _s) *ptr = &p->ptr; \ type *data = &p->data; \ M_CALL_INIT( oplist, *data); \ - ptr->data = data; \ + ptr->data = data; \ M_CALL_INIT_SET(cpt_oplist, &ptr->cpt, 1); \ ptr->combineAlloc = true; \ - *shared = ptr; \ + *shared = ptr; \ SHAREDI_CONTRACT(shared, cpt_oplist); \ - } \ - \ - static inline bool \ - M_C(name, _NULL_p)(const M_C(name, _t) shared) \ - { \ + } \ + \ + static inline bool \ + M_C(name, _NULL_p)(const M_C(name, _t) shared) \ + { \ SHAREDI_CONTRACT(shared, cpt_oplist); \ - return *shared == NULL; \ - } \ - \ - static inline void \ - M_C(name, _init_set)(M_C(name, _t) dest, \ - const M_C(name, _t) shared) \ - { \ + return *shared == NULL; \ + } \ + \ + static inline void \ + M_C(name, _init_set)(M_C(name, _t) dest, \ + const M_C(name, _t) shared) \ + { \ SHAREDI_CONTRACT(shared, cpt_oplist); \ assert (dest != shared); \ - *dest = *shared; \ - if (*dest != NULL) { \ - int n = M_CALL_ADD(cpt_oplist, &((*dest)->cpt), 1); \ - (void) n; /* unused return value */ \ - } \ + *dest = *shared; \ + if (*dest != NULL) { \ + int n = M_CALL_ADD(cpt_oplist, &((*dest)->cpt), 1); \ + (void) n; /* unused return value */ \ + } \ SHAREDI_CONTRACT(dest, cpt_oplist); \ - } \ - \ - static inline void \ - M_C(name, _clear)(M_C(name, _t) dest) \ - { \ + } \ + \ + static inline void \ + M_C(name, _clear)(M_C(name, _t) dest) \ + { \ SHAREDI_CONTRACT(dest, cpt_oplist); \ - if (*dest != NULL) { \ - if (M_CALL_SUB(cpt_oplist, &((*dest)->cpt), 1) == 1) { \ + if (*dest != NULL) { \ + if (M_CALL_SUB(cpt_oplist, &((*dest)->cpt), 1) == 1) { \ bool combineAlloc = (*dest)->combineAlloc; \ /* Note: if combineAlloc is true, the address of the slot \ combining both data & ptr is the same as the address of the \ @@ -236,96 +236,96 @@ static inline int sharedi_integer_cref(int *p) { return *p; } M_CALL_DEL(oplist, (*dest)->data); \ if (combineAlloc == false) \ M_CALL_DEL(oplist, *dest); \ - } \ + } \ *dest = NULL; \ } \ SHAREDI_CONTRACT(dest, cpt_oplist); \ - } \ - \ - static inline void \ - M_C(name, _clean)(M_C(name, _t) dest) \ - { \ - /* NOTE: Clear will also set dest to NULL */ \ - M_C(name, _clear)(dest); \ } \ - \ - static inline void \ - M_C(name, _set)(M_C(name, _t) dest, \ - const M_C(name, _t) shared) \ - { \ + \ + static inline void \ + M_C(name, _clean)(M_C(name, _t) dest) \ + { \ + /* NOTE: Clear will also set dest to NULL */ \ + M_C(name, _clear)(dest); \ + } \ + \ + static inline void \ + M_C(name, _set)(M_C(name, _t) dest, \ + const M_C(name, _t) shared) \ + { \ SHAREDI_CONTRACT(dest, cpt_oplist); \ SHAREDI_CONTRACT(shared, cpt_oplist); \ - M_C(name, _clear)(dest); \ - M_C(name, _init_set)(dest, shared); \ - } \ - \ - static inline void \ - M_C(name, _init_move)(M_C(name, _t) dest, \ - M_C(name, _t) shared) \ - { \ + M_C(name, _clear)(dest); \ + M_C(name, _init_set)(dest, shared); \ + } \ + \ + static inline void \ + M_C(name, _init_move)(M_C(name, _t) dest, \ + M_C(name, _t) shared) \ + { \ SHAREDI_CONTRACT(shared, cpt_oplist); \ assert (dest != NULL && dest != shared); \ - *dest = *shared; \ + *dest = *shared; \ *shared = NULL; \ SHAREDI_CONTRACT(dest, cpt_oplist); \ - } \ - \ - static inline void \ - M_C(name, _move)(M_C(name, _t) dest, \ - M_C(name, _t) shared) \ - { \ + } \ + \ + static inline void \ + M_C(name, _move)(M_C(name, _t) dest, \ + M_C(name, _t) shared) \ + { \ SHAREDI_CONTRACT(dest, cpt_oplist); \ SHAREDI_CONTRACT(shared, cpt_oplist); \ - assert (dest != shared); \ - M_C(name, _clear)(dest); \ - M_C(name, _init_move)(dest, shared); \ - } \ - \ - static inline void \ - M_C(name, _swap)(M_C(name, _t) p1, \ - M_C(name, _t) p2) \ - { \ + assert (dest != shared); \ + M_C(name, _clear)(dest); \ + M_C(name, _init_move)(dest, shared); \ + } \ + \ + static inline void \ + M_C(name, _swap)(M_C(name, _t) p1, \ + M_C(name, _t) p2) \ + { \ SHAREDI_CONTRACT(p1, cpt_oplist); \ SHAREDI_CONTRACT(p2, cpt_oplist); \ - M_SWAP (struct M_C(name, _s)*, *p1, *p2); \ + M_SWAP (struct M_C(name, _s)*, *p1, *p2); \ SHAREDI_CONTRACT(p1, cpt_oplist); \ SHAREDI_CONTRACT(p2, cpt_oplist); \ - } \ - \ - static inline bool \ - M_C(name, _equal_p)(const M_C(name, _t) p1, \ - const M_C(name, _t) p2) \ - { \ + } \ + \ + static inline bool \ + M_C(name, _equal_p)(const M_C(name, _t) p1, \ + const M_C(name, _t) p2) \ + { \ SHAREDI_CONTRACT(p1, cpt_oplist); \ SHAREDI_CONTRACT(p2, cpt_oplist); \ - return *p1 == *p2; \ - } \ - \ - static inline type const * \ - M_C(name, _cref)(const M_C(name, _t) shared) \ - { \ + return *p1 == *p2; \ + } \ + \ + static inline type const * \ + M_C(name, _cref)(const M_C(name, _t) shared) \ + { \ SHAREDI_CONTRACT(shared, cpt_oplist); \ assert(*shared != NULL); \ type *data = (*shared)->data; \ assert (data != NULL); \ return M_CONST_CAST (type, data); \ - } \ - \ - static inline type * \ - M_C(name, _ref)(M_C(name, _t) shared) \ - { \ + } \ + \ + static inline type * \ + M_C(name, _ref)(M_C(name, _t) shared) \ + { \ SHAREDI_CONTRACT(shared, cpt_oplist); \ assert(*shared != NULL); \ type *data = (*shared)->data; \ assert (data != NULL); \ return data; \ - } \ + } \ /********************************** SHARED RESOURCE ************************************/ -#define SHAREDI_RESOURCE_CONTRACT(s) do { \ - assert (s != NULL); \ - assert (s->buffer != NULL); \ +#define SHAREDI_RESOURCE_CONTRACT(s) do { \ + assert (s != NULL); \ + assert (s->buffer != NULL); \ } while (0) // deferred @@ -344,7 +344,7 @@ static inline int sharedi_integer_cref(int *p) { return *p; } /* Create an aligned type to avoid false sharing between threads */ \ typedef struct M_C(name, _atype_s) { \ atomic_uint cpt; \ - type x; \ + type x; \ M_CACHELINE_ALIGN(align, type, atomic_uint); \ } M_C(name, _atype_t); \ \ diff --git a/m-snapshot.h b/m-snapshot.h index 2cc79ea5..a0d19ce6 100644 --- a/m-snapshot.h +++ b/m-snapshot.h @@ -75,24 +75,24 @@ M_BEGIN_PROTECTED_CODE #define SNAPSHOTI_OPLIST_P1(arg) SNAPSHOTI_OPLIST_P2 arg /* Validation of the given oplist */ -#define SNAPSHOTI_OPLIST_P2(name, oplist) \ +#define SNAPSHOTI_OPLIST_P2(name, oplist) \ M_IF_OPLIST(oplist)(SNAPSHOTI_OPLIST_P3, SNAPSHOTI_OPLIST_FAILURE)(name, oplist) /* Prepare a clean compilation failure */ -#define SNAPSHOTI_OPLIST_FAILURE(name, oplist) \ +#define SNAPSHOTI_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_SNAPSHOT_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) /* Define the oplist of a snapshot */ -#define SNAPSHOTI_OPLIST_P3(name, oplist) \ - (INIT(M_C(name, _init)) \ - ,INIT_SET(M_C(name, _init_set)) \ - ,SET(M_C(name, _set)) \ - ,CLEAR(M_C(name, _clear)) \ - ,TYPE(M_C(name, _t)) \ - ,SUBTYPE(M_C(name_, type_t)) \ - ,OPLIST(oplist) \ - ,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_C(name, _init_move)),) \ - ,M_IF_METHOD(MOVE, oplist)(MOVE(M_C(name, _move)),) \ +#define SNAPSHOTI_OPLIST_P3(name, oplist) \ + (INIT(M_C(name, _init)) \ + ,INIT_SET(M_C(name, _init_set)) \ + ,SET(M_C(name, _set)) \ + ,CLEAR(M_C(name, _clear)) \ + ,TYPE(M_C(name, _t)) \ + ,SUBTYPE(M_C(name_, type_t)) \ + ,OPLIST(oplist) \ + ,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_C(name, _init_move)),) \ + ,M_IF_METHOD(MOVE, oplist)(MOVE(M_C(name, _move)),) \ ) @@ -105,25 +105,26 @@ M_BEGIN_PROTECTED_CODE * - b: Boolean indicating that the read buffer shall be updated * all fields packed in an unsigned char type. */ -#define SNAPSHOTI_SPSC_FLAG(r, w, f, b) \ +#define SNAPSHOTI_SPSC_FLAG(r, w, f, b) \ ((unsigned char)( ( (r) << 4) | ((w) << 2) | ((f)) | ((b) << 6))) -#define SNAPSHOTI_SPSC_R(flags) \ +#define SNAPSHOTI_SPSC_R(flags) \ (((unsigned int) (flags) >> 4) & 0x03u) -#define SNAPSHOTI_SPSC_W(flags) \ +#define SNAPSHOTI_SPSC_W(flags) \ (((unsigned int) (flags) >> 2) & 0x03u) -#define SNAPSHOTI_SPSC_F(flags) \ +#define SNAPSHOTI_SPSC_F(flags) \ (((unsigned int) (flags) >> 0) & 0x03u) -#define SNAPSHOTI_SPSC_B(flags) \ +#define SNAPSHOTI_SPSC_B(flags) \ (((unsigned int) (flags) >> 6) & 0x01u) /* NOTE: Due to atomic_load only accepting non-const pointer, we can't have any const in the interface. */ #define SNAPSHOTI_SPSC_FLAGS_CONTRACT(flags) \ assert(SNAPSHOTI_SPSC_R(flags) != SNAPSHOTI_SPSC_W(flags) \ - && SNAPSHOTI_SPSC_R(flags) != SNAPSHOTI_SPSC_F(flags) \ - && SNAPSHOTI_SPSC_W(flags) != SNAPSHOTI_SPSC_F(flags)) -#define SNAPSHOTI_SPSC_CONTRACT(snap) do { \ - assert((snap) != NULL); \ + && SNAPSHOTI_SPSC_R(flags) != SNAPSHOTI_SPSC_F(flags) \ + && SNAPSHOTI_SPSC_W(flags) != SNAPSHOTI_SPSC_F(flags)) + +#define SNAPSHOTI_SPSC_CONTRACT(snap) do { \ + assert((snap) != NULL); \ unsigned char f = atomic_load (&(snap)->flags); \ SNAPSHOTI_SPSC_FLAGS_CONTRACT(f); \ } while (0) @@ -133,10 +134,10 @@ M_BEGIN_PROTECTED_CODE #define SNAPSHOTI_SPSC_MAX_BUFFER 3 // Defered evaluation of the arguments. -#define SNAPSHOTI_SPSC_DEF_P1(arg) SNAPSHOTI_SPSC_DEF_P2 arg +#define SNAPSHOTI_SPSC_DEF_P1(arg) SNAPSHOTI_SPSC_DEF_P2 arg /* Validate the oplist before going further */ -#define SNAPSHOTI_SPSC_DEF_P2(name, type, oplist) \ +#define SNAPSHOTI_SPSC_DEF_P2(name, type, oplist) \ M_IF_OPLIST(oplist)(SNAPSHOTI_SPSC_DEF_P3, SNAPSHOTI_SPSC_DEF_FAILURE)(name, type, oplist) /* Stop processing with a compilation failure */ @@ -147,14 +148,14 @@ M_BEGIN_PROTECTED_CODE \ /* Create an aligned type to avoid false sharing between threads */ \ typedef struct M_C(name, _aligned_type_s) { \ - type x; \ + type x; \ M_CACHELINE_ALIGN(align, type); \ } M_C(name, _aligned_type_t); \ \ - typedef struct M_C(name, _s) { \ + typedef struct M_C(name, _s) { \ M_C(name, _aligned_type_t) data[SNAPSHOTI_SPSC_MAX_BUFFER]; \ atomic_uchar flags; \ - } M_C(name, _t)[1]; \ + } M_C(name, _t)[1]; \ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ @@ -163,107 +164,107 @@ M_BEGIN_PROTECTED_CODE M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ static inline void M_C(name, _init)(M_C(name, _t) snap) \ - { \ - assert(snap != NULL); \ + { \ + assert(snap != NULL); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ M_CALL_INIT(oplist, snap->data[i].x); \ - } \ + } \ atomic_init (&snap->flags, SNAPSHOTI_SPSC_FLAG(0, 1, 2, 0)); \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - } \ + } \ \ - static inline void M_C(name, _clear)(M_C(name, _t) snap) \ - { \ + static inline void M_C(name, _clear)(M_C(name, _t) snap) \ + { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ - M_CALL_CLEAR(oplist, snap->data[i].x); \ - } \ - } \ + M_CALL_CLEAR(oplist, snap->data[i].x); \ + } \ + } \ \ - static inline void M_C(name, _init_set)(M_C(name, _t) snap, \ - M_C(name, _t) org) \ - { \ + static inline void M_C(name, _init_set)(M_C(name, _t) snap, \ + M_C(name, _t) org) \ + { \ SNAPSHOTI_SPSC_CONTRACT(org); \ - assert(snap != NULL && snap != org); \ + assert(snap != NULL && snap != org); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ - M_CALL_INIT_SET(oplist, snap->data[i].x, org->data[i].x); \ - } \ - atomic_init (&snap->flags, atomic_load(&org->flags)); \ + M_CALL_INIT_SET(oplist, snap->data[i].x, org->data[i].x); \ + } \ + atomic_init (&snap->flags, atomic_load(&org->flags)); \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - } \ + } \ \ - static inline void M_C(name, _set)(M_C(name, _t) snap, \ - M_C(name, _t) org) \ - { \ + static inline void M_C(name, _set)(M_C(name, _t) snap, \ + M_C(name, _t) org) \ + { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ SNAPSHOTI_SPSC_CONTRACT(org); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ M_CALL_SET(oplist, snap->data[i].x, org->data[i].x); \ - } \ - atomic_init (&snap->flags, atomic_load(&org->flags)); \ + } \ + atomic_init (&snap->flags, atomic_load(&org->flags)); \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - } \ + } \ \ - M_IF_METHOD(INIT_MOVE, oplist)( \ + M_IF_METHOD(INIT_MOVE, oplist)( \ static inline void M_C(name, _init_move)(M_C(name, _t) snap, \ - M_C(name, _t) org) \ - { \ + M_C(name, _t) org) \ + { \ SNAPSHOTI_SPSC_CONTRACT(org); \ - assert(snap != NULL && snap != org); \ + assert(snap != NULL && snap != org); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ - M_CALL_INIT_MOVE(oplist, snap->data[i].x, org->data[i].x); \ - } \ + M_CALL_INIT_MOVE(oplist, snap->data[i].x, org->data[i].x); \ + } \ atomic_store (&snap->flags, atomic_load(&org->flags)); \ atomic_store (&org->flags, SNAPSHOTI_SPSC_FLAG(0,0,0,0) ); \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - } \ - ,) /* IF_METHOD (INIT_MOVE) */ \ + } \ + ,) /* IF_METHOD (INIT_MOVE) */ \ \ M_IF_METHOD(MOVE, oplist)( \ static inline void M_C(name, _move)(M_C(name, _t) snap, \ - M_C(name, _t) org) \ - { \ - SNAPSHOTI_SPSC_CONTRACT(snap); \ + M_C(name, _t) org) \ + { \ + SNAPSHOTI_SPSC_CONTRACT(snap); \ SNAPSHOTI_SPSC_CONTRACT(org); \ - assert(snap != org); \ + assert(snap != org); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ - M_CALL_MOVE(oplist, snap->data[i].x, org->data[i].x); \ - } \ + M_CALL_MOVE(oplist, snap->data[i].x, org->data[i].x); \ + } \ atomic_store (&snap->flags, atomic_load(&org->flags)); \ atomic_store (&org->flags, SNAPSHOTI_SPSC_FLAG(0,0,0,0) ); \ - SNAPSHOTI_SPSC_CONTRACT(snap); \ - } \ - ,) /* IF_METHOD (MOVE) */ \ + SNAPSHOTI_SPSC_CONTRACT(snap); \ + } \ + ,) /* IF_METHOD (MOVE) */ \ \ \ static inline type *M_C(name, _write)(M_C(name, _t) snap) \ - { \ + { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ + unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ /* Atomic CAS operation */ \ - do { \ + do { \ /* Swap F and W buffer, setting exchange flag */ \ nextFlags = SNAPSHOTI_SPSC_FLAG(SNAPSHOTI_SPSC_R(origFlags), \ SNAPSHOTI_SPSC_F(origFlags), \ SNAPSHOTI_SPSC_W(origFlags), 1); \ /* exponential backoff is not needed as there can't be more \ than 2 threads which try to update the data. */ \ - } while (!atomic_compare_exchange_weak (&snap->flags, &origFlags, \ - nextFlags)); \ + } while (!atomic_compare_exchange_weak (&snap->flags, &origFlags, \ + nextFlags)); \ /* Return new write buffer for new updating */ \ return &snap->data[SNAPSHOTI_SPSC_W(nextFlags)].x; \ - } \ + } \ \ - static inline type const *M_C(name, _read)(M_C(name, _t) snap) \ - { \ + static inline type const *M_C(name, _read)(M_C(name, _t) snap) \ + { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ + unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ /* Atomic CAS operation */ \ - do { \ + do { \ /* If no exchange registered, do nothing and keep the same */ \ if (!SNAPSHOTI_SPSC_B(origFlags)) { \ nextFlags = origFlags; \ - break; \ + break; \ } \ /* Swap R and F buffer, clearing exchange flag */ \ nextFlags = SNAPSHOTI_SPSC_FLAG(SNAPSHOTI_SPSC_F(origFlags), \ @@ -271,32 +272,32 @@ M_BEGIN_PROTECTED_CODE SNAPSHOTI_SPSC_R(origFlags), 0); \ /* exponential backoff is not needed as there can't be more \ than 2 threads which try to update the data. */ \ - } while (!atomic_compare_exchange_weak (&snap->flags, &origFlags, \ - nextFlags)); \ + } while (!atomic_compare_exchange_weak (&snap->flags, &origFlags, \ + nextFlags)); \ /* Return current read buffer */ \ return M_CONST_CAST(type, &snap->data[SNAPSHOTI_SPSC_R(nextFlags)].x); \ - } \ + } \ \ static inline bool M_C(name, _updated_p)(M_C(name, _t) snap) \ - { \ + { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ unsigned char flags = atomic_load (&snap->flags); \ return SNAPSHOTI_SPSC_B(flags); \ - } \ + } \ \ - static inline type *M_C(name, _get_write_buffer)(M_C(name, _t) snap) \ - { \ + static inline type *M_C(name, _get_write_buffer)(M_C(name, _t) snap) \ + { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - unsigned char flags = atomic_load(&snap->flags); \ + unsigned char flags = atomic_load(&snap->flags); \ return &snap->data[SNAPSHOTI_SPSC_W(flags)].x; \ - } \ + } \ \ static inline type const *M_C(name, _get_read_buffer)(M_C(name, _t) snap) \ - { \ + { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ - unsigned char flags = atomic_load(&snap->flags); \ - return M_CONST_CAST(type, &snap->data[SNAPSHOTI_SPSC_R(flags)].x); \ - } \ + unsigned char flags = atomic_load(&snap->flags); \ + return M_CONST_CAST(type, &snap->data[SNAPSHOTI_SPSC_R(flags)].x); \ + } \ @@ -553,7 +554,7 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) // Defered evaluation -#define SNAPSHOTI_SPMC_DEF_P1(arg) SNAPSHOTI_SPMC_DEF_P2 arg +#define SNAPSHOTI_SPMC_DEF_P1(arg) SNAPSHOTI_SPMC_DEF_P2 arg /* Validate the oplist before going further */ #define SNAPSHOTI_SPMC_DEF_P2(name, type, oplist) \ @@ -567,22 +568,22 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) \ /* Create an aligned type to avoid false sharing between threads */ \ typedef struct M_C(name, _aligned_type_s) { \ - type x; \ + type x; \ M_CACHELINE_ALIGN(align, type); \ } M_C(name, _aligned_type_t); \ \ - typedef struct M_C(name, _s) { \ + typedef struct M_C(name, _s) { \ M_C(name, _aligned_type_t) *data; \ snapshot_mrsw_int_t core; \ - } M_C(name, _t)[1]; \ + } M_C(name, _t)[1]; \ \ typedef type M_C(name, _type_t); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ static inline void M_C(name, _init)(M_C(name, _t) snap, size_t nReader) \ - { \ - assert (snap != NULL); \ + { \ + assert (snap != NULL); \ assert (nReader > 0 && nReader <= SNAPSHOTI_SPMC_MAX_READER); \ snap->data = M_CALL_REALLOC(oplist, M_C(name, _aligned_type_t), \ NULL, nReader+SNAPSHOTI_SPMC_EXTRA_BUFFER); \ @@ -593,38 +594,38 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) } \ for(size_t i = 0; i < nReader + SNAPSHOTI_SPMC_EXTRA_BUFFER; i++) { \ M_CALL_INIT(oplist, snap->data[i].x); \ - } \ + } \ snapshot_mrsw_int_init(snap->core, nReader); \ SNAPSHOTI_SPMC_CONTRACT(snap); \ - } \ + } \ \ - static inline void M_C(name, _clear)(M_C(name, _t) snap) \ - { \ + static inline void M_C(name, _clear)(M_C(name, _t) snap) \ + { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ size_t nReader = snapshot_mrsw_int_size(snap->core); \ for(size_t i = 0; i < nReader + SNAPSHOTI_SPMC_EXTRA_BUFFER; i++) { \ - M_CALL_CLEAR(oplist, snap->data[i].x); \ - } \ + M_CALL_CLEAR(oplist, snap->data[i].x); \ + } \ M_CALL_FREE(oplist, snap->data); \ snapshot_mrsw_int_clear(snap->core); \ - } \ + } \ \ static inline type *M_C(name, _write)(M_C(name, _t) snap) \ - { \ + { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ const unsigned int idx = snapshot_mrsw_int_write(snap->core); \ return &snap->data[idx].x; \ - } \ + } \ \ - static inline type const *M_C(name, _read_start)(M_C(name, _t) snap) \ - { \ + static inline type const *M_C(name, _read_start)(M_C(name, _t) snap) \ + { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ const unsigned int idx = snapshot_mrsw_int_read_start(snap->core); \ return M_CONST_CAST(type, &snap->data[idx].x); \ - } \ + } \ \ static inline void M_C(name, _read_end)(M_C(name, _t) snap, type const *old) \ - { \ + { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ assert (old != NULL); \ const M_C(name, _aligned_type_t) *oldx; \ @@ -634,14 +635,14 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) assert(snap->core->n_reader +SNAPSHOTI_SPMC_EXTRA_BUFFER < UINT_MAX); \ const unsigned int idx = (unsigned int) (oldx - snap->data); \ snapshot_mrsw_int_read_end(snap->core, idx); \ - } \ + } \ \ - static inline type *M_C(name, _get_write_buffer)(M_C(name, _t) snap) \ - { \ + static inline type *M_C(name, _get_write_buffer)(M_C(name, _t) snap) \ + { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ const unsigned int idx = snapshot_mrsw_int_get_write_idx(snap->core); \ return &snap->data[idx].x; \ - } \ + } \ \ //FIXME: Evaluate the needs for the methods _set_, _init_set. @@ -653,10 +654,10 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) // MPMC is built upon SPMC // Defered evaluation -#define SNAPSHOTI_MPMC_DEF_P1(arg) SNAPSHOTI_MPMC_DEF_P2 arg +#define SNAPSHOTI_MPMC_DEF_P1(arg) SNAPSHOTI_MPMC_DEF_P2 arg /* Validate the oplist before going further */ -#define SNAPSHOTI_MPMC_DEF_P2(name, type, oplist) \ +#define SNAPSHOTI_MPMC_DEF_P2(name, type, oplist) \ M_IF_OPLIST(oplist)(SNAPSHOTI_MPMC_DEF_P3, SNAPSHOTI_MPMC_DEF_FAILURE)(name, type, oplist) /* Stop processing with a compilation failure */ @@ -667,36 +668,36 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) \ SNAPSHOTI_SPMC_DEF_P1((M_C(name, _mrsw), type, oplist)) \ \ - typedef struct M_C(name, _s) { \ + typedef struct M_C(name, _s) { \ M_C(name, _mrsw_t) core; \ - } M_C(name, _t)[1]; \ + } M_C(name, _t)[1]; \ \ typedef type M_C(name, _type_t); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ static inline void M_C(name, _init)(M_C(name, _t) snap, size_t nReader, size_t nWriter) \ - { \ + { \ M_C(name, _mrsw_init)(snap->core, nReader + nWriter -1 ); \ unsigned int idx = snap->core->core->currentWrite; \ snap->core->core->currentWrite = GENINT_ERROR; \ snapshot_mrsw_int_write_end(snap->core->core, idx); \ - } \ + } \ \ - static inline void M_C(name, _clear)(M_C(name, _t) snap) \ - { \ + static inline void M_C(name, _clear)(M_C(name, _t) snap) \ + { \ M_C(name, _mrsw_clear)(snap->core); \ - } \ + } \ \ static inline type *M_C(name, _write_start)(M_C(name, _t) snap) \ - { \ + { \ SNAPSHOTI_SPMC_CONTRACT(snap->core); \ const unsigned int idx = snapshot_mrsw_int_write_start(snap->core->core); \ return &snap->core->data[idx].x; \ - } \ + } \ \ static inline void M_C(name, _write_end)(M_C(name, _t) snap, type *old) \ - { \ + { \ SNAPSHOTI_SPMC_CONTRACT(snap->core); \ const M_C(name, _mrsw_aligned_type_t) *oldx; \ oldx = M_CTYPE_FROM_FIELD(M_C(name, _mrsw_aligned_type_t), old, type, x); \ @@ -705,17 +706,17 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) assert(snap->core->core->n_reader + SNAPSHOTI_SPMC_EXTRA_BUFFER < UINT_MAX); \ const unsigned int idx = (unsigned int) (oldx - snap->core->data); \ snapshot_mrsw_int_write_end(snap->core->core, idx); \ - } \ + } \ \ - static inline type const *M_C(name, _read_start)(M_C(name, _t) snap) \ - { \ + static inline type const *M_C(name, _read_start)(M_C(name, _t) snap) \ + { \ return M_C(name, _mrsw_read_start)(snap->core); \ - } \ + } \ \ static inline void M_C(name, _read_end)(M_C(name, _t) snap, type const *old) \ - { \ + { \ M_C(name, _mrsw_read_end)(snap->core, old); \ - } \ + } \ \ //TODO: _set_, _init_set