Transform TAB into SPACE

This commit is contained in:
Patrick Pelissier committed 2020-07-22 20:51:45 +02:00
1 parent f68840ef8c
commit 1b206931df
5 files changed
+416 -415

No files matched your search

+91 -91
View File
@@ -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)
+30 -30
View File
@@ -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
+48 -48
View File
@@ -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 ?
+115 -115
View File
@@ -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); \
\
+132 -131
View File
@@ -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