diff --git a/README.md b/README.md index 23fe35ed..68b0c244 100644 --- a/README.md +++ b/README.md @@ -2227,15 +2227,17 @@ Return true if 'it' references the last element or is no longer valid. Update the iterator 'it' to the next element. -##### struct name\_pair\_s *name\_ref(name\_it\_t it) +##### name\_type\_t *name\_ref(name\_it\_t it) -Return a pointer to the pair composed by the key ('key' field) and its value ('value' field). -'key' element can not be modified. +Return a pointer to the pair composed by the key ('key' field) and its value ('value' field) if it is not a set, +to the key type if it is a set. +'key' element shall not be modified. This pointer remains valid until the dictionary is modified by another method. -##### const struct name\_pair\_s *name\_ref(name\_it\_t it) +##### const name\_type\_t *name\_ref(name\_it\_t it) -Return a constant pointer to the pair composed by the key('key' field) and its value ('value' field). +Return a constant pointer to the pair composed by the key ('key' field) and its value ('value' field) if it is not a set, +to the key type if it is a set. This pointer remains valid until the dictionary is modified by another method. ##### void name\_get\_str(string\_t str, const name\_t dict, bool append) diff --git a/m-algo.h b/m-algo.h index 55272f25..2aa0e9a5 100644 --- a/m-algo.h +++ b/m-algo.h @@ -142,12 +142,12 @@ ALGOI_FIND_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ , /* NO EQUAL */) \ \ - ALGOI_FIND_IF_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t, if, M_C(name, _test_cb_t), M_C(name, _eq_cb_t), M_APPLY, M_APPLY) \ + ALGOI_FIND_IF_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t, if, M_C(name, _test_cb_ct), M_C(name, _eq_cb_ct), M_APPLY, M_APPLY) \ M_IF_FUNCOBJ(ALGOI_FIND_IF_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t, fo, M_C(name, _test_obj_t), M_C(name, _eq_obj_t), M_C(name, _test_obj_call), M_C(name, _eq_obj_call))) \ \ ALGOI_MAP_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t) \ \ - ALGOI_ALL_OF_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t, _, M_C(name, _test_cb_t), M_APPLY) \ + ALGOI_ALL_OF_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t, _, M_C(name, _test_cb_ct), M_APPLY) \ M_IF_FUNCOBJ(ALGOI_ALL_OF_DEF_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t, _fo_, M_C(name, _test_obj_t), M_C(name, _test_obj_call)) ) \ \ /* If there is a IT_REF method, we consider the container as modifiable through iterator */ \ @@ -175,11 +175,11 @@ /* Define the types of the callbacks associated to the algorithms */ #define ALGOI_CALLBACK_P5(name, container_t, cont_oplist, type_t, type_oplist, it_t)\ \ - typedef bool (*M_C(name, _test_cb_t))(type_t const); \ - typedef bool (*M_C(name, _eq_cb_t))(type_t const, type_t const); \ - typedef int (*M_C(name, _cmp_cb_t))(type_t const, type_t const); \ - typedef void (*M_C(name, _transform_cb_t))(type_t *, type_t const); \ - typedef void (*M_C(name, _apply_cb_t))(type_t); \ + typedef bool (*M_C(name, _test_cb_ct))(type_t const); \ + typedef bool (*M_C(name, _eq_cb_ct))(type_t const, type_t const); \ + typedef int (*M_C(name, _cmp_cb_ct))(type_t const, type_t const); \ + typedef void (*M_C(name, _transform_cb_ct))(type_t *, type_t const); \ + typedef void (*M_C(name, _apply_cb_ct))(type_t); \ /* Define the function objects associated to the algorithms */ @@ -752,7 +752,7 @@ \ /* Apply func for all elements of the container */ \ static inline void \ - M_C(name, _for_each) (container_t l, M_C(name, _apply_cb_t) func) \ + M_C(name, _for_each) (container_t l, M_C(name, _apply_cb_ct) func) \ { \ for M_EACH(item, l, cont_oplist) { \ func(*item); \ @@ -766,7 +766,7 @@ static inline void \ M_C(name, _transform) (container_t dst, \ container_t src, \ - M_C(name, _transform_cb_t) func) \ + M_C(name, _transform_cb_ct) func) \ { \ assert(dst != src); \ M_CALL_CLEAN(cont_oplist, dst); \ @@ -784,7 +784,7 @@ M_IF_METHOD(SET, type_oplist)( \ static inline void \ M_C(name, _reduce) (type_t *dest, container_t const l, \ - M_C(name, _transform_cb_t) func) \ + M_C(name, _transform_cb_ct) func) \ { \ bool initDone = false; \ for M_EACH(item, l, cont_oplist) { \ @@ -803,8 +803,8 @@ static inline \ void M_C(name, _map_reduce) (type_t *dest, \ const container_t l, \ - M_C(name, _transform_cb_t) redFunc, \ - M_C(name, _transform_cb_t) mapFunc) \ + M_C(name, _transform_cb_ct) redFunc, \ + M_C(name, _transform_cb_ct) mapFunc) \ { \ bool initDone = false; \ type_t tmp; \ @@ -950,7 +950,7 @@ } \ \ static inline void \ - M_C(name, _remove_if)(container_t l, M_C(name, _test_cb_t) func) \ + M_C(name, _remove_if)(container_t l, M_C(name, _test_cb_ct) func) \ { \ it_t it1; \ M_CALL_IT_FIRST(cont_oplist, it1, l); \ diff --git a/m-array.h b/m-array.h index 2ea78670..95abac4b 100644 --- a/m-array.h +++ b/m-array.h @@ -75,10 +75,10 @@ ,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)) \ + ,TYPE(M_C(name,_ct)) \ + ,SUBTYPE(M_C(name, _subtype_ct)) \ ,TEST_EMPTY(M_C(name,_empty_p)) \ - ,IT_TYPE(M_C(name,_it_t)) \ + ,IT_TYPE(M_C(name,_it_ct)), \ ,IT_FIRST(M_C(name,_it)) \ ,IT_LAST(M_C(name,_it_last)) \ ,IT_END(M_C(name,_it_end)) \ @@ -94,7 +94,7 @@ ,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(IT_REMOVE(M_C(name,_remove)),) \ ,CLEAN(M_C(name,_clean)) \ ,KEY_TYPE(size_t) \ - ,VALUE_TYPE(M_C(name, _type_t)) \ + ,VALUE_TYPE(M_C(name, _subtype_ct)) \ ,KEY_OPLIST(M_DEFAULT_OPLIST) \ ,VALUE_OPLIST(oplist) \ ,M_IF_METHOD(SET, oplist)(SET_KEY(M_C(name, _set_at)) ,) \ @@ -103,7 +103,7 @@ ,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(ERASE_KEY(M_C(name, _erase)),) \ ,GET_SIZE(M_C(name, _size)) \ ,M_IF_METHOD(INIT_SET, oplist)(PUSH(M_C(name,_push_back)) ,) \ - ,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(POP(M_C(name,_pop_back)) ,) \ + ,M_IF_AT_LEAST_METHOD(SET,INIT_MOVE,oplist)(POP(M_C(name,_pop_back)) ,) \ ,M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist)(PUSH_MOVE(M_C(name,_push_move)) ,) \ ,M_IF_AT_LEAST_METHOD(INIT_SET,INIT_MOVE,oplist)(POP_MOVE(M_C(name,_pop_move)) ,) \ ,OPLIST(oplist) \ @@ -144,8 +144,8 @@ - name: prefix to be used - type: type of the elements of the array - oplist: oplist of the type of the elements of the array - - array_t: alias for M_C(name, _t) [ type of the array ] - - it_t: alias for M_C(name, _it_t) [ iterator of the array ] + - array_t: alias for the type of the array + - it_t: alias for the iterator of the array */ #define ARRAYI_DEF_P3(name, type, oplist, array_t, it_t) \ \ @@ -155,16 +155,19 @@ size_t alloc; /* Allocated size for the array base */ \ type *ptr; /* Pointer to the array base */ \ } array_t[1]; \ - typedef struct M_C(name, _s) *M_C(name, _ptr); \ - typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ - \ - typedef type M_C(name, _type_t); \ \ typedef struct M_C(name, _it_s) { \ size_t index; /* Index of the element */ \ const struct M_C(name, _s) *array; /* Reference of the array */ \ } it_t[1]; \ \ + /* Definition of the synonyms of the type */ \ + typedef struct M_C(name, _s) *M_C(name, _ptr); \ + typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ + typedef array_t M_C(name, _ct); \ + typedef it_t M_C(name, _it_ct); \ + typedef type M_C(name, _subtype_ct); \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ static inline void \ diff --git a/m-bitset.h b/m-bitset.h index 5fa91e3c..50937f9e 100644 --- a/m-bitset.h +++ b/m-bitset.h @@ -33,9 +33,9 @@ M_BEGIN_PROTECTED_CODE // Define the basic limb of a bitset -typedef uint64_t bitset_limb; +typedef uint64_t bitset_limb_ct; // And its size in bits -#define BITSET_LIMB_BIT (sizeof(bitset_limb) * CHAR_BIT) +#define BITSET_LIMB_BIT (sizeof(bitset_limb_ct) * CHAR_BIT) // bitset grow policy. n is limb size #define BITSETI_INC_ALLOC_SIZE(n) ((n) < 4 ? 4 : (n) * 2) @@ -63,7 +63,7 @@ typedef uint64_t bitset_limb; typedef struct bitset_s { size_t size; // Size is the number of bits size_t alloc; // Alloc is the number of allocated limbs - bitset_limb *ptr; // Pointer to the allocated limbs + bitset_limb_ct *ptr; // Pointer to the allocated limbs } bitset_t[1]; /* Pointer to a bitset_t */ @@ -121,7 +121,7 @@ bitset_set(bitset_t d, const bitset_t s) if (M_UNLIKELY (d == s)) return; const size_t needAlloc = BITSETI_TO_ALLOC (s->size); if (s->size > BITSETI_FROM_ALLOC (d->alloc)) { - bitset_limb *ptr = M_MEMORY_REALLOC (bitset_limb, d->ptr, needAlloc); + bitset_limb_ct *ptr = M_MEMORY_REALLOC (bitset_limb_ct, d->ptr, needAlloc); if (M_UNLIKELY (ptr == NULL)) { M_MEMORY_FULL(needAlloc); return ; @@ -129,7 +129,7 @@ bitset_set(bitset_t d, const bitset_t s) d->ptr = ptr; d->alloc = needAlloc; } - memcpy (d->ptr, s->ptr, needAlloc * sizeof(bitset_limb) ); + memcpy (d->ptr, s->ptr, needAlloc * sizeof(bitset_limb_ct) ); d->size = s->size; BITSETI_CONTRACT(d); } @@ -173,8 +173,8 @@ bitset_set_at(bitset_t v, size_t i, bool x) const size_t offset = i / BITSET_LIMB_BIT; const size_t index = i % BITSET_LIMB_BIT; // This is a branchless version as x can only be 0 or 1 with only one variable shift. - const bitset_limb mask = ((bitset_limb)1)<ptr[offset] = (v->ptr[offset] & ~mask) | (mask & (0-(bitset_limb)x)); + const bitset_limb_ct mask = ((bitset_limb_ct)1)<ptr[offset] = (v->ptr[offset] & ~mask) | (mask & (0-(bitset_limb_ct)x)); BITSETI_CONTRACT (v); } @@ -186,7 +186,7 @@ bitset_flip_at(bitset_t v, size_t i) assert (i < v->size && v->ptr != NULL); size_t offset = i / BITSET_LIMB_BIT; size_t index = i % BITSET_LIMB_BIT; - v->ptr[offset] ^= ((bitset_limb)1)<ptr[offset] ^= ((bitset_limb_ct)1)<alloc); // Check for integer overflow if (M_UNLIKELY (needAlloc <= v->alloc)) { - M_MEMORY_FULL(needAlloc * sizeof(bitset_limb)); + M_MEMORY_FULL(needAlloc * sizeof(bitset_limb_ct)); return; } // Alloc memory - bitset_limb *ptr = M_MEMORY_REALLOC (bitset_limb, v->ptr, needAlloc); + bitset_limb_ct *ptr = M_MEMORY_REALLOC (bitset_limb_ct, v->ptr, needAlloc); // Check if success if (M_UNLIKELY (ptr == NULL) ) { - M_MEMORY_FULL(needAlloc * sizeof(bitset_limb)); + M_MEMORY_FULL(needAlloc * sizeof(bitset_limb_ct)); return; } // Clear allocated memory @@ -235,9 +235,9 @@ bitset_resize (bitset_t v, size_t size) // Compute the needed allocation. size_t newAlloc = BITSETI_TO_ALLOC (size); if (newAlloc > v->alloc) { - bitset_limb *ptr = M_MEMORY_REALLOC (bitset_limb, v->ptr, newAlloc); + bitset_limb_ct *ptr = M_MEMORY_REALLOC (bitset_limb_ct, v->ptr, newAlloc); if (M_UNLIKELY (ptr == NULL) ) { - M_MEMORY_FULL(newAlloc * sizeof(bitset_limb)); + M_MEMORY_FULL(newAlloc * sizeof(bitset_limb_ct)); return; } v->ptr = ptr; @@ -267,9 +267,9 @@ bitset_reserve (bitset_t v, size_t size) v->size = v->alloc = 0; v->ptr = NULL; } else { - bitset_limb *ptr = M_MEMORY_REALLOC (bitset_limb, v->ptr, newAlloc); + bitset_limb_ct *ptr = M_MEMORY_REALLOC (bitset_limb_ct, v->ptr, newAlloc); if (M_UNLIKELY (ptr == NULL) ) { - M_MEMORY_FULL(newAlloc * sizeof(bitset_limb)); + M_MEMORY_FULL(newAlloc * sizeof(bitset_limb_ct)); return; } v->ptr = ptr; @@ -289,7 +289,7 @@ bitset_get(const bitset_t v, size_t i) assert (v->ptr != NULL && i < v->size); size_t offset = i / BITSET_LIMB_BIT; size_t index = i % BITSET_LIMB_BIT; - return ( v->ptr[offset] & (((bitset_limb)1) << index) ) != 0; + return ( v->ptr[offset] & (((bitset_limb_ct)1) << index) ) != 0; } /* bitset_cget is the exact same service than bitset_get */ @@ -372,18 +372,18 @@ bitset_swap (bitset_t v1, bitset_t v2) BITSETI_CONTRACT (v2); M_SWAP (size_t, v1->size, v2->size); M_SWAP (size_t, v1->alloc, v2->alloc); - M_SWAP (bitset_limb *, v1->ptr, v2->ptr); + M_SWAP (bitset_limb_ct *, v1->ptr, v2->ptr); } /* (INTERNAL) Left shift of the bitset (ptr+size) by 1 bit, * integrating the carry in the lowest position. * Return the new carry. */ -static inline bitset_limb -bitseti_lshift(bitset_limb ptr[], size_t n, bitset_limb carry) +static inline bitset_limb_ct +bitseti_lshift(bitset_limb_ct ptr[], size_t n, bitset_limb_ct carry) { for(size_t i = 0; i < n; i++) { - bitset_limb v = ptr[i]; + bitset_limb_ct v = ptr[i]; ptr[i] = (v << 1) | carry; carry = (v >> (BITSET_LIMB_BIT-1) ); } @@ -394,11 +394,11 @@ bitseti_lshift(bitset_limb ptr[], size_t n, bitset_limb carry) * integrating the carry in the lowest position. * Return the new carry. */ -static inline bitset_limb -bitseti_rshift(bitset_limb ptr[], size_t n, bitset_limb carry) +static inline bitset_limb_ct +bitseti_rshift(bitset_limb_ct ptr[], size_t n, bitset_limb_ct carry) { for(size_t i = n - 1; i < n; i--) { - bitset_limb v = ptr[i]; + bitset_limb_ct v = ptr[i]; v = (v >> 1) | (carry << (BITSET_LIMB_BIT-1) ); carry = v & 1; } @@ -416,9 +416,9 @@ bitset_push_at(bitset_t set, size_t key, bool value) // Then shift it size_t offset = key / BITSET_LIMB_BIT; size_t index = key % BITSET_LIMB_BIT; - bitset_limb v = set->ptr[offset]; - bitset_limb mask = (((bitset_limb)1)<> (BITSET_LIMB_BIT-1) ); + bitset_limb_ct v = set->ptr[offset]; + bitset_limb_ct mask = (((bitset_limb_ct)1)<> (BITSET_LIMB_BIT-1) ); v = (v & mask) | ((unsigned int) value << index) | ((v & ~mask) << 1); set->ptr[offset] = v; size_t size = (set->size + BITSET_LIMB_BIT - 1) / BITSET_LIMB_BIT; @@ -443,10 +443,10 @@ bitset_pop_at(bool *dest, bitset_t set, size_t key) size_t offset = key / BITSET_LIMB_BIT; size_t index = key % BITSET_LIMB_BIT; size_t size = (set->size + BITSET_LIMB_BIT - 1) / BITSET_LIMB_BIT; - bitset_limb v, mask, carry; + bitset_limb_ct v, mask, carry; carry = bitseti_rshift(&set->ptr[offset+1], size - offset - 1, false); v = set->ptr[offset]; - mask = (((bitset_limb)1)<>1) & ~mask) | (carry << (BITSET_LIMB_BIT-1)) ; set->ptr[offset] = v; // Decrease size @@ -471,7 +471,7 @@ bitset_equal_p (const bitset_t set1, const bitset_t set2) /* Compare the last limb if needed */ const size_t index = set1->size % BITSET_LIMB_BIT; if (index > 0) { - const bitset_limb mask = (((bitset_limb)1) << index) - 1; + const bitset_limb_ct mask = (((bitset_limb_ct)1) << index) - 1; if ((set1->ptr[limbSize] & mask) != (set2->ptr[limbSize] & mask)) return false; } @@ -644,7 +644,7 @@ bitset_and(bitset_t dest, const bitset_t src) for(size_t i = 0 ; i < n; i++) dest->ptr[i] &= src->ptr[i]; if (m) { - bitset_limb mask = (((bitset_limb)1) << m) - 1; + bitset_limb_ct mask = (((bitset_limb_ct)1) << m) - 1; dest->ptr[n] = (dest->ptr[n] & src->ptr[n]) & mask; } dest->size = s; @@ -664,7 +664,7 @@ bitset_or(bitset_t dest, const bitset_t src) for(size_t i = 0 ; i < n; i++) dest->ptr[i] |= src->ptr[i]; if (m) { - bitset_limb mask = (((bitset_limb)1) << m) - 1; + bitset_limb_ct mask = (((bitset_limb_ct)1) << m) - 1; dest->ptr[n] = (dest->ptr[n] | src->ptr[n]) & mask; } dest->size = s; @@ -684,7 +684,7 @@ bitset_xor(bitset_t dest, const bitset_t src) for(size_t i = 0 ; i < n; i++) dest->ptr[i] ^= src->ptr[i]; if (m) { - bitset_limb mask = (((bitset_limb)1) << m) - 1; + bitset_limb_ct mask = (((bitset_limb_ct)1) << m) - 1; dest->ptr[n] = (dest->ptr[n] ^ src->ptr[n]) & mask; } dest->size = s; @@ -702,7 +702,7 @@ bitset_not(bitset_t dest) for(size_t i = 0 ; i < n; i++) dest->ptr[i] = ~ (dest->ptr[i]); if (m) { - bitset_limb mask = (((bitset_limb)1) << m) - 1; + bitset_limb_ct mask = (((bitset_limb_ct)1) << m) - 1; dest->ptr[n] = (~ dest->ptr[n]) & mask; } dest->size = s; @@ -721,7 +721,7 @@ bitset_hash(const bitset_t set) for(size_t i = 0 ; i < n; i++) M_HASH_UP(hash, set->ptr[i]); if (m) { - bitset_limb mask = (((bitset_limb)1) << m) - 1; + bitset_limb_ct mask = (((bitset_limb_ct)1) << m) - 1; M_HASH_UP(hash, (set->ptr[n] & mask)); } return M_HASH_FINAL (hash); @@ -736,9 +736,9 @@ bitset_clz(const bitset_t set) assert (s > 0); size_t n = (s -1) / BITSET_LIMB_BIT; size_t m = s % BITSET_LIMB_BIT; - bitset_limb limb = set->ptr[n]; + bitset_limb_ct limb = set->ptr[n]; if (m) { - bitset_limb mask = (((bitset_limb)1) << m) - 1; + bitset_limb_ct mask = (((bitset_limb_ct)1) << m) - 1; limb &= mask; } else { m = BITSET_LIMB_BIT; diff --git a/m-bptree.h b/m-bptree.h index 2f8dd310..77099bd4 100644 --- a/m-bptree.h +++ b/m-bptree.h @@ -37,8 +37,8 @@ #define BPTREE_DEF2(name, N, key_type, ...) \ M_BEGIN_PROTECTED_CODE \ BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, N, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 1, 0, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t) ), \ - (name, N, key_type, __VA_ARGS__, 1, 0, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t)))) \ + ((name, N, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 1, 0, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ), \ + (name, N, key_type, __VA_ARGS__, 1, 0, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ))) \ M_END_PROTECTED_CODE @@ -48,8 +48,8 @@ #define BPTREE_DEF(name, N, ...) \ M_BEGIN_PROTECTED_CODE \ BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, N, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 0, 0, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t) ), \ - (name, N, __VA_ARGS__, __VA_ARGS__, 0, 0, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t) ))) \ + ((name, N, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 0, 0, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ), \ + (name, N, __VA_ARGS__, __VA_ARGS__, 0, 0, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ))) \ M_END_PROTECTED_CODE @@ -64,8 +64,8 @@ #define BPTREE_MULTI_DEF2(name, N, key_type, ...) \ M_BEGIN_PROTECTED_CODE \ BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, N, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 1, 1, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t) ), \ - (name, N, key_type, __VA_ARGS__, 1, 1, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t)))) \ + ((name, N, key_type, M_GLOBAL_OPLIST_OR_DEF(key_type)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 1, 1, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ), \ + (name, N, key_type, __VA_ARGS__, 1, 1, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ))) \ M_END_PROTECTED_CODE @@ -76,8 +76,8 @@ #define BPTREE_MULTI_DEF(name, N, ...) \ M_BEGIN_PROTECTED_CODE \ BPTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, N, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 0, 1, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t) ), \ - (name, N, __VA_ARGS__, __VA_ARGS__, 0, 1, M_C(name, _t), M_C(name, _node_t), M_C(name, _pit_t), M_C(name, _it_t) ))) \ + ((name, N, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), 0, 1, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ), \ + (name, N, __VA_ARGS__, __VA_ARGS__, 0, 1, M_C(name, _t), M_C(name, _node_ct), M_C(name, _pit_ct), M_C(name, _it_t), M_C(name, _type_t) ))) \ M_BEGIN_PROTECTED_CODE @@ -125,9 +125,9 @@ 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)), \ - IT_TYPE(M_C(name, _it_t)), \ + TYPE(M_C(name,_ct)), \ + SUBTYPE(M_C(name, _subtype_ct)), \ + IT_TYPE(M_C(name, _it_ct)), \ IT_FIRST(M_C(name,_it)), \ IT_SET(M_C(name,_it_set)), \ IT_END(M_C(name,_it_end)), \ @@ -174,10 +174,10 @@ 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)), \ + TYPE(M_C(name,_ct)), \ + SUBTYPE(M_C(name, _subtype_ct)), \ TEST_EMPTY(M_C(name,_empty_p)), \ - IT_TYPE(M_C(name, _it_t)), \ + IT_TYPE(M_C(name, _it_ct)), \ IT_FIRST(M_C(name,_it)), \ IT_SET(M_C(name,_it_set)), \ IT_END(M_C(name,_it_end)), \ @@ -188,8 +188,8 @@ CLEAN(M_C(name,_clean)), \ GET_MIN(M_C(name,_min)), \ GET_MAX(M_C(name,_max)), \ - KEY_TYPE(M_C(name, _key_type_t)), \ - VALUE_TYPE(M_C(name, _value_type_t)), \ + KEY_TYPE(M_C(name, _key_ct)), \ + VALUE_TYPE(M_C(name, _value_ct)), \ SET_KEY(M_C(name, _set_at)), \ GET_KEY(M_C(name, _get)), \ ERASE_KEY(M_C(name, _erase)), \ @@ -210,7 +210,7 @@ -/* Internal contract of a B+TREE node 'node' or root 'root' */ +/* Internal contract of a B+TREE of size 'N' for a node 'node' or root 'root' */ #ifdef NDEBUG # define BPTREEI_NODE_CONTRACT(N, isMulti, key_oplist, node, root) do { } while (0) #else @@ -238,6 +238,7 @@ } while (0) #endif +/* Contract for a B+TREE of size N named 'b' */ #define BPTREEI_CONTRACT(N, isMulti, key_oplist, b) do { \ assert (N >= 3); /* TBC: 2 instead ? */ \ BPTREEI_NODE_CONTRACT(N, isMulti, key_oplist, (b)->root, (b)->root); \ @@ -253,15 +254,15 @@ #define BPTREEI_DEF_P1(arg) BPTREEI_DEF_P2 arg /* Validate the key oplist before going further */ -#define BPTREEI_DEF_P2(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) \ - M_IF_OPLIST(key_oplist)(BPTREEI_DEF_P3, BPTREEI_DEF_FAILURE)(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) +#define BPTREEI_DEF_P2(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) \ + M_IF_OPLIST(key_oplist)(BPTREEI_DEF_P3, BPTREEI_DEF_FAILURE)(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) /* Validate the value oplist before going further */ -#define BPTREEI_DEF_P3(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) \ - M_IF_OPLIST(value_oplist)(BPTREEI_DEF_P4, BPTREEI_DEF_FAILURE)(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) +#define BPTREEI_DEF_P3(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) \ + M_IF_OPLIST(value_oplist)(BPTREEI_DEF_P4, BPTREEI_DEF_FAILURE)(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) /* Stop processing with a compilation failure */ -#define BPTREEI_DEF_FAILURE(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) \ +#define BPTREEI_DEF_FAILURE(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(BPTREE*_DEF): one of the given argument is not a valid oplist: " M_AS_STR(key_oplist) " / " M_AS_STR(value_oplist)) /* Internal b+tree definition @@ -273,12 +274,13 @@ - value_oplist: oplist of the value type of the elements of the container - isMap: true if map, false if set - isMulti: true if multimap/multiset, false otherwise - - tree_t: alias for M_C(name, _t) [ type of the container ] - - it_t: alias for M_C(name, _it_t) [ iterator of the container ] - - node_t: alias for M_C(name, _node_t) [ node ] - - pit_t: alias for M_C(name, _pit_t) [parent iterator] + - tree_t: alias for the type of the container + - it_t: alias for the iterator of the container + - node_t: alias for internal node + - pit_t: alias for internal parent iterator + - subtype_t: alias for the type referenced by the iterator */ -#define BPTREEI_DEF_P4(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) \ +#define BPTREEI_DEF_P4(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) \ \ M_IF(isMap)( \ /* Type returned by the iterator. Due to having key and value \ @@ -287,12 +289,10 @@ typedef struct M_C(name, _pair_s) { \ key_t *key_ptr; \ value_t *value_ptr; \ - } M_C(name, _type_t); \ + } subtype_t; \ , \ - typedef key_t M_C(name, _type_t); \ - ) \ - typedef key_t M_C(name, _key_type_t); \ - typedef value_t M_C(name, _value_type_t); \ + typedef key_t subtype_t; \ + ) \ \ /* Node of a B+TREE */ \ typedef struct M_C(name, _node_s) { \ @@ -313,6 +313,12 @@ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ + /* Definition of the alias used by the oplists */ \ + typedef subtype_t M_C(name, _subtype_ct); \ + typedef key_t M_C(name, _key_ct); \ + typedef value_t M_C(name, _value_ct); \ + typedef tree_t M_C(name, _ct); \ + \ /* Parent Iterator */ \ typedef struct M_C(name, _parent_it_s) { \ int num; \ @@ -325,6 +331,7 @@ node_t node; \ int idx; \ } it_t[1]; \ + typedef it_t M_C(name, _it_ct); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, key_t, key_oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 2, value_t, value_oplist) \ @@ -961,7 +968,7 @@ } \ } \ \ - static inline M_C(name, _type_t) * \ + static inline subtype_t * \ M_C(name, _ref)(it_t it) \ { \ assert (it != NULL && it->node != NULL); \ @@ -975,10 +982,10 @@ ); \ } \ \ - static inline M_C(name, _type_t) const * \ + static inline subtype_t const * \ M_C(name, _cref)(it_t it) \ { \ - return M_CONST_CAST(M_C(name, _type_t), M_C(name, _ref)(it)); \ + return M_CONST_CAST(subtype_t, M_C(name, _ref)(it)); \ } \ \ \ @@ -1099,12 +1106,12 @@ BPTREEI_CONTRACT(N, isMulti, key_oplist, tree2); \ } \ \ - BPTREEI_FUNC_ADDITIONAL_DEF2(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) + BPTREEI_FUNC_ADDITIONAL_DEF2(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) /* Define additional functions. Do not used any fields but the already defined methods */ -#define BPTREEI_FUNC_ADDITIONAL_DEF2(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t) \ +#define BPTREEI_FUNC_ADDITIONAL_DEF2(name, N, key_t, key_oplist, value_t, value_oplist, isMap, isMulti, tree_t, node_t, pit_t, it_t, subtype_t) \ \ M_IF_METHOD_BOTH(EQUAL, key_oplist, value_oplist)( \ static inline bool M_C(name,_equal_p)(const tree_t t1, const tree_t t2) { \ @@ -1123,8 +1130,8 @@ M_C(name, _it)(it2, t2); \ while (!M_C(name, _end_p)(it1) \ && !M_C(name, _end_p)(it2)) { \ - const M_C(name, _type_t) *ref1 = M_C(name, _cref)(it1); \ - const M_C(name, _type_t) *ref2 = M_C(name, _cref)(it2); \ + const subtype_t *ref1 = M_C(name, _cref)(it1); \ + const subtype_t *ref2 = M_C(name, _cref)(it2); \ M_IF(isMap)( \ if (!M_CALL_EQUAL(key_oplist, *ref1->key_ptr, *ref2->key_ptr)) \ return false; \ @@ -1151,7 +1158,7 @@ it_t it1; \ M_C(name, _it)(it1, t1); \ while (!M_C(name, _end_p)(it1)) { \ - const M_C(name, _type_t) *ref1 = M_C(name, _cref)(it1); \ + subtype_t const *ref1 = M_C(name, _cref)(it1); \ M_IF(isMap)( \ M_HASH_UP(hash, M_CALL_HASH(key_oplist, *ref1->key_ptr)); \ M_HASH_UP(hash, M_CALL_HASH(value_oplist, *ref1->value_ptr)); \ @@ -1179,7 +1186,7 @@ if (commaToPrint) \ string_push_back (str, M_GET_SEPARATOR key_oplist); \ commaToPrint = true; \ - const M_C(name, _type_t) *ref1 = M_C(name, _cref)(it); \ + subtype_t const *ref1 = M_C(name, _cref)(it); \ M_IF(isMap)( \ M_CALL_GET_STR(key_oplist, str, *ref1->key_ptr, true); \ string_cat_str(str, ":"); \ @@ -1207,7 +1214,7 @@ if (commaToPrint) \ fputc (M_GET_SEPARATOR key_oplist, file); \ commaToPrint = true; \ - const M_C(name, _type_t) *ref1 = M_C(name, _cref)(it); \ + subtype_t const *ref1 = M_C(name, _cref)(it); \ M_IF(isMap)( \ M_CALL_OUT_STR(key_oplist, file, *ref1->key_ptr); \ fputc (':', file); \ @@ -1308,7 +1315,7 @@ assert (f != NULL && f->m_interface != NULL); \ m_serial_return_code_t ret; \ m_serial_local_t local; \ - const M_C(name, _type_t) *item; \ + subtype_t const *item; \ bool first_done = false; \ it_t it; \ /* Format is different between associative container \ diff --git a/m-buffer.h b/m-buffer.h index 11f65693..3b001d01 100644 --- a/m-buffer.h +++ b/m-buffer.h @@ -120,6 +120,14 @@ typedef enum { #define BUFFERI_DEF_FAILURE(name, type, m_size, policy, oplist, buffer_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(BUFFER_DEF): the given argument is not a valid oplist: " M_AS_STR(oplist)) +/* Define the buffer type using mutex lock and its functions. + - name: main prefix of the container + - type: type of an element of the buffer + - m_size: constant to 0 if variable runtime size, or else the fixed size of the buffer + - policy: the policy of the buffer + - oplist: the oplist of the type of an element of the buffer + - buffer_t: name of the buffer + */ #define BUFFERI_DEF_P3(name, type, m_size, policy, oplist, buffer_t) \ \ typedef struct M_C(name, _s) { \ @@ -141,7 +149,8 @@ typedef enum { typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ typedef union { M_C(name, _srcptr) cptr; M_C(name, _ptr) ptr; } M_C(name, _uptr); \ - typedef type M_C(name, _type_t); \ + typedef type M_C(name, _subtype_ct); \ + typedef buffer_t M_C(name, _ct); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ @@ -624,6 +633,13 @@ M_C(name, _init)(buffer_t v, size_t size) \ #endif +/* Define the buffer type MPMC using atomics and its functions. + - name: main prefix of the container + - type: type of an element of the buffer + - policy: the policy of the buffer + - oplist: the oplist of the type of an element of the buffer + - buffer_t: name of the buffer + */ #define QUEUEI_MPMC_DEF_P3(name, type, policy, oplist, buffer_t) \ \ /* The sequence number of an element will be equal to either \ @@ -651,6 +667,9 @@ M_C(name, _init)(buffer_t v, size_t size) \ unsigned int size; \ } buffer_t[1]; \ \ + typedef type M_C(name, _subtype_ct); \ + typedef buffer_t M_C(name, _ct); \ + \ static inline bool \ M_C(name, _push)(buffer_t table, type const x) \ { \ @@ -834,6 +853,13 @@ M_C(name, _init)(buffer_t v, size_t size) \ } while (0) #endif +/* Define the buffer type SPSC using atomics and its functions. + - name: main prefix of the container + - type: type of an element of the buffer + - policy: the policy of the buffer + - oplist: the oplist of the type of an element of the buffer + - buffer_t: name of the buffer + */ #define QUEUEI_SPSC_DEF_P3(name, type, policy, oplist, buffer_t) \ \ typedef struct M_C(name, _el_s) { \ @@ -848,6 +874,9 @@ M_C(name, _init)(buffer_t v, size_t size) \ atomic_uint prodIdx; /* Can only increase until overflow */ \ } buffer_t[1]; \ \ + typedef type M_C(name, _subtype_ct); \ + typedef buffer_t M_C(name, _ct); \ + \ static inline bool \ M_C(name, _push)(buffer_t table, type const x) \ { \ @@ -1086,14 +1115,14 @@ M_C(name, _init)(buffer_t v, size_t size) \ #define BUFFERI_OPLIST_FAILURE(name, oplist) \ ((M_LIB_ERROR(ARGUMENT_OF_BUFFER_OPLIST_IS_NOT_AN_OPLIST, name, oplist))) -/* OPLIST defininition of a buffer */ +/* OPLIST definition of a buffer */ #define BUFFERI_OPLIST_P3(name, oplist) \ (INIT(M_C(name, _int_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)) \ + ,TYPE(M_C(name,_ct)) \ + ,SUBTYPE(M_C(name, _subtype_ct)) \ ,CLEAN(M_C(name,_clean)) \ ,PUSH(M_C(name,_push)) \ ,POP(M_C(name,_pop)) \ diff --git a/m-c-mempool.h b/m-c-mempool.h index c6a9fdad..c74f848f 100644 --- a/m-c-mempool.h +++ b/m-c-mempool.h @@ -677,7 +677,7 @@ m_gc_sleep(m_gc_t gc_mem, m_gc_tid_t id) /***********************************************************************/ /* */ -/* VLA MEMPOOL */ +/* Variable Length Array MEMPOOL */ /* */ /***********************************************************************/ diff --git a/m-concurrent.h b/m-concurrent.h index cf5f37e3..e546c85f 100644 --- a/m-concurrent.h +++ b/m-concurrent.h @@ -87,8 +87,8 @@ ,M_IF_METHOD(INIT_MOVE, oplist)(INIT_MOVE(M_C(name, _init_move)),) \ ,M_IF_METHOD(MOVE, oplist)(MOVE(M_C(name, _move)),) \ ,M_IF_METHOD(SWAP,oplist)(SWAP(M_C(name, _swap)),) \ - ,TYPE(M_C(name,_t)) \ - ,SUBTYPE(M_C(name, _type_t)) \ + ,TYPE(M_C(name,_ct)) \ + ,SUBTYPE(M_C(name, _subtype_ct)) \ ,OPLIST(oplist) \ ,M_IF_METHOD(TEST_EMPTY, oplist)(TEST_EMPTY(M_C(name,_empty_p)),) \ ,M_IF_METHOD(GET_SIZE, oplist)(GET_SIZE(M_C(name,_size)),) \ @@ -132,7 +132,7 @@ M_IF_OPLIST(oplist)(CONCURRENTI_DEF_P3, CONCURRENTI_DEF_FAILURE)(name, type, oplist, concurrent_t) /* Stop processing with a compilation failure */ -#define CONCURRENTI_DEF_FAILURE(name, type, oplist, concurrent_t) \ +#define CONCURRENTI_DEF_FAILURE(name, type, oplist, concurrent_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(CONCURRENT_DEF): the given argument is not a valid oplist: " M_AS_STR(oplist)) /* Internal concurrent definition @@ -153,7 +153,9 @@ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ - typedef type M_C(name, _type_t); \ + /* Internal types for oplist */ \ + typedef concurrent_t M_C(name, _ct); \ + typedef type M_C(name, _subtype_ct); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ diff --git a/m-deque.h b/m-deque.h index 08c29ca4..f6d05fa1 100644 --- a/m-deque.h +++ b/m-deque.h @@ -32,8 +32,8 @@ #define DEQUE_DEF(name, ...) \ M_BEGIN_PROTECTED_CODE \ DEQUEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), M_C(name,_t), M_C(name,_it_t), M_C(name, _node_t) ), \ - (name, __VA_ARGS__, M_C(name,_t), M_C(name,_it_t), M_C(name, _node_t)))) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), M_C(name,_t), M_C(name,_it_t), M_C(name, _node_ct) ), \ + (name, __VA_ARGS__, M_C(name,_t), M_C(name,_it_t), M_C(name, _node_ct)))) \ M_END_PROTECTED_CODE @@ -83,7 +83,7 @@ - oplist: oplist of the type of the elements of the container - deque_t: alias for M_C(name, _t) [ type of the container ] - it_t: alias for M_C(name, _it_t) [ iterator of the container ] - - node_t: alias for M_C(name, _node_t) [ node ] + - node_t: alias for node_t [ node ] */ #define DEQUEI_DEF_P3(name, type, oplist, deque_t, it_t, node_t) \ \ @@ -139,25 +139,28 @@ const struct M_C(name, _s) *deque; \ } it_t[1]; \ \ - typedef type M_C(name, _type_t); \ + /* Define internal types for oplist */ \ + typedef deque_t M_C(name, _ct); \ + typedef type M_C(name, _subtype_ct); \ + typedef it_t M_C(name, _it_ct); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ - static inline M_C(name, _node_t)* \ + static inline node_t* \ M_C(name, _int_new_node)(deque_t d) \ { \ size_t def = d->default_size; \ /* Test for overflow of the size computation */ \ - if (M_UNLIKELY (def > SIZE_MAX / sizeof (type) - sizeof(M_C(name, _node_t)))) { \ - M_MEMORY_FULL(sizeof(M_C(name, _node_t))+def * sizeof(type)); \ + if (M_UNLIKELY (def > SIZE_MAX / sizeof (type) - sizeof(node_t))) { \ + M_MEMORY_FULL(sizeof(node_t)+def * sizeof(type)); \ return NULL; \ } \ /* Alloc a new node */ \ - M_C(name, _node_t)*n = (M_C(name, _node_t)*) (void*) \ + node_t*n = (node_t*) (void*) \ M_CALL_REALLOC(oplist, char, NULL, \ - sizeof(M_C(name, _node_t)) + def * sizeof(type) ); \ + sizeof(node_t) + def * sizeof(type) ); \ if (n==NULL) { \ - M_MEMORY_FULL(sizeof(M_C(name, _node_t))+def * sizeof(type)); \ + M_MEMORY_FULL(sizeof(node_t)+def * sizeof(type)); \ return NULL; \ } \ /* Initialize the node */ \ @@ -177,7 +180,7 @@ M_C(name, _node_list_init)(d->list); \ d->default_size = DEQUEUI_DEFAULT_SIZE; \ d->count = 0; \ - M_C(name, _node_t) *n = M_C(name, _int_new_node)(d); \ + node_t *n = M_C(name, _int_new_node)(d); \ if (n == NULL) return; \ M_C(name, _node_list_push_back)(d->list, n); \ d->front->node = n; \ @@ -191,8 +194,8 @@ M_C(name, _clean)(deque_t d) \ { \ DEQUEI_CONTRACT(d); \ - M_C(name, _node_t) *min_node = NULL; \ - for(M_C(name, _node_t) *n = d->front->node; \ + node_t *min_node = NULL; \ + for(node_t *n = d->front->node; \ n != NULL ; \ n = (n == d->back->node) ? NULL : \ M_C(name, _node_list_next_obj)(d->list, n) ){ \ @@ -229,7 +232,7 @@ M_C(name, _push_back_raw)(deque_t d) \ { \ DEQUEI_CONTRACT(d); \ - M_C(name, _node_t) *n = d->back->node; \ + node_t *n = d->back->node; \ size_t index = d->back->index; \ if (M_UNLIKELY (n->size <= index)) { \ /* try to get an already allocated node */ \ @@ -286,7 +289,7 @@ M_C(name, _push_front_raw)(deque_t d) \ { \ DEQUEI_CONTRACT(d); \ - M_C(name, _node_t) *n = d->front->node; \ + node_t *n = d->front->node; \ size_t index = d->front->index; \ index --; \ /* If overflow */ \ @@ -343,14 +346,14 @@ { \ DEQUEI_CONTRACT(d); \ assert(d->count > 0); \ - M_C(name, _node_t) *n = d->back->node; \ + node_t *n = d->back->node; \ size_t index = d->back->index; \ index --; \ if (M_UNLIKELY (n->size <= index)) { \ /* If there is a next node, \ pop the back node and push it back to the front. This \ reduce the used memory if the deque is used as a FIFO queue.*/ \ - M_C(name, _node_t) *next = M_C(name, _node_list_next_obj)(d->list, n); \ + node_t *next = M_C(name, _node_list_next_obj)(d->list, n); \ if (next != NULL) { \ next = M_C(name, _node_list_pop_back)(d->list); \ assert (next != n); \ @@ -389,13 +392,13 @@ { \ DEQUEI_CONTRACT(d); \ assert(d->count > 0); \ - M_C(name, _node_t) *n = d->front->node; \ + node_t *n = d->front->node; \ size_t index = d->front->index; \ if (M_UNLIKELY (n->size <= index)) { \ /* If there is a previous node, \ pop the front node and push it back to the back. This \ reduce the used memory if the deque is used as a FIFO queue.*/ \ - M_C(name,_node_t) *prev = M_C(name, _node_list_previous_obj)(d->list, n); \ + node_t *prev = M_C(name, _node_list_previous_obj)(d->list, n); \ if (prev != NULL) { \ prev = M_C(name, _node_list_pop_front)(d->list); \ assert (prev != n); \ @@ -435,7 +438,7 @@ DEQUEI_CONTRACT(d); \ assert (d->count > 0); \ size_t i = d->back->index; \ - M_C(name, _node_t) *n = d->back->node; \ + node_t *n = d->back->node; \ if (M_UNLIKELY (i == 0)) { \ n = M_C(name, _node_list_previous_obj)(d->list, n); \ assert (n != NULL); \ @@ -450,7 +453,7 @@ DEQUEI_CONTRACT(d); \ assert (d->count > 0); \ size_t i = d->front->index; \ - M_C(name, _node_t) *n = d->front->node; \ + node_t *n = d->front->node; \ if (M_UNLIKELY (n->size <= i)) { \ n = M_C(name, _node_list_next_obj)(d->list, n); \ assert (n != NULL); \ @@ -471,7 +474,7 @@ { \ DEQUEI_CONTRACT(v); \ size_t s = 0; \ - for(M_C(name, _node_t) *n = M_C(name, _node_list_back)(v->list); \ + for(node_t *n = M_C(name, _node_list_back)(v->list); \ n != NULL ; \ n = (n == v->back->node) ? NULL : \ M_C(name, _node_list_previous_obj)(v->list, n) ){ \ @@ -485,7 +488,7 @@ { \ DEQUEI_CONTRACT(v); \ size_t s = 0; \ - for(M_C(name, _node_t) *n = M_C(name, _node_list_front)(v->list); \ + for(node_t *n = M_C(name, _node_list_front)(v->list); \ n != NULL ; \ n = (n == v->front->node) ? NULL : \ M_C(name, _node_list_next_obj)(v->list, n) ){ \ @@ -566,7 +569,7 @@ M_C(name, _next)(it_t it) \ { \ assert (it != NULL); \ - M_C(name, _node_t) *n = it->node; \ + node_t *n = it->node; \ it->index ++; \ if (M_UNLIKELY (it->index >= n->size)) { \ n = M_C(name, _node_list_next_obj)(it->deque->list, n); \ @@ -585,7 +588,7 @@ M_C(name, _previous)(it_t it) \ { \ assert (it != NULL); \ - M_C(name, _node_t) *n = it->node; \ + node_t *n = it->node; \ it->index --; \ if (M_UNLIKELY (it->index >= n->size)) { \ n = M_C(name, _node_list_previous_obj)(it->deque->list, n); \ @@ -644,7 +647,7 @@ M_C(name, _node_list_init)(d->list); \ d->default_size = DEQUEUI_DEFAULT_SIZE + src->count; \ d->count = src->count; \ - M_C(name, _node_t) *n = M_C(name, _int_new_node)(d); \ + node_t *n = M_C(name, _int_new_node)(d); \ if (n == NULL) return; \ d->default_size /= 2; \ M_C(name, _node_list_push_back)(d->list, n); \ @@ -723,7 +726,7 @@ const size_t index0 = d->front->index; \ size_t count = 0; \ /* This loop is in log(N) since the size increase exponentially.*/ \ - for(M_C(name, _node_t) *n = d->front->node; \ + for(node_t *n = d->front->node; \ n != NULL ; \ n = (n == d->back->node) ? NULL : \ M_C(name, _node_list_next_obj)(d->list, n) ){ \ @@ -977,10 +980,10 @@ ,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)) \ + ,TYPE(M_C(name,_ct)) \ + ,SUBTYPE(M_C(name, _subtype_ct)) \ ,TEST_EMPTY(M_C(name,_empty_p)) \ - ,IT_TYPE(M_C(name,_it_t)) \ + ,IT_TYPE(M_C(name,_it_ct)) \ ,IT_FIRST(M_C(name,_it)) \ ,IT_LAST(M_C(name,_it_last)) \ ,IT_END(M_C(name,_it_end)) \ diff --git a/m-dict.h b/m-dict.h index d59711ac..05b0a99b 100644 --- a/m-dict.h +++ b/m-dict.h @@ -252,6 +252,7 @@ /* NOTE: \ if isSet is true, all methods of value_oplist are NOP methods */ \ \ + /* Define chained dict type */ \ typedef struct M_C(name, _s) { \ size_t used, lower_limit, upper_limit; \ M_C(name, _array_list_pair_t) table; \ @@ -260,19 +261,26 @@ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ - M_IF(isSet)( \ - typedef key_type M_C(name, _type_t); \ - , \ - typedef struct M_C(name, _pair_s) M_C(name, _type_t); \ - ) \ - typedef key_type M_C(name, _key_type_t); \ - typedef value_type M_C(name, _value_type_t); \ - \ + /* Define iterator type */ \ typedef struct M_C(name, _it_s) { \ M_C(name, _array_list_pair_it_t) array_it; \ M_C(name, _list_pair_it_t) list_it; \ } dict_it_t[1]; \ \ + /* Define type returned by the _ref method of an iterator */ \ + M_IF(isSet)( \ + typedef key_type M_C(name, _type_t); \ + , \ + typedef struct M_C(name, _pair_s) M_C(name, _type_t); \ + ) \ + \ + /* Define internal types for oplist */ \ + typedef dict_t M_C(name, _ct); \ + typedef M_C(name, _type_t) M_C(name, _subtype_ct); \ + typedef key_type M_C(name, _key_ct); \ + typedef value_type M_C(name, _value_ct); \ + typedef dict_it_t M_C(name, _it_ct); \ + \ static inline void \ M_C(name, _init)(dict_t map) \ { \ @@ -994,10 +1002,10 @@ MOVE(M_C(name, _move)), \ SWAP(M_C(name, _swap)), \ CLEAN(M_C(name, _clean)), \ - TYPE(M_C(name, _t)), \ - SUBTYPE(M_C(name, _type_t)), \ + TYPE(M_C(name, _ct)), \ + SUBTYPE(M_C(name, _subtype_ct)), \ TEST_EMPTY(M_C(name,_empty_p)), \ - IT_TYPE(M_C(name, _it_t)), \ + IT_TYPE(M_C(name, _it_ct)), \ IT_FIRST(M_C(name,_it)), \ IT_SET(M_C(name, _it_set)), \ IT_END(M_C(name,_it_end)), \ @@ -1005,8 +1013,8 @@ IT_LAST_P(M_C(name,_last_p)), \ IT_NEXT(M_C(name,_next)), \ IT_CREF(M_C(name,_cref)) \ - ,KEY_TYPE(M_C(name, _key_type_t)) \ - ,VALUE_TYPE(M_C(name, _value_type_t)) \ + ,KEY_TYPE(M_C(name, _key_ct)) \ + ,VALUE_TYPE(M_C(name, _value_ct)) \ ,SET_KEY(M_C(name, _set_at)) \ ,GET_KEY(M_C(name, _get)) \ ,GET_SET_KEY(M_C(name, _get_at)) \ @@ -1049,19 +1057,19 @@ MOVE(M_C(name, _move)), \ SWAP(M_C(name, _swap)), \ CLEAN(M_C(name, _clean)), \ - TYPE(M_C(name, _t)), \ - SUBTYPE(M_C(name, _type_t)), \ + TYPE(M_C(name, _ct)), \ + SUBTYPE(M_C(name, _subtype_ct)), \ TEST_EMPTY(M_C(name,_empty_p)), \ PUSH(M_C(name,_push)), \ - KEY_TYPE(M_C(name, _key_type_t)), \ - VALUE_TYPE(M_C(name, _key_type_t)), \ + KEY_TYPE(M_C(name, _key_ct)), \ + VALUE_TYPE(M_C(name, _key_ct)), \ GET_KEY(M_C(name, _get)), \ GET_SET_KEY(M_C(name, _get_at)), \ ERASE_KEY(M_C(name, _erase)), \ KEY_OPLIST(oplist), \ VALUE_OPLIST(oplist), \ GET_SIZE(M_C(name, _size)), \ - IT_TYPE(M_C(name, _it_t)), \ + IT_TYPE(M_C(name, _it_ct)), \ IT_FIRST(M_C(name,_it)), \ IT_SET(M_C(name, _it_set)), \ IT_END(M_C(name,_it_end)), \ @@ -1111,9 +1119,9 @@ /* Open Addressing implementation */ /****************************************************************************************/ -typedef enum { +enum dicti_oa_element_e { DICTI_OA_EMPTY = 0, DICTI_OA_DELETED = 1 -} dicti_oa_element_t; +}; /* Performing Quadratic probing Replace it by '1' to perform linear probing */ @@ -1182,12 +1190,12 @@ typedef enum { M_IF(isSet)( , value_type value;) \ } M_C(name, _pair_t); \ \ + /* Define type returned by the _ref method of an iterator */ \ M_IF(isSet)( \ - typedef key_type M_C(name, _type_t); \ + typedef key_type M_C(name, _type_t); \ , \ - typedef struct M_C(name, _pair_s) M_C(name, _type_t); ) \ - typedef key_type M_C(name, _key_type_t); \ - typedef value_type M_C(name, _value_type_t); \ + typedef struct M_C(name, _pair_s) M_C(name, _type_t); \ + ) \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, key_type, key_oplist) \ M_CHECK_COMPATIBLE_OPLIST(name, 2, value_type, value_oplist) \ @@ -1210,6 +1218,13 @@ typedef enum { size_t index; \ } dict_it_t[1]; \ \ + /* Define internal types for oplist */ \ + typedef dict_t M_C(name, _ct); \ + typedef M_C(name, _type_t) M_C(name, _subtype_ct); \ + typedef key_type M_C(name, _key_ct); \ + typedef value_type M_C(name, _value_ct); \ + typedef dict_it_t M_C(name, _it_ct); \ + \ static inline void \ M_C(name,_int_limit)(dict_t dict, size_t size) \ { \ diff --git a/m-funcobj.h b/m-funcobj.h index bf8ee828..93791406 100644 --- a/m-funcobj.h +++ b/m-funcobj.h @@ -90,7 +90,7 @@ /* Specialization of the OPLIST in function if there is at least one member or not */ #define FUNCOBJI_INS_NO_ATTR_OPLIST(name) \ - (NAME(name), TYPE(M_C(name, _t)), \ + (NAME(name), TYPE(M_C(name, _ct)), \ CLEAR(M_C(name, _clear)), \ INIT(M_C(name,_init)) \ ) @@ -105,7 +105,7 @@ /* Define at least the oplist */ #define FUNCOBJI_INS_ATTR_OPLIST_P3(name, ...) \ - (NAME(name), TYPE(M_C(name, _t)), \ + (NAME(name), TYPE(M_C(name, _ct)), \ INIT_WITH(M_C(name, _init_with)), \ CLEAR(M_C(name, _clear)), \ M_IF_METHOD_ALL(INIT, __VA_ARGS__)(INIT(M_C(name,_init)),), \ @@ -114,19 +114,25 @@ /* Specialization of the definition a function object interface of name 'name' * with a function like retcode () that doesn't have any input parameters. + * Define the following types to be used by instance: + * - M_C(name, _retcode_ct): internal type of the return code + * - M_C(name, _callback_ct): internal type of the callback. + * - M_C(name, _ct): synonym of main type used by oplist. */ #define FUNCOBJI_ITF_NO_PARAM_DEF(name, retcode) \ - typedef retcode M_C(name, _retcode_t); \ + typedef retcode M_C(name, _retcode_ct); \ \ struct M_C(name, _s); \ \ /* No parameters to the callback */ \ - typedef retcode(*M_C(name, _callback_t))(struct M_C(name, _s) *); \ + typedef retcode(*M_C(name, _callback_ct))(struct M_C(name, _s) *); \ \ typedef struct M_C(name, _s) { \ - M_C(name, _callback_t) callback; \ + M_C(name, _callback_ct) callback; \ } M_C(name, _t)[1]; \ \ + typedef M_C(name, _t) M_C(name, _ct); \ + \ static inline retcode \ M_C(name, _call)(M_C(name, _t) funcobj) \ { \ @@ -138,25 +144,33 @@ /* Specialization of the definition a function object interface of name 'name' * with a function like retcode, type of param1, type of param 2, ... * with mandatory input parameters. + * Define the following types to be used by instance: + * - M_C(name, _retcode_ct): internal type of the return code + * - M_C(name, _callback_ct): internal type of the callback. + * - M_C4(name, _param_, num, _ct) for each parameter defined + * - M_C(name, _ct): synonym of main type used by oplist. */ #define FUNCOBJI_ITF_PARAM_DEF(name, retcode, ...) \ - typedef retcode M_C(name, _retcode_t); \ + typedef retcode M_C(name, _retcode_ct); \ \ - /* Define types for all paremeters */ \ + /* Define types for all parameters */ \ M_MAP3(FUNCOBJI_BASE_TYPE, name, __VA_ARGS__) \ \ struct M_C(name, _s); \ \ - typedef retcode(*M_C(name, _callback_t))(struct M_C(name, _s) *, __VA_ARGS__); \ + typedef retcode(*M_C(name, _callback_ct))(struct M_C(name, _s) *, __VA_ARGS__); \ \ typedef struct M_C(name, _s) { \ - M_C(name, _callback_t) callback; \ + M_C(name, _callback_ct) callback; \ } M_C(name, _t)[1]; \ \ + typedef M_C(name, _t) M_C(name, _ct); \ + \ static inline retcode \ M_C(name, _call)(M_C(name, _t) funcobj \ M_MAP3(FUNCOBJI_BASE_ARGLIST, name, __VA_ARGS__) ) \ { \ + /* If the retcode is 'void', don't return the value of the callback */ \ M_IF(M_KEYWORD_P(void, retcode)) ( /* nothing */,return) \ funcobj->callback(funcobj M_MAP3(FUNCOBJI_BASE_ARGCALL, name, __VA_ARGS__) ); \ } @@ -167,10 +181,12 @@ */ #define FUNCOBJI_INS_NO_ATTR_DEF(name, base_name, param_list, callback_core) \ typedef struct M_C(name, _s) { \ - M_C(base_name, _callback_t) callback; \ + M_C(base_name, _callback_ct) callback; \ } M_C(name, _t)[1]; \ \ - static inline M_C(base_name, _retcode_t) \ + typedef M_C(name, _t) M_C(name, _ct); \ + \ + static inline M_C(base_name, _retcode_ct) \ M_C(name, _callback)(M_C(base_name, _t) _self \ M_IF_EMPTY(M_OPFLAT param_list)( \ /* No param */, \ @@ -245,14 +261,16 @@ #define FUNCOBJI_INS_ATTR_DEF_P3(name, base_name, param_list, callback_core, ...) \ typedef struct M_C(name, _s) { \ /* Callback is the mandatory first argument */ \ - M_C(base_name, _callback_t) callback; \ + M_C(base_name, _callback_ct) callback; \ /* All the member attribute of the Function Object */ \ M_MAP(FUNCOBJI_INS_ATTR_STRUCT, __VA_ARGS__) \ } M_C(name, _t)[1]; \ \ - FUNCOBJI_CONTROL_ALL_OPLIST(name, __VA_ARGS__) \ + typedef M_C(name, _t) M_C(name, _ct); \ \ - static inline M_C(base_name, _retcode_t) \ + FUNCOBJI_CONTROL_ALL_OPLIST(name, __VA_ARGS__) \ + \ + static inline M_C(base_name, _retcode_ct) \ M_C(name, _callback)(M_C(base_name, _t) _self \ M_IF_EMPTY(M_OPFLAT param_list)( \ /* No param */, \ @@ -298,7 +316,7 @@ /* Define a numbered type of a parameter of the callback*/ #define FUNCOBJI_BASE_TYPE(name, num, type) \ - typedef type M_C4(name, _param_, num, _t); + typedef type M_C4(name, _param_, num, _ct); /* Define a list of the type of arguments for a function definition */ #define FUNCOBJI_BASE_ARGLIST(name, num, type) \ @@ -328,7 +346,7 @@ /* Define the list of arguments of the instance of the callback */ #define FUNCOBJI_INS_ARGLIST(name, num, param) \ - M_DEFERRED_COMMA M_C4(name, _param_, num, _t) param + M_DEFERRED_COMMA M_C4(name, _param_, num, _ct) param /* Macros for testing for a method presence in all the attributes */ diff --git a/m-genint.h b/m-genint.h index 28819d50..2376730d 100644 --- a/m-genint.h +++ b/m-genint.h @@ -48,14 +48,14 @@ M_BEGIN_PROTECTED_CODE // TO DO: We may want a specialization with constant N value. // Define the limb size used by genint -typedef unsigned long long genint_limb_t; +typedef unsigned long long genint_limb_ct; /* Define a generator of unique integer (Lock Free) */ typedef struct genint_s { unsigned int n; // size of the container unsigned int max; // number of allocated limb - 1 - genint_limb_t mask0; // mask of the last limb (constant) - genint_limb_t mask_master; // mask of the master limb that controls others (constant) + genint_limb_ct mask0; // mask of the last limb (constant) + genint_limb_ct mask_master; // mask of the master limb that controls others (constant) atomic_ullong master; // master bitfield (which informs if a limb is full or not) atomic_ullong *data; // the bitfield which informs if an integer is used or not } genint_t[1]; @@ -64,7 +64,7 @@ typedef struct genint_s { #define GENINT_MAX_ALLOC (GENINT_LIMBSIZE * (GENINT_LIMBSIZE - GENINT_ABA_CPT)) // Define the size of a limb in bits. -#define GENINT_LIMBSIZE ((unsigned)(sizeof(genint_limb_t) * CHAR_BIT)) +#define GENINT_LIMBSIZE ((unsigned)(sizeof(genint_limb_ct) * CHAR_BIT)) // Define the contract of a genint #define GENINT_CONTRACT(s) do { \ @@ -75,7 +75,7 @@ typedef struct genint_s { } while (0) // Define the limb one -#define GENINT_ONE ((genint_limb_t)1) +#define GENINT_ONE ((genint_limb_ct)1) #define GENINT_FULL_MASK ULLONG_MAX @@ -121,9 +121,9 @@ genint_init(genint_t s, unsigned int n) s->max = (unsigned int) (alloc-1); s->mask0 = (index == 0) ? GENINT_FULL_MASK : ~((GENINT_ONE<<(GENINT_LIMBSIZE-index))-1); s->mask_master = (((GENINT_ONE << alloc) - 1) << (GENINT_LIMBSIZE-alloc)) >> GENINT_ABA_CPT; - atomic_init (&s->master, (genint_limb_t)0); + atomic_init (&s->master, (genint_limb_ct)0); for(unsigned int i = 0; i < alloc; i++) - atomic_init(&s->data[i], (genint_limb_t)0); + atomic_init(&s->data[i], (genint_limb_ct)0); GENINT_CONTRACT(s); } @@ -151,18 +151,18 @@ genint_pop(genint_t s) { GENINT_CONTRACT(s); // First read master to see which limb is not full. - genint_limb_t master = atomic_load(&s->master); + genint_limb_ct master = atomic_load(&s->master); // While master is not full while ((master >> GENINT_ABA_CPT) != s->mask_master) { // Let's get the index i of the first not full limb according to master. unsigned int i = m_core_clz64(~master); assert (i < GENINT_LIMBSIZE); // Let's compute the mask of this limb representing the limb as being full - genint_limb_t mask = s->mask0; + genint_limb_ct mask = s->mask0; mask = (i == s->max) ? mask : GENINT_FULL_MASK; unsigned int bit; // Let's load this limb, - genint_limb_t next, org = atomic_load(&s->data[i]); + genint_limb_ct next, org = atomic_load(&s->data[i]); do { // If it is now full, we have been preempted by another. if (M_UNLIKELY (org == mask)) @@ -181,7 +181,7 @@ genint_pop(genint_t s) // If the limb is now full, try to update master if (M_UNLIKELY(next == mask)) { while (true) { - genint_limb_t newMaster; + genint_limb_ct newMaster; if (next == mask) { newMaster = GENINT_MASTER_SET(master, i); } else { @@ -213,9 +213,9 @@ genint_push(genint_t s, unsigned int n) assert (n < s->n); const unsigned int i = n / GENINT_LIMBSIZE; const unsigned int bit = GENINT_LIMBSIZE - 1 - (n % GENINT_LIMBSIZE); - genint_limb_t master = atomic_load(&s->master); + genint_limb_ct master = atomic_load(&s->master); // Load the limb - genint_limb_t next, org = atomic_load(&s->data[i]); + genint_limb_ct next, org = atomic_load(&s->data[i]); do { assert ((org & (GENINT_ONE << bit)) != 0); // Reset it @@ -223,13 +223,13 @@ genint_push(genint_t s, unsigned int n) // Try to unreserve it. } while (!atomic_compare_exchange_weak (&s->data[i], &org, next)); // if the limb was marked as full by master - genint_limb_t mask = s->mask0; + genint_limb_ct mask = s->mask0; mask = (i == s->max) ? mask : GENINT_FULL_MASK; if (M_UNLIKELY (next != mask)) { // Let's compute the mask of this limb representing the limb as being full // Let's try to update master to say that this limb is not full while (true) { - genint_limb_t newMaster; + genint_limb_ct newMaster; if (next == mask) { newMaster = GENINT_MASTER_SET(master, i); } else { diff --git a/m-i-list.h b/m-i-list.h index b9691974..6ced2024 100644 --- a/m-i-list.h +++ b/m-i-list.h @@ -67,7 +67,7 @@ typedef struct ilist_head_s { struct ilist_head_s *next; struct ilist_head_s *prev; -} ilist_head_t; +} ilist_head_ct; /* Indirection call to allow expanding all arguments */ #define ILISTI_OPLIST_P1(arg) ILISTI_OPLIST_P2 arg @@ -86,11 +86,11 @@ typedef struct ilist_head_s { CLEAR(M_C(name, _clear)), \ INIT_MOVE(M_C(name, _init_move)), \ MOVE(M_C(name, _move)), \ - TYPE(M_C(name,_t)), \ + TYPE(M_C(name,_ct)), \ CLEAN(M_C(name,_clean)), \ - SUBTYPE(M_C(name,_type_t)), \ + SUBTYPE(M_C(name,_subtype_ct)), \ TEST_EMPTY(M_C(name,_empty_p)), \ - IT_TYPE(M_C(name,_it_t)), \ + IT_TYPE(M_C(name,_it_ct)), \ IT_FIRST(M_C(name,_it)), \ IT_SET(M_C(name,_it_set)), \ IT_LAST(M_C(name,_it_last)), \ @@ -154,8 +154,6 @@ typedef struct ilist_head_s { typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ - typedef type M_C(name, _type_t); \ - \ typedef struct M_C(name, _it_s) { \ struct ilist_head_s *head; \ struct ilist_head_s *previous; \ @@ -163,6 +161,11 @@ typedef struct ilist_head_s { struct ilist_head_s *next; \ } it_t[1]; \ \ + /* Define types used by oplist */ \ + typedef type M_C(name, _subtype_ct); \ + typedef list_t M_C(name, _ct); \ + typedef it_t M_C(name, _it_ct); \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ static inline void M_C(name, _init)(list_t list) \ diff --git a/m-i-shared.h b/m-i-shared.h index 98de07a5..d0f71d69 100644 --- a/m-i-shared.h +++ b/m-i-shared.h @@ -51,8 +51,8 @@ M_BEGIN_PROTECTED_CODE #define ISHARED_PTR_DEF(name, ...) \ M_BEGIN_PROTECTED_CODE \ ISHAREDI_PTR_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)() ), \ - (name, __VA_ARGS__ ))) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), M_C(name, _t) ), \ + (name, __VA_ARGS__ , M_C(name, _t) ))) \ M_END_PROTECTED_CODE @@ -76,9 +76,9 @@ M_BEGIN_PROTECTED_CODE SET(M_C(name, _set) M_IPTR), \ CLEAR(M_C(name, _clear)), \ CLEAN(M_C(name, _clean) M_IPTR), \ - TYPE(M_C(name, _t)), \ + TYPE(M_C(name, _ct)), \ OPLIST(oplist), \ - SUBTYPE(M_C(name, _type_t)) \ + SUBTYPE(M_C(name, _subtype_ct)) \ ,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),) \ @@ -88,32 +88,38 @@ M_BEGIN_PROTECTED_CODE #define ISHAREDI_PTR_DEF_P1(arg) ISHAREDI_PTR_DEF_P2 arg /* Validate the oplist before going further */ -#define ISHAREDI_PTR_DEF_P2(name, type, oplist) \ - M_IF_OPLIST(oplist)(ISHAREDI_PTR_DEF_P3, ISHAREDI_PTR_DEF_FAILURE)(name, type, oplist) +#define ISHAREDI_PTR_DEF_P2(name, type, oplist, shared_t) \ + M_IF_OPLIST(oplist)(ISHAREDI_PTR_DEF_P3, ISHAREDI_PTR_DEF_FAILURE)(name, type, oplist, shared_t) /* Stop processing with a compilation failure */ -#define ISHAREDI_PTR_DEF_FAILURE(name, type, oplist) \ +#define ISHAREDI_PTR_DEF_FAILURE(name, type, oplist, shared_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(ISHARED_PTR_DEF): the given argument is not a valid oplist: " #oplist) -#define ISHAREDI_PTR_DEF_P3(name, type, oplist) \ +#define ISHAREDI_PTR_DEF_P3(name, type, oplist, shared_t) \ \ - typedef type *M_C(name,_t); \ - typedef type M_C(name, _type_t); \ + /* The shared pointer is only a pointer to the type */ \ + typedef type *shared_t; \ + \ + /* Define internal types for oplits */ \ + typedef shared_t M_C(name, _ct); \ + typedef type M_C(name, _subtype_ct); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ - static inline M_C(name,_t) \ + static inline shared_t \ M_C(name, _init)(type *ptr) \ { \ - if (M_LIKELY (ptr != NULL)) \ + /* Initialize the type referenced by the pointer */ \ + if (M_LIKELY (ptr != NULL)) { \ atomic_init(&ptr->M_C(name, _cpt), 1); \ + } \ return ptr; \ } \ \ - static inline M_C(name,_t) \ - M_C(name, _init_set)(M_C(name,_t) shared) \ + static inline shared_t \ + M_C(name, _init_set)(shared_t shared) \ { \ - if (M_LIKELY (shared != NULL)) { \ + if (M_LIKELY (shared != NULL)) { \ int n = atomic_fetch_add(&(shared->M_C(name, _cpt)), 1); \ (void) n; \ } \ @@ -121,7 +127,7 @@ M_BEGIN_PROTECTED_CODE } \ \ static inline void M_ATTR_DEPRECATED \ - M_C(name, _init_set2)(M_C(name,_t) *ptr, M_C(name,_t) shared) \ + M_C(name, _init_set2)(shared_t *ptr, shared_t shared) \ { \ assert (ptr != NULL); \ *ptr = M_C(name, _init_set)(shared); \ @@ -130,7 +136,7 @@ M_BEGIN_PROTECTED_CODE M_IF_DISABLED_METHOD(NEW, oplist) \ ( /* Nothing to do */, M_IF_METHOD(INIT, oplist) \ ( \ - static inline M_C(name,_t) \ + static inline shared_t \ M_C(name, _init_new)(void) \ { \ type *ptr = M_CALL_NEW(oplist, type); \ @@ -146,9 +152,9 @@ M_BEGIN_PROTECTED_CODE /* End of NEW */) \ \ static inline void \ - M_C(name, _clear)(M_C(name,_t) shared) \ + M_C(name, _clear)(shared_t shared) \ { \ - if (shared != NULL) { \ + if (shared != NULL) { \ if (atomic_fetch_sub(&(shared->M_C(name, _cpt)), 1) == 1) { \ M_CALL_CLEAR(oplist, *shared); \ M_IF_DISABLED_METHOD(DEL, oplist)(, M_CALL_DEL(oplist, shared);) \ @@ -157,7 +163,7 @@ M_BEGIN_PROTECTED_CODE } \ \ static inline void \ - M_C(name, _clear_ptr)(M_C(name,_t) *shared) \ + M_C(name, _clear_ptr)(shared_t *shared) \ { \ assert(shared != NULL); \ M_C(name, _clear)(*shared); \ @@ -165,14 +171,14 @@ M_BEGIN_PROTECTED_CODE } \ \ static inline void \ - M_C(name, _clean)(M_C(name,_t) *shared) \ + M_C(name, _clean)(shared_t *shared) \ { \ M_C(name, _clear)(*shared); \ *shared = NULL; \ } \ \ static inline void \ - M_C(name, _set)(M_C(name,_t) *ptr, M_C(name,_t)shared) \ + M_C(name, _set)(shared_t *ptr, shared_t shared) \ { \ assert (ptr != NULL); \ if (M_LIKELY (*ptr != shared)) { \ @@ -185,4 +191,3 @@ M_BEGIN_PROTECTED_CODE M_END_PROTECTED_CODE #endif - diff --git a/m-list.h b/m-list.h index e3cbeb29..13bd3be7 100644 --- a/m-list.h +++ b/m-list.h @@ -79,10 +79,10 @@ MOVE(M_C(name, _move)), \ INIT_MOVE(M_C(name, _init_move)), \ SWAP(M_C(name, _swap)), \ - TYPE(M_C(name,_t)), \ - SUBTYPE(M_C(name, _type_t)), \ + TYPE(M_C(name,_ct)), \ + SUBTYPE(M_C(name,_subtype_ct)), \ TEST_EMPTY(M_C(name,_empty_p)), \ - IT_TYPE(M_C(name, _it_t)), \ + IT_TYPE(M_C(name, _it_ct)), \ IT_FIRST(M_C(name,_it)), \ IT_END(M_C(name,_it_end)), \ IT_SET(M_C(name,_it_set)), \ @@ -166,16 +166,19 @@ struct M_C(name, _s) *next; \ type data; \ } *list_t[1]; \ - typedef struct M_C(name, _s) *M_C(name, _ptr); \ - typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ - \ - typedef type M_C(name, _type_t); \ \ typedef struct M_C(name, _it_s) { \ struct M_C(name, _s) *previous; \ struct M_C(name, _s) *current; \ } it_t[1]; \ \ + /* Definition of the synonyms of the type */ \ + typedef struct M_C(name, _s) *M_C(name, _ptr); \ + typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ + typedef list_t M_C(name, _ct); \ + typedef it_t M_C(name, _it_ct); \ + typedef type M_C(name, _subtype_ct); \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ LISTI_MEMPOOL_DEF(name, type, oplist, list_t, it_t) \ @@ -194,9 +197,8 @@ - name: prefix to be used - type: type of the elements of the list - oplist: oplist of the type of the elements of the container - - list_t: alias for M_C(name, _t) [ type of the container ] - - it_t: alias for M_C(name, _it_t) [ iterator of the container ] - - node_t: alias for M_C(name, _node_t) [ node ] + - list_t: alias for type of the container + - it_t: alias for iterator of the container */ #define LISTI_DEF_P4(name, type, oplist, list_t, it_t) \ \ @@ -871,16 +873,19 @@ struct M_C(name, _s) *front; \ struct M_C(name, _s) *back; \ } list_t[1]; \ - typedef struct M_C(name, _head_s) *M_C(name, _ptr); \ - typedef const struct M_C(name, _head_s) *M_C(name, _srcptr); \ - \ - typedef type M_C(name, _type_t); \ \ typedef struct M_C(name, _it_s) { \ struct M_C(name, _s) *previous; \ struct M_C(name, _s) *current; \ } it_t[1]; \ \ + /* Definition of the synonyms of the type */ \ + typedef struct M_C(name, _head_s) *M_C(name, _ptr); \ + typedef const struct M_C(name, _head_s) *M_C(name, _srcptr); \ + typedef list_t M_C(name, _ct); \ + typedef it_t M_C(name, _it_ct); \ + typedef type M_C(name, _subtype_ct); \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ LISTI_MEMPOOL_DEF(name, type, oplist, list_t, it_t) \ @@ -899,9 +904,8 @@ - name: prefix to be used - type: type of the elements of the array - oplist: oplist of the type of the elements of the container - - list_t: alias for M_C(name, _t) [ type of the container ] - - it_t: alias for M_C(name, _it_t) [ iterator of the container ] - - node_t: alias for M_C(name, _node_t) [ node ] + - list_t: alias for type of the container + - it_t: alias for iterator of the container */ #define LISTI_DUAL_PUSH_DEF_P4(name, type, oplist, list_t, it_t) \ \ diff --git a/m-mempool.h b/m-mempool.h index 7fd43086..c74a283e 100644 --- a/m-mempool.h +++ b/m-mempool.h @@ -41,12 +41,13 @@ */ #define MEMPOOL_DEF(name, type) \ M_BEGIN_PROTECTED_CODE \ - MEMPOOL_DEF_P2(name, type) \ + MEMPOOL_DEF_P2(name, type, M_C(name, _t) ) \ M_END_PROTECTED_CODE /* User shall be able to cutomize the size of the segment and/or the minimun number of elements. + The default is the number of elements that fits in 16KB. */ #ifndef MEMPOOL_MAX_PER_SEGMENT #define MEMPOOL_MAX_PER_SEGMENT(type) \ @@ -56,31 +57,31 @@ /********************************** INTERNAL ************************************/ -#define MEMPOOL_DEF_P2(name, type) \ +#define MEMPOOL_DEF_P2(name, type, name_t) \ \ typedef union M_C(name,_union_s) { \ type t; \ union M_C(name,_union_s) *next; \ - } M_C(name,_union_t); \ + } M_C(name,_union_ct); \ \ 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); \ + M_C(name,_union_ct) tab[MEMPOOL_MAX_PER_SEGMENT(type)]; \ + } M_C(name,_segment_ct); \ \ 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]; \ + M_C(name,_union_ct) *free_list; \ + M_C(name,_segment_ct) *current_segment; \ + } name_t[1]; \ \ static inline void \ - M_C(name,_init)(M_C(name,_t) mem) \ + M_C(name,_init)(name_t mem) \ { \ mem->free_list = NULL; \ - mem->current_segment = M_MEMORY_ALLOC(M_C(name,_segment_t)); \ + mem->current_segment = M_MEMORY_ALLOC(M_C(name,_segment_ct)); \ if (mem->current_segment == NULL) { \ - M_MEMORY_FULL(sizeof (M_C(name,_segment_t))); \ + M_MEMORY_FULL(sizeof (M_C(name,_segment_ct))); \ return; \ } \ mem->current_segment->next = NULL; \ @@ -89,12 +90,12 @@ } \ \ static inline void \ - M_C(name,_clear)(M_C(name,_t) mem) \ + M_C(name,_clear)(name_t mem) \ { \ MEMPOOLI_CONTRACT(mem, type); \ - M_C(name,_segment_t) *segment = mem->current_segment; \ + M_C(name,_segment_ct) *segment = mem->current_segment; \ while (segment != NULL) { \ - M_C(name,_segment_t) *next = segment->next; \ + M_C(name,_segment_ct) *next = segment->next; \ M_MEMORY_DEL (segment); \ segment = next; \ } \ @@ -104,21 +105,21 @@ } \ \ static inline type * \ - M_C(name,_alloc)(M_C(name,_t) mem) \ + M_C(name,_alloc)(name_t mem) \ { \ MEMPOOLI_CONTRACT(mem, type); \ - M_C(name,_union_t) *ret = mem->free_list; \ + M_C(name,_union_ct) *ret = mem->free_list; \ if (ret != NULL) { \ mem->free_list = ret->next; \ return &ret->t; \ } \ - M_C(name,_segment_t) *segment = mem->current_segment; \ + M_C(name,_segment_ct) *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)); \ + M_C(name,_segment_ct) *new_segment = M_MEMORY_ALLOC (M_C(name,_segment_ct)); \ if (M_UNLIKELY (new_segment == NULL)) { \ - M_MEMORY_FULL(sizeof (M_C(name,_segment_t))); \ + M_MEMORY_FULL(sizeof (M_C(name,_segment_ct))); \ return NULL; \ } \ new_segment->next = segment; \ @@ -134,12 +135,12 @@ } \ \ static inline void \ - M_C(name,_free)(M_C(name,_t) mem, type *ptr) \ + M_C(name,_free)(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; \ + M_C(name,_union_ct) *ret = (M_C(name,_union_ct) *)(uintptr_t)ptr; \ ret->next = mem->free_list; \ mem->free_list = ret; \ MEMPOOLI_CONTRACT(mem, type); \ diff --git a/m-mutex.h b/m-mutex.h index 45bb715a..d4f59056 100644 --- a/m-mutex.h +++ b/m-mutex.h @@ -153,13 +153,13 @@ static inline bool m_thread_sleep(unsigned long long usec) } // Internal type, not exported. -typedef once_flag m_oncei_t[1]; +typedef once_flag m_once_ct[1]; -// Initial value for m_oncei_t +// Initial value for m_once_ct #define M_ONCEI_INIT_VALUE { ONCE_FLAG_INIT } // Call the function exactly once -static inline void m_oncei_call(m_oncei_t o, void (*func)(void)) +static inline void m_oncei_call(m_once_ct o, void (*func)(void)) { call_once(o,func); } @@ -316,7 +316,7 @@ static inline bool m_thread_sleep(unsigned long long usec) // Internal type, not exported. -typedef INIT_ONCE m_oncei_t[1]; +typedef INIT_ONCE m_once_ct[1]; #define M_ONCEI_INIT_VALUE { INIT_ONCE_STATIC_INIT } static inline BOOL CALLBACK m_oncei_callback( PINIT_ONCE InitOnce, PVOID Parameter, PVOID *lpContext) { @@ -327,7 +327,7 @@ static inline BOOL CALLBACK m_oncei_callback( PINIT_ONCE InitOnce, PVOID Paramet (*func)(); return TRUE; } -static inline void m_oncei_call(m_oncei_t o, void (*func)(void)) +static inline void m_oncei_call(m_once_ct o, void (*func)(void)) { InitOnceExecuteOnce(o, m_oncei_callback, (void*)(intptr_t)func, NULL); } @@ -475,9 +475,9 @@ static inline bool m_thread_sleep(unsigned long long usec) } // Internal type, not exported. -typedef pthread_once_t m_oncei_t[1]; +typedef pthread_once_t m_once_ct[1]; #define M_ONCEI_INIT_VALUE { PTHREAD_ONCE_INIT } -static inline void m_oncei_call(m_oncei_t o, void (*func)(void)) +static inline void m_oncei_call(m_once_ct o, void (*func)(void)) { pthread_once(o,func); } @@ -488,7 +488,6 @@ M_END_PROTECTED_CODE #endif -// TODO: m_thread_sleep doesn't yield thread during waiting, making it a poor choice for active waiting. // TODO: Obsolete M_LOCK macro. /* M_LOCK macro. Allow simple locking encapsulation. @@ -512,7 +511,7 @@ M_END_PROTECTED_CODE static void M_C(m_mutex_init_, name)(void) { \ m_mutex_init(name); \ } \ - m_oncei_t M_C(m_once_, name) = M_ONCEI_INIT_VALUE + m_once_ct M_C(m_once_, name) = M_ONCEI_INIT_VALUE # define M_LOCKI_BY_ONCE(name) \ (m_oncei_call(M_C(m_once_, name), M_C(m_mutex_init_, name)), \ m_mutex_lock(name), (void) 0 ) diff --git a/m-prioqueue.h b/m-prioqueue.h index b5191eed..80207c66 100644 --- a/m-prioqueue.h +++ b/m-prioqueue.h @@ -73,8 +73,8 @@ ,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)) \ + ,TYPE(M_C(name,_ct)) \ + ,SUBTYPE(M_C(name, _subtype_ct)) \ ,CLEAN(M_C(name,_clean)) \ ,PUSH(M_C(name,_push)) \ ,POP(M_C(name,_pop)) \ @@ -104,9 +104,10 @@ - it_t: iterator of the container */ #define PRIOQUEUEI_DEF_P3(name, type, oplist, prioqueue_t, it_t) \ + \ + /* Definition of the internal array used to construct the priority queue */ \ ARRAY_DEF(M_C(name, _array), type, oplist) \ \ - typedef type M_C(name, _type_t); \ \ typedef struct M_C(name, _s) { \ M_C(name, _array_t) array; \ @@ -114,8 +115,14 @@ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ + /* The iterator is the same one as the one of the internal array */ \ typedef M_C(name, _array_it_t) it_t; \ \ + /* Definition of the internal types used by the oplist */ \ + typedef prioqueue_t M_C(name, _ct); \ + typedef type M_C(name, _subtype_ct); \ + typedef it_t M_C(name, _subtype_t); \ + \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ static inline void \ diff --git a/m-rbtree.h b/m-rbtree.h index 9b25ea6e..7cdc5df1 100644 --- a/m-rbtree.h +++ b/m-rbtree.h @@ -29,21 +29,21 @@ /* Define a Red/Black binary tree of a given type. USAGE: RBTREE_DEF(name, type [, oplist_of_the_type]) */ -#define RBTREE_DEF(name, ...) \ - M_BEGIN_PROTECTED_CODE \ - RBTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), \ - M_C(name, _t), M_C(name, _node_t), M_C(name, _it_t)), \ - (name, __VA_ARGS__ , \ - M_C(name, _t), M_C(name, _node_t), M_C(name, _it_t)))) \ +#define RBTREE_DEF(name, ...) \ + M_BEGIN_PROTECTED_CODE \ + RBTREEI_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), \ + M_C(name, _t), M_C(name, _node_ct), M_C(name, _it_t)), \ + (name, __VA_ARGS__ , \ + M_C(name, _t), M_C(name, _node_ct), M_C(name, _it_t)))) \ M_END_PROTECTED_CODE /* Define the oplist of a rbtree of type. 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), \ +#define RBTREE_OPLIST(...) \ + RBTREEI_OPLIST_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ + ((__VA_ARGS__, M_DEFAULT_OPLIST), \ (__VA_ARGS__ ))) @@ -73,11 +73,11 @@ 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)), \ + TYPE(M_C(name,_ct)), \ + SUBTYPE(M_C(name, _subtype_ct)), \ TEST_EMPTY(M_C(name,_empty_p)), \ GET_SIZE(M_C(name, _size)), \ - IT_TYPE(M_C(name, _it_t)), \ + IT_TYPE(M_C(name, _it_ct)), \ IT_FIRST(M_C(name,_it)), \ IT_SET(M_C(name,_it_set)), \ IT_LAST(M_C(name,_it_last)), \ @@ -161,9 +161,9 @@ typedef enum { - name: prefix to be used - type: type of the elements of the rbtree - oplist: oplist of the type of the elements of the container - - tree_t: alias for M_C(name, _t) [ type of the container ] - - it_t: alias for M_C(name, _it_t) [ iterator of the container ] - - node_t: alias for M_C(name, _node_t) [ node ] + - tree_t: alias for the type of the container + - it_t: alias for the iterator of the container + - node_t: alias for the node of an element of the container */ #define RBTREEI_DEF_P3(name, type, oplist, tree_t, node_t, it_t) \ \ @@ -192,7 +192,10 @@ typedef enum { unsigned int cpt; \ } it_t[1]; \ \ - typedef type M_C(name, _type_t); \ + /* Definition of the alias used by the oplists */ \ + typedef type M_C(name, _subtype_ct); \ + typedef tree_t M_C(name, _ct); \ + typedef it_t M_C(name, _it_ct); \ \ /* Link with fast memory allocator if requested */ \ M_IF_METHOD(MEMPOOL, oplist)( \ @@ -1089,7 +1092,7 @@ typedef enum { assert (f != NULL && f->m_interface != NULL); \ m_serial_local_t local; \ m_serial_return_code_t ret; \ - const M_C(name, _type_t) *item; \ + M_C(name, _subtype_ct) const *item; \ bool first_done = false; \ it_t it; \ ret = f->m_interface->write_array_start(local, f, t1->size); \ diff --git a/m-shared.h b/m-shared.h index f28e05f0..08d5abd5 100644 --- a/m-shared.h +++ b/m-shared.h @@ -91,7 +91,7 @@ M_BEGIN_PROTECTED_CODE CLEAN(M_C(name, _clean)), \ MOVE(M_C(name, _move)), \ SWAP(M_C(name, _swap)) \ - ,TYPE(M_C(name, _t)) \ + ,TYPE(M_C(name, _ct)) \ ,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),) \ @@ -127,8 +127,8 @@ static inline int sharedi_integer_cref(int *p) { return *p; } #define SHAREDI_PTR_DEF_P1(arg) SHAREDI_PTR_DEF_P2 arg /* Validate the oplist before going further */ -#define SHAREDI_PTR_DEF_P2(name, type, oplist, cpt_oplist_t) \ - M_IF_OPLIST(oplist)(SHAREDI_PTR_DEF_P3, SHAREDI_PTR_DEF_FAILURE)(name, type, oplist, cpt_oplist_t) +#define SHAREDI_PTR_DEF_P2(name, type, oplist, cpt_oplist) \ + M_IF_OPLIST(oplist)(SHAREDI_PTR_DEF_P3, SHAREDI_PTR_DEF_FAILURE)(name, type, oplist, cpt_oplist) /* Stop processing with a compilation failure */ #define SHAREDI_PTR_DEF_FAILURE(name, type, oplist, cpt_oplist) \ @@ -139,16 +139,19 @@ static inline int sharedi_integer_cref(int *p) { return *p; } \ 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 */ \ + M_GET_TYPE cpt_oplist cpt; /* Counter of how many refs the data */ \ bool combineAlloc; /* Does the data and the ptr share the slot? */ \ } *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); \ \ + /* Internal type for oplist */ \ + typedef M_C(name, _t) M_C(name, _ct); \ + \ typedef struct M_C(name, combine_s) { \ type data; \ struct M_C(name, _s) ptr; \ - } M_C(name, combine_t)[1]; \ + } M_C(name, combine_ct)[1]; \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ @@ -321,6 +324,8 @@ static inline int sharedi_integer_cref(int *p) { return *p; } return data; \ } \ + + /********************************** SHARED RESOURCE ************************************/ #define SHAREDI_RESOURCE_CONTRACT(s) do { \ @@ -346,11 +351,11 @@ static inline int sharedi_integer_cref(int *p) { return *p; } atomic_uint cpt; \ type x; \ M_CACHELINE_ALIGN(align, type, atomic_uint); \ - } M_C(name, _atype_t); \ + } M_C(name, _atype_ct); \ \ typedef struct M_C(name, _s) { \ genint_t core; \ - M_C(name, _atype_t) *buffer; \ + M_C(name, _atype_ct) *buffer; \ } M_C(name, _t)[1]; \ \ typedef struct M_C(name, _it_s) { \ @@ -358,14 +363,18 @@ static inline int sharedi_integer_cref(int *p) { return *p; } struct M_C(name, _s) *ref; \ } M_C(name, _it_t)[1]; \ \ + /* Internal Types for oplist */ \ + typedef M_C(name, _t) M_C(name, _ct); \ + typedef M_C(name, _it_t) M_C(name, _it__ct); \ + \ static inline void \ M_C(name, _init)(M_C(name, _t) s, size_t n) \ { \ assert(s != NULL); \ assert (n > 0 && n < UINT_MAX); \ - s->buffer = M_CALL_REALLOC(oplist, M_C(name, _atype_t), NULL, n); \ + s->buffer = M_CALL_REALLOC(oplist, M_C(name, _atype_ct), NULL, n); \ if (M_UNLIKELY (s->buffer == NULL)) { \ - M_MEMORY_FULL(sizeof(M_C(name, _atype_t)) * n); \ + M_MEMORY_FULL(sizeof(M_C(name, _atype_ct)) * n); \ return; \ } \ for(size_t i = 0; i < n; i++) { \ diff --git a/m-snapshot.h b/m-snapshot.h index a0d19ce6..e6e97440 100644 --- a/m-snapshot.h +++ b/m-snapshot.h @@ -36,8 +36,8 @@ M_BEGIN_PROTECTED_CODE #define SNAPSHOT_SPSC_DEF(name, ...) \ M_BEGIN_PROTECTED_CODE \ SNAPSHOTI_SPSC_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)() ), \ - (name, __VA_ARGS__ ))) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), M_C(name, _t) ), \ + (name, __VA_ARGS__ , M_C(name, _t) ))) \ M_END_PROTECTED_CODE @@ -46,8 +46,8 @@ M_BEGIN_PROTECTED_CODE #define SNAPSHOT_SPMC_DEF(name, ...) \ M_BEGIN_PROTECTED_CODE \ SNAPSHOTI_SPMC_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)() ), \ - (name, __VA_ARGS__ ))) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), M_C(name, _t) ), \ + (name, __VA_ARGS__ , M_C(name, _t) ))) \ M_END_PROTECTED_CODE @@ -56,8 +56,8 @@ M_BEGIN_PROTECTED_CODE #define SNAPSHOT_MPMC_DEF(name, ...) \ M_BEGIN_PROTECTED_CODE \ SNAPSHOTI_MPMC_DEF_P1(M_IF_NARGS_EQ1(__VA_ARGS__) \ - ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)() ), \ - (name, __VA_ARGS__ ))) \ + ((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__)(), M_C(name, _t) ), \ + (name, __VA_ARGS__ , M_C(name, _t) ))) \ M_END_PROTECTED_CODE @@ -88,8 +88,8 @@ M_BEGIN_PROTECTED_CODE ,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)) \ + ,TYPE(M_C(name, _ct)) \ + ,SUBTYPE(M_C(name, _subtype_ct)) \ ,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)),) \ @@ -137,14 +137,15 @@ M_BEGIN_PROTECTED_CODE #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) \ - M_IF_OPLIST(oplist)(SNAPSHOTI_SPSC_DEF_P3, SNAPSHOTI_SPSC_DEF_FAILURE)(name, type, oplist) +#define SNAPSHOTI_SPSC_DEF_P2(name, type, oplist, snapshot_t) \ + M_IF_OPLIST(oplist)(SNAPSHOTI_SPSC_DEF_P3, SNAPSHOTI_SPSC_DEF_FAILURE)(name, type, oplist, snapshot_t) /* Stop processing with a compilation failure */ -#define SNAPSHOTI_SPSC_DEF_FAILURE(name, type, oplist) \ +#define SNAPSHOTI_SPSC_DEF_FAILURE(name, type, oplist, snapshot_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(SNAPSHOT_SPSC_DEF): the given argument is not a valid oplist: " #oplist) -#define SNAPSHOTI_SPSC_DEF_P3(name, type, oplist) \ +/* Expand the type and the functions of a SPSC snapshot */ +#define SNAPSHOTI_SPSC_DEF_P3(name, type, oplist, snapshot_t) \ \ /* Create an aligned type to avoid false sharing between threads */ \ typedef struct M_C(name, _aligned_type_s) { \ @@ -155,15 +156,18 @@ M_BEGIN_PROTECTED_CODE 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]; \ + } snapshot_t[1]; \ typedef struct M_C(name, _s) *M_C(name, _ptr); \ typedef const struct M_C(name, _s) *M_C(name, _srcptr); \ \ - typedef type M_C(name, _type_t); \ + /* Define internal types for oplist */ \ + typedef snapshot_t M_C(name, _ct); \ + typedef type M_C(name, _subtype_ct); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ - static inline void M_C(name, _init)(M_C(name, _t) snap) \ + static inline void \ + M_C(name, _init)(snapshot_t snap) \ { \ assert(snap != NULL); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ @@ -173,7 +177,8 @@ M_BEGIN_PROTECTED_CODE SNAPSHOTI_SPSC_CONTRACT(snap); \ } \ \ - static inline void M_C(name, _clear)(M_C(name, _t) snap) \ + static inline void \ + M_C(name, _clear)(snapshot_t snap) \ { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ for(int i = 0; i < SNAPSHOTI_SPSC_MAX_BUFFER; i++) { \ @@ -181,8 +186,9 @@ M_BEGIN_PROTECTED_CODE } \ } \ \ - static inline void M_C(name, _init_set)(M_C(name, _t) snap, \ - M_C(name, _t) org) \ + /* const is missing for org due to use of atomic_load of org */ \ + static inline void \ + M_C(name, _init_set)(snapshot_t snap, snapshot_t org) \ { \ SNAPSHOTI_SPSC_CONTRACT(org); \ assert(snap != NULL && snap != org); \ @@ -193,8 +199,9 @@ M_BEGIN_PROTECTED_CODE SNAPSHOTI_SPSC_CONTRACT(snap); \ } \ \ - static inline void M_C(name, _set)(M_C(name, _t) snap, \ - M_C(name, _t) org) \ + /* const is missing for org due to use of atomic_load of org */ \ + static inline void \ + M_C(name, _set)(snapshot_t snap, snapshot_t org) \ { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ SNAPSHOTI_SPSC_CONTRACT(org); \ @@ -206,8 +213,8 @@ M_BEGIN_PROTECTED_CODE } \ \ M_IF_METHOD(INIT_MOVE, oplist)( \ - static inline void M_C(name, _init_move)(M_C(name, _t) snap, \ - M_C(name, _t) org) \ + static inline void \ + M_C(name, _init_move)(snapshot_t snap, snapshot_t org) \ { \ SNAPSHOTI_SPSC_CONTRACT(org); \ assert(snap != NULL && snap != org); \ @@ -218,26 +225,27 @@ M_BEGIN_PROTECTED_CODE 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); \ - SNAPSHOTI_SPSC_CONTRACT(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); \ - } \ - 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) */ \ + M_IF_METHOD(MOVE, oplist)( \ + static inline void \ + M_C(name, _move)(snapshot_t snap, \ + snapshot_t org) \ + { \ + SNAPSHOTI_SPSC_CONTRACT(snap); \ + SNAPSHOTI_SPSC_CONTRACT(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); \ + } \ + 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) */ \ \ - \ - static inline type *M_C(name, _write)(M_C(name, _t) snap) \ + static inline type * \ + M_C(name, _write)(snapshot_t snap) \ { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ @@ -255,7 +263,8 @@ M_BEGIN_PROTECTED_CODE 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)(snapshot_t snap) \ { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ unsigned char nextFlags, origFlags = atomic_load (&snap->flags); \ @@ -278,21 +287,27 @@ M_BEGIN_PROTECTED_CODE 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) \ + /* Non const due to use of atomic_load */ \ + static inline bool \ + M_C(name, _updated_p)(snapshot_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) \ + /* Non const due to use of atomic_load */ \ + static inline type * \ + M_C(name, _get_write_buffer)(snapshot_t snap) \ { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ 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) \ + /* Non const due to use of atomic_load */ \ + static inline type const * \ + M_C(name, _get_read_buffer)(snapshot_t snap) \ { \ SNAPSHOTI_SPSC_CONTRACT(snap); \ unsigned char flags = atomic_load(&snap->flags); \ @@ -312,7 +327,7 @@ M_BEGIN_PROTECTED_CODE #define SNAPSHOTI_SPMC_MAX_READER (GENINT_MAX_ALLOC-SNAPSHOTI_SPMC_EXTRA_BUFFER) -/* structure to handle SPMC snapshot but return an unique index in the buffer array. +/* Internal structure to handle SPMC snapshot but return an unique index in the buffer array. - lastNext: last published written index + next flag (format SNAPSHOTI_SPMC_INT_FLAG) - currentWrite: the index being currently written. - n_reader : number of readers @@ -325,7 +340,7 @@ typedef struct snapshot_mrsw_int_s { size_t n_reader; atomic_uint *cptTab; genint_t freeList; -} snapshot_mrsw_int_t[1]; +} snapshot_mrsw_int_ct[1]; // can't check currentWrite due to potential data race on it #define SNAPSHOTI_SPMC_INT_CONTRACT(s) do { \ @@ -336,9 +351,9 @@ typedef struct snapshot_mrsw_int_s { assert (s->cptTab != NULL); \ } while (0) -/* Initialize snapshot_mrsw_int_t for n readers (constructor) */ +/* Initialize snapshot_mrsw_int_ct for n readers (constructor) */ static inline void -snapshot_mrsw_int_init(snapshot_mrsw_int_t s, size_t n) +snapshot_mrsw_int_init(snapshot_mrsw_int_ct s, size_t n) { assert (s != NULL); assert (n >= 1 && n <= SNAPSHOTI_SPMC_MAX_READER); @@ -369,9 +384,9 @@ snapshot_mrsw_int_init(snapshot_mrsw_int_t s, size_t n) SNAPSHOTI_SPMC_INT_CONTRACT(s); } -/* Clear snapshot_mrsw_int_t (destructor) */ +/* Clear snapshot_mrsw_int_ct (destructor) */ static inline void -snapshot_mrsw_int_clear(snapshot_mrsw_int_t s) +snapshot_mrsw_int_clear(snapshot_mrsw_int_ct s) { SNAPSHOTI_SPMC_INT_CONTRACT(s); M_MEMORY_FREE (s->cptTab); @@ -382,7 +397,7 @@ snapshot_mrsw_int_clear(snapshot_mrsw_int_t s) /* Return the current index that is written in the buffer */ static inline unsigned int -snapshot_mrsw_int_get_write_idx(snapshot_mrsw_int_t s) +snapshot_mrsw_int_get_write_idx(snapshot_mrsw_int_ct s) { SNAPSHOTI_SPMC_INT_CONTRACT(s); return s->currentWrite; @@ -390,7 +405,7 @@ snapshot_mrsw_int_get_write_idx(snapshot_mrsw_int_t s) /* Return the number of readers */ static inline unsigned int -snapshot_mrsw_int_size(snapshot_mrsw_int_t s) +snapshot_mrsw_int_size(snapshot_mrsw_int_ct s) { SNAPSHOTI_SPMC_INT_CONTRACT(s); return (unsigned int) s->n_reader; @@ -399,7 +414,7 @@ snapshot_mrsw_int_size(snapshot_mrsw_int_t s) /* Give the current index that is written to the readers, and return new available index for writter */ static inline unsigned int -snapshot_mrsw_int_write_idx(snapshot_mrsw_int_t s, unsigned int idx) +snapshot_mrsw_int_write_idx(snapshot_mrsw_int_ct s, unsigned int idx) { SNAPSHOTI_SPMC_INT_CONTRACT(s); @@ -441,7 +456,7 @@ snapshot_mrsw_int_write_idx(snapshot_mrsw_int_t s, unsigned int idx) /* Perform a swap of the current write buffer and return a new one */ static inline unsigned int -snapshot_mrsw_int_write(snapshot_mrsw_int_t s) +snapshot_mrsw_int_write(snapshot_mrsw_int_ct s) { s->currentWrite = snapshot_mrsw_int_write_idx(s, s->currentWrite); SNAPSHOTI_SPMC_INT_CONTRACT(s); @@ -450,7 +465,7 @@ snapshot_mrsw_int_write(snapshot_mrsw_int_t s) /* Start writing to the write buffer and return its index */ static inline unsigned int -snapshot_mrsw_int_write_start(snapshot_mrsw_int_t s) +snapshot_mrsw_int_write_start(snapshot_mrsw_int_ct s) { SNAPSHOTI_SPMC_INT_CONTRACT(s); // Get a new buffer. @@ -465,7 +480,7 @@ snapshot_mrsw_int_write_start(snapshot_mrsw_int_t s) /* End writing to the given write buffer */ static inline void -snapshot_mrsw_int_write_end(snapshot_mrsw_int_t s, unsigned int idx) +snapshot_mrsw_int_write_end(snapshot_mrsw_int_ct s, unsigned int idx) { SNAPSHOTI_SPMC_INT_CONTRACT(s); @@ -487,7 +502,7 @@ snapshot_mrsw_int_write_end(snapshot_mrsw_int_t s, unsigned int idx) /* Start reading the latest written buffer and return the index to it */ static inline unsigned int -snapshot_mrsw_int_read_start(snapshot_mrsw_int_t s) +snapshot_mrsw_int_read_start(snapshot_mrsw_int_ct s) { SNAPSHOTI_SPMC_INT_CONTRACT(s); unsigned int idx, previous; @@ -530,7 +545,7 @@ snapshot_mrsw_int_read_start(snapshot_mrsw_int_t s) /* End the reading the given buffer */ static inline void -snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) +snapshot_mrsw_int_read_end(snapshot_mrsw_int_ct s, unsigned int idx) { SNAPSHOTI_SPMC_INT_CONTRACT(s); assert (idx < s->n_reader + SNAPSHOTI_SPMC_EXTRA_BUFFER); @@ -546,7 +561,7 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) } /* Contract of a SPMC snapshot. - Nothing notable */ + Nothing notable as it can be accessed concurrently */ #define SNAPSHOTI_SPMC_CONTRACT(snap) do { \ assert (snap != NULL); \ assert (snap->data != NULL); \ @@ -557,14 +572,15 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) #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) \ - M_IF_OPLIST(oplist)(SNAPSHOTI_SPMC_DEF_P3, SNAPSHOTI_SPMC_DEF_FAILURE)(name, type, oplist) +#define SNAPSHOTI_SPMC_DEF_P2(name, type, oplist, snapshot_t) \ + M_IF_OPLIST(oplist)(SNAPSHOTI_SPMC_DEF_P3, SNAPSHOTI_SPMC_DEF_FAILURE)(name, type, oplist, snapshot_t) /* Stop processing with a compilation failure */ -#define SNAPSHOTI_SPMC_DEF_FAILURE(name, type, oplist) \ +#define SNAPSHOTI_SPMC_DEF_FAILURE(name, type, oplist, snapshot_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(SNAPSHOT_SPMC_DEF): the given argument is not a valid oplist: " #oplist) -#define SNAPSHOTI_SPMC_DEF_P3(name, type, oplist) \ +/* Expand the type and the functions of a SPMC snapshot */ +#define SNAPSHOTI_SPMC_DEF_P3(name, type, oplist, snapshot_t) \ \ /* Create an aligned type to avoid false sharing between threads */ \ typedef struct M_C(name, _aligned_type_s) { \ @@ -574,14 +590,17 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) \ typedef struct M_C(name, _s) { \ M_C(name, _aligned_type_t) *data; \ - snapshot_mrsw_int_t core; \ - } M_C(name, _t)[1]; \ + snapshot_mrsw_int_ct core; \ + } snapshot_t[1]; \ \ - typedef type M_C(name, _type_t); \ + /* Define internal types for oplist */ \ + typedef snapshot_t M_C(name, _ct); \ + typedef type M_C(name, _subtype_ct); \ \ M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \ \ - static inline void M_C(name, _init)(M_C(name, _t) snap, size_t nReader) \ + static inline void \ + M_C(name, _init)(snapshot_t snap, size_t nReader) \ { \ assert (snap != NULL); \ assert (nReader > 0 && nReader <= SNAPSHOTI_SPMC_MAX_READER); \ @@ -599,7 +618,8 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) SNAPSHOTI_SPMC_CONTRACT(snap); \ } \ \ - static inline void M_C(name, _clear)(M_C(name, _t) snap) \ + static inline void \ + M_C(name, _clear)(snapshot_t snap) \ { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ size_t nReader = snapshot_mrsw_int_size(snap->core); \ @@ -610,21 +630,24 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) snapshot_mrsw_int_clear(snap->core); \ } \ \ - static inline type *M_C(name, _write)(M_C(name, _t) snap) \ + static inline type * \ + M_C(name, _write)(snapshot_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)(snapshot_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) \ + static inline void \ + M_C(name, _read_end)(snapshot_t snap, type const *old) \ { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ assert (old != NULL); \ @@ -637,7 +660,8 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) 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)(snapshot_t snap) \ { \ SNAPSHOTI_SPMC_CONTRACT(snap); \ const unsigned int idx = snapshot_mrsw_int_get_write_idx(snap->core); \ @@ -657,26 +681,30 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) #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) \ - M_IF_OPLIST(oplist)(SNAPSHOTI_MPMC_DEF_P3, SNAPSHOTI_MPMC_DEF_FAILURE)(name, type, oplist) +#define SNAPSHOTI_MPMC_DEF_P2(name, type, oplist, snapshot_t) \ + M_IF_OPLIST(oplist)(SNAPSHOTI_MPMC_DEF_P3, SNAPSHOTI_MPMC_DEF_FAILURE)(name, type, oplist, snapshot_t) /* Stop processing with a compilation failure */ -#define SNAPSHOTI_MPMC_DEF_FAILURE(name, type, oplist) \ +#define SNAPSHOTI_MPMC_DEF_FAILURE(name, type, oplist, snapshot_t) \ M_STATIC_FAILURE(M_LIB_NOT_AN_OPLIST, "(SNAPSHOT_MPMC_DEF): the given argument is not a valid oplist: " #oplist) -#define SNAPSHOTI_MPMC_DEF_P3(name, type, oplist) \ +/* Expand the type and the functions of a MPMC snapshot */ +#define SNAPSHOTI_MPMC_DEF_P3(name, type, oplist, snapshot_t) \ \ - SNAPSHOTI_SPMC_DEF_P1((M_C(name, _mrsw), type, oplist)) \ + SNAPSHOTI_SPMC_DEF_P1((M_C(name, _mrsw), type, oplist, M_C(name, _mrsw_pct))) \ \ typedef struct M_C(name, _s) { \ - M_C(name, _mrsw_t) core; \ - } M_C(name, _t)[1]; \ + M_C(name, _mrsw_pct) core; \ + } snapshot_t[1]; \ \ - typedef type M_C(name, _type_t); \ + /* Define internal types for oplist */ \ + typedef snapshot_t M_C(name, _ct); \ + typedef type M_C(name, _subtype_ct); \ \ 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) \ + static inline void \ + M_C(name, _init)(snapshot_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; \ @@ -684,19 +712,22 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) 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)(snapshot_t snap) \ { \ M_C(name, _mrsw_clear)(snap->core); \ } \ \ - static inline type *M_C(name, _write_start)(M_C(name, _t) snap) \ + static inline type * \ + M_C(name, _write_start)(snapshot_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) \ + static inline void \ + M_C(name, _write_end)(snapshot_t snap, type *old) \ { \ SNAPSHOTI_SPMC_CONTRACT(snap->core); \ const M_C(name, _mrsw_aligned_type_t) *oldx; \ @@ -708,12 +739,14 @@ snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned int idx) 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)(snapshot_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) \ + static inline void \ + M_C(name, _read_end)(snapshot_t snap, type const *old) \ { \ M_C(name, _mrsw_read_end)(snap->core, old); \ } \ diff --git a/m-string.h b/m-string.h index eaf809c0..dbbb8873 100644 --- a/m-string.h +++ b/m-string.h @@ -1761,26 +1761,58 @@ namespace m_string { /* */ /***********************************************************************/ +/* Define a bounded (fixed) string of exactly 'max_size' characters + * (excluding the final nul char). + */ +#define BOUNDED_STRING_DEF(name, max_size) \ + M_BEGIN_PROTECTED_CODE \ + BOUNDED_STRING_DEF_P2(name, max_size, M_C(name, _t) ) \ + M_END_PROTECTED_CODE + +/* Define the OPLIST of a BOUNDED_STRING */ +#define BOUNDED_STRING_OPLIST(name) \ + (INIT(M_C(name,_init)), \ + INIT_SET(M_C(name,_init_set)), \ + SET(M_C(name,_set)), \ + CLEAR(M_C(name,_clear)), \ + HASH(M_C(name,_hash)), \ + EQUAL(M_C(name,_equal_p)), \ + CMP(M_C(name,_cmp)), \ + TYPE(M_C(name,_ct)), \ + OOR_EQUAL(M_C(name,_oor_equal_p)), \ + OOR_SET(M_C(name, _oor_set)), \ + PARSE_STR(M_C(name,_parse_str)), \ + GET_STR(M_C(name,_get_str)), \ + OUT_STR(M_C(name,_out_str)), \ + IN_STR(M_C(name,_in_str)), \ + OUT_SERIAL(M_C(name,_out_serial)), \ + IN_SERIAL(M_C(name,_in_serial)), \ + ) + +/************************** INTERNAL ***********************************/ + +/* Contract of a bounded string. + * A bounded string last characters is always zero. */ #define BOUNDED_STRINGI_CONTRACT(var, max_size) do { \ assert(var != NULL); \ assert(var->s[max_size] == 0); \ } while (0) -#define BOUNDED_STRING_DEF(name, max_size) \ - M_BEGIN_PROTECTED_CODE \ - BOUNDED_STRING_DEF_P2(name, max_size) \ - M_END_PROTECTED_CODE - - -#define BOUNDED_STRING_DEF_P2(name, max_size) \ +/* Expand the functions for a bounded string */ +#define BOUNDED_STRING_DEF_P2(name, max_size, bounded_t) \ + \ + /* Define of an array with one more to store the final nul char */ \ typedef char M_C(name, _array_t)[max_size+1]; \ \ typedef struct M_C(name, _s) { \ char s[max_size+1]; \ - } M_C(name,_t)[1]; \ + } bounded_t[1]; \ + \ + /* Internal types for oplist */ \ + typedef bounded_t M_C(name, _ct); \ \ static inline void \ - M_C(name, _init)(M_C(name,_t) s) \ + M_C(name, _init)(bounded_t s) \ { \ assert(s != NULL); \ assert(max_size >= 1); \ @@ -1790,7 +1822,7 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _clear)(M_C(name,_t) s) \ + M_C(name, _clear)(bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ /* nothing to do */ \ @@ -1798,21 +1830,21 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _clean)(M_C(name,_t) s) \ + M_C(name, _clean)(bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ s->s[0] = 0; \ } \ \ static inline size_t \ - M_C(name, _size)(const M_C(name,_t) s) \ + M_C(name, _size)(const bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ return strlen(s->s); \ } \ \ static inline size_t \ - M_C(name, _capacity)(const M_C(name,_t) s) \ + M_C(name, _capacity)(const bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ (void)s; /* unused */ \ @@ -1820,7 +1852,7 @@ namespace m_string { } \ \ static inline char \ - M_C(name, _get_char)(const M_C(name,_t) s, size_t index) \ + M_C(name, _get_char)(const bounded_t s, size_t index) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(index < max_size); \ @@ -1828,14 +1860,14 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _empty_p)(const M_C(name,_t) s) \ + M_C(name, _empty_p)(const bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ return s->s[0] == 0; \ } \ \ static inline void \ - M_C(name, _set_str)(M_C(name,_t) s, const char str[]) \ + M_C(name, _set_str)(bounded_t s, const char str[]) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ m_core_strncpy(s->s, str, max_size); \ @@ -1843,7 +1875,7 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _set_strn)(M_C(name,_t) s, const char str[], size_t n) \ + M_C(name, _set_strn)(bounded_t s, const char str[], size_t n) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(str != NULL); \ @@ -1854,14 +1886,14 @@ namespace m_string { } \ \ static inline const char * \ - M_C(name, _get_cstr)(const M_C(name,_t) s) \ + M_C(name, _get_cstr)(const bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ return s->s; \ } \ \ static inline void \ - M_C(name, _set)(M_C(name,_t) s, const M_C(name,_t) str) \ + M_C(name, _set)(bounded_t s, const bounded_t str) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ BOUNDED_STRINGI_CONTRACT(str, max_size); \ @@ -1869,7 +1901,7 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _set_n)(M_C(name,_t) s, const M_C(name,_t) str, \ + M_C(name, _set_n)(bounded_t s, const bounded_t str, \ size_t offset, size_t length) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ @@ -1879,21 +1911,21 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _init_set)(M_C(name,_t) s, const M_C(name,_t) str) \ + M_C(name, _init_set)(bounded_t s, const bounded_t str) \ { \ M_C(name,_init)(s); \ M_C(name,_set)(s, str); \ } \ \ static inline void \ - M_C(name, _init_set_str)(M_C(name,_t) s, const char str[]) \ + M_C(name, _init_set_str)(bounded_t s, const char str[]) \ { \ M_C(name,_init)(s); \ M_C(name,_set_str)(s, str); \ } \ \ static inline void \ - M_C(name, _cat_str)(M_C(name,_t) s, const char str[]) \ + M_C(name, _cat_str)(bounded_t s, const char str[]) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert (str != NULL); \ @@ -1902,14 +1934,14 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _cat)(M_C(name,_t) s, const M_C(name,_t) str) \ + M_C(name, _cat)(bounded_t s, const bounded_t str) \ { \ BOUNDED_STRINGI_CONTRACT(str, max_size); \ M_C(name, _cat_str)(s, str->s); \ } \ \ static inline int \ - M_C(name, _cmp_str)(const M_C(name,_t) s, const char str[]) \ + M_C(name, _cmp_str)(const bounded_t s, const char str[]) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(str != NULL); \ @@ -1917,7 +1949,7 @@ namespace m_string { } \ \ static inline int \ - M_C(name, _cmp)(const M_C(name,_t) s, const M_C(name,_t) str) \ + M_C(name, _cmp)(const bounded_t s, const bounded_t str) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ BOUNDED_STRINGI_CONTRACT(str, max_size); \ @@ -1925,7 +1957,7 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _equal_str_p)(const M_C(name,_t) s, const char str[]) \ + M_C(name, _equal_str_p)(const bounded_t s, const char str[]) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(str != NULL); \ @@ -1933,14 +1965,14 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _equal_p)(const M_C(name,_t) s, const M_C(name,_t) str) \ + M_C(name, _equal_p)(const bounded_t s, const bounded_t str) \ { \ /* _equal_p may be called in context OOR. So contract cannot be verified */ \ return (s->s[max_size] == str->s[max_size]) & (strcmp(s->s, str->s) == 0); \ } \ \ static inline int \ - M_C(name, _printf)(M_C(name,_t) s, const char format[], ...) \ + M_C(name, _printf)(bounded_t s, const char format[], ...) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(format != NULL); \ @@ -1953,7 +1985,7 @@ namespace m_string { } \ \ static inline int \ - M_C(name, _cat_printf)(M_C(name,_t) s, const char format[], ...) \ + M_C(name, _cat_printf)(bounded_t s, const char format[], ...) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(format != NULL); \ @@ -1968,7 +2000,7 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _fgets)(M_C(name,_t)s, FILE *f, string_fgets_t arg) \ + M_C(name, _fgets)(bounded_t s, FILE *f, string_fgets_t arg) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(f != NULL); \ @@ -1984,7 +2016,7 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _fputs)(FILE *f, const M_C(name,_t) s) \ + M_C(name, _fputs)(FILE *f, const bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(f != NULL); \ @@ -1992,7 +2024,7 @@ namespace m_string { } \ \ static inline size_t \ - M_C(name, _hash)(const M_C(name,_t) s) \ + M_C(name, _hash)(const bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ /* Cannot use m_core_hash: alignment not sufficent */ \ @@ -2006,7 +2038,7 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _oor_equal_p)(const M_C(name,_t) s, unsigned char n) \ + M_C(name, _oor_equal_p)(const bounded_t s, unsigned char n) \ { \ /* s may be invalid contract */ \ assert (s != NULL); \ @@ -2015,7 +2047,7 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _oor_set)(M_C(name,_t) s, unsigned char n) \ + M_C(name, _oor_set)(bounded_t s, unsigned char n) \ { \ /* s may be invalid contract */ \ assert (s != NULL); \ @@ -2024,7 +2056,7 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _get_str)(string_t v, const M_C(name,_t) s, bool append) \ + M_C(name, _get_str)(string_t v, const bounded_t s, bool append) \ { \ STRINGI_CONTRACT(v); \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ @@ -2038,7 +2070,7 @@ namespace m_string { } \ \ static inline void \ - M_C(name, _out_str)(FILE *f, const M_C(name,_t) s) \ + M_C(name, _out_str)(FILE *f, const bounded_t s) \ { \ BOUNDED_STRINGI_CONTRACT(s, max_size); \ assert(f != NULL); \ @@ -2052,7 +2084,7 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _in_str)(M_C(name,_t) v, FILE *f) \ + M_C(name, _in_str)(bounded_t v, FILE *f) \ { \ BOUNDED_STRINGI_CONTRACT(v, max_size); \ assert(f != NULL); \ @@ -2065,7 +2097,7 @@ namespace m_string { } \ \ static inline bool \ - M_C(name, _parse_str)(M_C(name,_t) v, const char str[], const char **endptr) \ + M_C(name, _parse_str)(bounded_t v, const char str[], const char **endptr) \ { \ BOUNDED_STRINGI_CONTRACT(v, max_size); \ assert(str != NULL); \ @@ -2078,7 +2110,7 @@ namespace m_string { } \ \ static inline m_serial_return_code_t \ - M_C(name, _out_serial)(m_serial_write_t serial, const M_C(name,_t) v) \ + M_C(name, _out_serial)(m_serial_write_t serial, const bounded_t v) \ { \ BOUNDED_STRINGI_CONTRACT(v, max_size); \ assert (serial != NULL && serial->m_interface != NULL); \ @@ -2086,7 +2118,7 @@ namespace m_string { } \ \ static inline m_serial_return_code_t \ - M_C(name, _in_serial)(M_C(name,_t) v, m_serial_read_t serial) \ + M_C(name, _in_serial)(bounded_t v, m_serial_read_t serial) \ { \ BOUNDED_STRINGI_CONTRACT(v, max_size); \ assert (serial != NULL && serial->m_interface != NULL); \ @@ -2101,16 +2133,6 @@ namespace m_string { } -/* Define the OPLIST of a BOUNDED_STRING */ -#define BOUNDED_STRING_OPLIST(name) \ - (INIT(M_C(name,_init)), INIT_SET(M_C(name,_init_set)), \ - SET(M_C(name,_set)), CLEAR(M_C(name,_clear)), HASH(M_C(name,_hash)), \ - EQUAL(M_C(name,_equal_p)), CMP(M_C(name,_cmp)), TYPE(M_C(name,_t)), \ - OOR_EQUAL(M_C(name,_oor_equal_p)), OOR_SET(M_C(name, _oor_set)) \ - PARSE_STR(M_C(name,_parse_str)), GET_STR(M_C(name,_get_str)), \ - OUT_STR(M_C(name,_out_str)), IN_STR(M_C(name,_in_str)), \ - OUT_SERIAL(M_C(name,_out_serial)), IN_SERIAL(M_C(name,_in_serial)), \ - ) /* Init a constant bounded string. Try to do a clean cast */ diff --git a/m-tuple.h b/m-tuple.h index 5f1834a7..b3141b40 100644 --- a/m-tuple.h +++ b/m-tuple.h @@ -196,8 +196,11 @@ namespace m_tuple { typedef struct M_C(name, _s) { \ M_MAP(TUPLEI_DEFINE_RECUR_TYPE_ELE , __VA_ARGS__) \ } 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 const struct M_C(name, _s) *M_C(name, _srcptr); \ + /* Define internal type for oplist */ \ + typedef M_C(name, _t) M_C(name, _ct); #define TUPLEI_DEFINE_RECUR_TYPE_ELE(a) \ TUPLEI_GET_TYPE a TUPLEI_GET_FIELD a ; @@ -644,7 +647,7 @@ namespace m_tuple { INIT_WITH(M_C(name, _init_set2)), \ SET(M_C(name,_set)), \ CLEAR(M_C(name, _clear)), \ - TYPE(M_C(name,_t)), \ + TYPE(M_C(name,_ct)), \ M_IF_METHOD_ALL(CMP, __VA_ARGS__)(CMP(M_C(name, _cmp)),), \ M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_C(name, _hash)),), \ M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_C(name, _equal_p)),), \ diff --git a/m-variant.h b/m-variant.h index e68a7d08..bc3261bd 100644 --- a/m-variant.h +++ b/m-variant.h @@ -172,20 +172,26 @@ /* Define the type */ #define VARIANTI_DEFINE_TYPE(name, ...) \ + /* Define enum of all types of the variant */ \ enum M_C(name, _enum) { M_C(name, _EMPTY) \ M_MAP2(VARIANTI_DEFINE_UNION_ELE, name, __VA_ARGS__) \ }; \ + /* Define enum equal to the number of types of the variant */ \ enum M_C(name, _enum_max) { \ M_C(name, _MAX_TYPE) = M_NARGS(__VA_ARGS__) \ }; \ + /* Define the variant */ \ typedef struct M_C(name, _s) { \ enum M_C(name, _enum) type; \ union { \ M_MAP(VARIANTI_DEFINE_TYPE_ELE , __VA_ARGS__) \ } value; \ } 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 const struct M_C(name, _s) *M_C(name, _srcptr); \ + /* Define internal type for oplist */ \ + typedef M_C(name, _t) M_C(name, _ct); #define VARIANTI_DEFINE_UNION_ELE(name, a) \ , M_C4(name, _, VARIANTI_GET_FIELD a, _value) @@ -724,7 +730,7 @@ SET(M_C(name,_set)), \ CLEAR(M_C(name, _clear)), \ CLEAN(M_C(name, _clean)), \ - TYPE(M_C(name,_t)), \ + TYPE(M_C(name,_ct)), \ TEST_EMPTY(M_C(name,_empty_p)), \ M_IF_METHOD_ALL(HASH, __VA_ARGS__)(HASH(M_C(name, _hash)),), \ M_IF_METHOD_ALL(EQUAL, __VA_ARGS__)(EQUAL(M_C(name, _equal_p)),), \ diff --git a/m-worker.h b/m-worker.h index 42852155..bc84c324 100644 --- a/m-worker.h +++ b/m-worker.h @@ -106,7 +106,7 @@ typedef struct work_order_s { #if M_USE_WORKER_CPP_FUNCTION std::function function; // The work order function (for C++) #endif -} worker_order_t; +} worker_order_ct; /* Define the macros needed to initialize an order. * * MACRO to be used to send an empty order to stop the thread @@ -124,11 +124,11 @@ typedef struct work_order_s { is not sufficient for initialization of the structure. So let's use C++ constructor, destructor and copy constructor */ #if M_USE_WORKER_CPP_FUNCTION -# define WORKERI_CPP_INIT(x) (new (&(x)) worker_order_t()) -# define WORKERI_CPP_INIT_SET(x, y) (new (&(x)) worker_order_t(y)) +# define WORKERI_CPP_INIT(x) (new (&(x)) worker_order_ct()) +# define WORKERI_CPP_INIT_SET(x, y) (new (&(x)) worker_order_ct(y)) # define WORKERI_CPP_SET(x, y) ((x) = (y)) -# define WORKERI_CPP_CLEAR(x) ((&(x))->~worker_order_t()) -# define WORKERI_CPP_INIT_MOVE(x,y) (new (&(x)) worker_order_t(y), ((&(y))->~worker_order_t())) +# define WORKERI_CPP_CLEAR(x) ((&(x))->~worker_order_ct()) +# define WORKERI_CPP_INIT_MOVE(x,y) (new (&(x)) worker_order_ct(y), ((&(y))->~worker_order_ct())) # define WORKER_OPLIST \ (INIT(WORKERI_CPP_INIT), INIT_SET(WORKERI_CPP_INIT_SET), \ SET(WORKERI_CPP_SET), CLEAR(WORKERI_CPP_CLEAR), INIT_MOVE(WORKERI_CPP_INIT_MOVE) ) @@ -139,10 +139,10 @@ typedef struct work_order_s { /* Definition of a worker (implemented by a thread) */ typedef struct worker_thread_s { m_thread_t id; -} worker_thread_t; +} worker_thread_ct; /* Definition of the queue that will record the work orders */ -BUFFER_DEF(worker_queue, worker_order_t, 0, +BUFFER_DEF(worker_queue, worker_order_ct, 0, BUFFER_QUEUE|BUFFER_UNBLOCKING_PUSH|BUFFER_BLOCKING_POP|BUFFER_THREAD_SAFE|BUFFER_DEFERRED_POP, WORKER_OPLIST) /* Definition the global pool of workers */ @@ -151,7 +151,7 @@ typedef struct worker_s { worker_queue_t queue_g; /* The table of available workers */ - worker_thread_t *worker; + worker_thread_ct *worker; /* Number of workers in the table */ unsigned int numWorker_g; @@ -163,7 +163,7 @@ typedef struct worker_s { void (*clearFunc_g)(void); m_mutex_t lock; - m_cond_t a_thread_ends; // A worker has ended + m_cond_t a_thread_ends; // EVENT: A worker has ended } worker_t[1]; @@ -207,7 +207,7 @@ workeri_get_cpu_count(void) /* Execute the registered work order **synchronously** */ static inline void -workeri_exec(worker_order_t *w) +workeri_exec(worker_order_ct *w) { assert (w!= NULL && w->block != NULL); WORKERI_DEBUG ("Starting thread with data %p\n", w->data); @@ -236,7 +236,7 @@ workeri_thread(void *arg) // Get back the given argument struct worker_s *g = M_ASSIGN_CAST(struct worker_s *, arg); while (true) { - worker_order_t w; + worker_order_ct w; // If needed, reset the global state of the worker if (g->resetFunc_g != NULL) { g->resetFunc_g(); @@ -282,9 +282,9 @@ worker_init(worker_t g, int numWorker, unsigned int extraQueue, void (*resetFunc // Initialization assert(numWorker > 0); size_t numWorker_st = (size_t) numWorker; - g->worker = M_MEMORY_REALLOC(worker_thread_t, NULL, numWorker_st); + g->worker = M_MEMORY_REALLOC(worker_thread_ct, NULL, numWorker_st); if (g->worker == NULL) { - M_MEMORY_FULL(sizeof (worker_thread_t) * numWorker_st); + M_MEMORY_FULL(sizeof (worker_thread_ct) * numWorker_st); return; } worker_queue_init(g->queue_g, numWorker_st + extraQueue); @@ -315,7 +315,7 @@ worker_clear(worker_t g) assert (worker_queue_empty_p (g->queue_g)); // Push the terminate order on the queue for(unsigned int i = 0; i < g->numWorker_g; i++) { - worker_order_t w = WORKERI_EMPTY_ORDER; + worker_order_ct w = WORKERI_EMPTY_ORDER; // Normaly all worker threads shall be waiting at this // stage, so all push won't block as the queue is empty. // But for robustness, let's wait. @@ -350,7 +350,7 @@ worker_start(worker_sync_t block, worker_t g) static inline void worker_spawn(worker_sync_t block, void (*func)(void *data), void *data) { - const worker_order_t w = { block, data, func WORKERI_EXTRA_ORDER }; + const worker_order_ct w = { block, data, func WORKERI_EXTRA_ORDER }; if (M_UNLIKELY (!worker_queue_full_p(block->worker->queue_g)) && worker_queue_push (block->worker->queue_g, w) == true) { WORKERI_DEBUG ("Sending data to thread: %p (block: %d / %d)\n", data, block->num_spawn, block->num_terminated_spawn); @@ -368,7 +368,7 @@ worker_spawn(worker_sync_t block, void (*func)(void *data), void *data) static inline void worker_spawn_block(worker_sync_t block, void (^func)(void *data), void *data) { - const worker_order_t w = { block, data, NULL, func }; + const worker_order_ct w = { block, data, NULL, func }; if (M_UNLIKELY (!worker_queue_full_p(block->worker->queue_g)) && worker_queue_push (block->worker->queue_g, w) == true) { WORKERI_DEBUG ("Sending data to thread as block: %p (block: %d / %d)\n", data, block->num_spawn, block->num_terminated_spawn); @@ -387,7 +387,7 @@ worker_spawn_block(worker_sync_t block, void (^func)(void *data), void *data) static inline void worker_spawn_function(worker_sync_t block, std::function func, void *data) { - const worker_order_t w = { block, data, NULL, func }; + const worker_order_ct w = { block, data, NULL, func }; if (M_UNLIKELY (!worker_queue_full_p(block->worker->queue_g)) && worker_queue_push (block->worker->queue_g, w) == true) { WORKERI_DEBUG ("Sending data to thread as block: %p (block: %d / %d)\n", data, block->num_spawn, block->num_terminated_spawn); @@ -429,7 +429,7 @@ worker_sync(worker_sync_t block) static inline void worker_flush(worker_t g) { - worker_order_t w; + worker_order_ct w; while (worker_queue_pop_blocking (&w, g->queue_g, false) == true) { workeri_exec(&w); worker_queue_pop_release(g->queue_g); diff --git a/tests/err b/tests/err new file mode 100644 index 00000000..e69de29b diff --git a/tests/test-msnapshot.c b/tests/test-msnapshot.c index f24ed67c..eb15bb4f 100644 --- a/tests/test-msnapshot.c +++ b/tests/test-msnapshot.c @@ -150,7 +150,7 @@ static void test_global(void) static void test_mrsw_int1(void) { - snapshot_mrsw_int_t idx; + snapshot_mrsw_int_ct idx; snapshot_mrsw_int_init(idx, 1); assert (snapshot_mrsw_int_get_write_idx(idx) == 1); @@ -180,7 +180,7 @@ static void test_mrsw_int1(void) static void test_mrsw_int2(void) { - snapshot_mrsw_int_t idx; + snapshot_mrsw_int_ct idx; snapshot_mrsw_int_init(idx, 2); assert (snapshot_mrsw_int_get_write_idx(idx) == 1);