Update comments
This commit is contained in:
1 parent
eb8b106f48
commit
b396b42808
9 files changed
+54
-17
No files matched your search
+2
-1
@@ -30,6 +30,7 @@
|
||||
See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=60932
|
||||
clang++ has no issue with this header but if someone includes
|
||||
atomic from C++, there is incompatibility between atomic & stdatomic.
|
||||
Moreover some compilers lack a working stdatomic header.
|
||||
GCC 4.9 doesn't have a working implementation of 'atomic'.
|
||||
APPLE Clang defines __GNUC__ to be only 4 despite having full support
|
||||
for atomic.
|
||||
@@ -149,7 +150,7 @@ using std::memory_order_seq_cst;
|
||||
Supports only up to 64-bits atomic (sizeof long long to be more precise).
|
||||
The locks are never properly cleared and remain active until
|
||||
the end of the program.
|
||||
We also assume that the call to the atomic_* interface is "clean".
|
||||
We also assume that the call to the atomic_* interface is "macro clean".
|
||||
*/
|
||||
#else
|
||||
|
||||
|
||||
+7
-3
@@ -294,7 +294,11 @@
|
||||
typedef key_t subtype_t; \
|
||||
) \
|
||||
\
|
||||
/* Node of a B+TREE */ \
|
||||
/* Define a Node of a B+TREE \
|
||||
* For a reason of simplicity, it allocates one more element than \
|
||||
* needed so that the code can push one more element in the node and \
|
||||
* then split the nodes (simplify the code) \
|
||||
*/ \
|
||||
typedef struct M_C(name, _node_s) { \
|
||||
int num; /* Abs=Number of keys. Sign <0 is leaf */ \
|
||||
key_t key[N+1]; /* We can temporary push one more key */ \
|
||||
@@ -319,13 +323,13 @@
|
||||
typedef value_t M_C(name, _value_ct); \
|
||||
typedef tree_t M_C(name, _ct); \
|
||||
\
|
||||
/* Parent Iterator */ \
|
||||
/* Define the Parent Tree Iterator */ \
|
||||
typedef struct M_C(name, _parent_it_s) { \
|
||||
int num; \
|
||||
node_t parent[BPTREEI_MAX_STACK]; \
|
||||
} pit_t[1]; \
|
||||
\
|
||||
/* Iterator */ \
|
||||
/* Define the Iterator */ \
|
||||
typedef struct M_C(name, _it_s) { \
|
||||
M_IF(isMap)(struct M_C(name, _pair_s) pair;,) \
|
||||
node_t node; \
|
||||
|
||||
+5
-3
@@ -148,7 +148,9 @@ 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); \
|
||||
/* Internal type used to unconst the buffer */ \
|
||||
typedef union { M_C(name, _srcptr) cptr; M_C(name, _ptr) ptr; } M_C(name, _uptr_ct); \
|
||||
/* Internal types used by the oplist */ \
|
||||
typedef type M_C(name, _subtype_ct); \
|
||||
typedef buffer_t M_C(name, _ct); \
|
||||
\
|
||||
@@ -263,7 +265,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
|
||||
M_C(name, _init_set)(buffer_t dest, const buffer_t src) \
|
||||
{ \
|
||||
/* unconst 'src', so that we can lock it (semantically it is const) */ \
|
||||
M_C(name, _uptr) vu; \
|
||||
M_C(name, _uptr_ct) vu; \
|
||||
vu.cptr = src; \
|
||||
M_C(name, _ptr) v = vu.ptr; \
|
||||
assert (dest != v); \
|
||||
@@ -307,7 +309,7 @@ M_C(name, _init)(buffer_t v, size_t size) \
|
||||
M_C(name, _set)(buffer_t dest, const buffer_t src) \
|
||||
{ \
|
||||
/* unconst 'src', so that we can lock it (semantically it is const) */ \
|
||||
M_C(name, _uptr) vu; \
|
||||
M_C(name, _uptr_ct) vu; \
|
||||
vu.cptr = src; \
|
||||
M_C(name, _ptr) v = vu.ptr; \
|
||||
BUFFERI_CONTRACT(dest,m_size); \
|
||||
|
||||
@@ -143,6 +143,7 @@
|
||||
*/
|
||||
#define CONCURRENTI_DEF_P3(name, type, oplist, concurrent_t) \
|
||||
\
|
||||
/* Define a concurrent container using a lock */ \
|
||||
typedef struct M_C(name, _s) { \
|
||||
struct M_C(name, _s) *self; \
|
||||
m_mutex_t lock; \
|
||||
@@ -150,6 +151,7 @@
|
||||
type data; \
|
||||
} concurrent_t[1]; \
|
||||
\
|
||||
/* Define alias for pointer types */ \
|
||||
typedef struct M_C(name, _s) *M_C(name, _ptr); \
|
||||
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
|
||||
\
|
||||
@@ -157,6 +159,7 @@
|
||||
typedef concurrent_t M_C(name, _ct); \
|
||||
typedef type M_C(name, _subtype_ct); \
|
||||
\
|
||||
/* Don't define iterator as it cannot be reliable in a concurrent type */ \
|
||||
M_CHECK_COMPATIBLE_OPLIST(name, 1, type, oplist) \
|
||||
\
|
||||
/* Define the lock strategy (global & shared lock) */ \
|
||||
|
||||
@@ -114,7 +114,7 @@
|
||||
typedef struct M_C(name, _it2_s) { \
|
||||
node_t *node; \
|
||||
size_t index; \
|
||||
} M_C(name, _it2_t)[1]; \
|
||||
} M_C(name, _it2_ct)[1]; \
|
||||
\
|
||||
/* Define the deque type: \
|
||||
- 'list' if the list of buckets containing the objects. \
|
||||
@@ -124,15 +124,17 @@
|
||||
*/ \
|
||||
typedef struct M_C(name, _s) { \
|
||||
M_C(name, _node_list_t) list; \
|
||||
M_C(name, _it2_t) front; \
|
||||
M_C(name, _it2_t) back; \
|
||||
M_C(name, _it2_ct) front; \
|
||||
M_C(name, _it2_ct) back; \
|
||||
size_t default_size; \
|
||||
size_t count; \
|
||||
} deque_t[1]; \
|
||||
\
|
||||
/* Define pointer alias */ \
|
||||
typedef struct M_C(name, _s) *M_C(name, _ptr); \
|
||||
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
|
||||
\
|
||||
/* Define the iterator object */ \
|
||||
typedef struct M_C(name, _it_s) { \
|
||||
node_t *node; \
|
||||
size_t index; \
|
||||
|
||||
+1
-1
@@ -100,7 +100,7 @@ M_BEGIN_PROTECTED_CODE
|
||||
/* The shared pointer is only a pointer to the type */ \
|
||||
typedef type *shared_t; \
|
||||
\
|
||||
/* Define internal types for oplits */ \
|
||||
/* Define internal types for oplist */ \
|
||||
typedef shared_t M_C(name, _ct); \
|
||||
typedef type M_C(name, _subtype_ct); \
|
||||
\
|
||||
|
||||
+16
-1
@@ -59,17 +59,24 @@
|
||||
|
||||
#define MEMPOOL_DEF_P2(name, type, name_t) \
|
||||
\
|
||||
/* Define the type of element in a segment of the mempool. \
|
||||
Either it is the basic type or a pointer to another one. */ \
|
||||
typedef union M_C(name,_union_s) { \
|
||||
type t; \
|
||||
union M_C(name,_union_s) *next; \
|
||||
} M_C(name,_union_ct); \
|
||||
\
|
||||
/* Define a segment of a mempool. \
|
||||
It is an array of basic type, each segment is in a linked list */ \
|
||||
typedef struct M_C(name,_segment_s) { \
|
||||
unsigned int count; \
|
||||
struct M_C(name,_segment_s) *next; \
|
||||
M_C(name,_union_ct) tab[MEMPOOL_MAX_PER_SEGMENT(type)]; \
|
||||
} M_C(name,_segment_ct); \
|
||||
\
|
||||
/* Define a mempool. \
|
||||
It is a pointer to the first free object within the segments \
|
||||
and the segments themselves */ \
|
||||
typedef struct M_C(name, _s) { \
|
||||
M_C(name,_union_ct) *free_list; \
|
||||
M_C(name,_segment_ct) *current_segment; \
|
||||
@@ -108,14 +115,18 @@
|
||||
M_C(name,_alloc)(name_t mem) \
|
||||
{ \
|
||||
MEMPOOLI_CONTRACT(mem, type); \
|
||||
/* Test if one object is in the free list */ \
|
||||
M_C(name,_union_ct) *ret = mem->free_list; \
|
||||
if (ret != NULL) { \
|
||||
/* Yes, so return it, and pop it from the free list */ \
|
||||
mem->free_list = ret->next; \
|
||||
return &ret->t; \
|
||||
} \
|
||||
/* No cheap free object exist. Test within a segment */ \
|
||||
M_C(name,_segment_ct) *segment = mem->current_segment; \
|
||||
assert(segment != NULL); \
|
||||
unsigned int count = segment->count; \
|
||||
/* If segment is full, allocate a new one from the system */ \
|
||||
if (M_UNLIKELY (count >= MEMPOOL_MAX_PER_SEGMENT(type))) { \
|
||||
M_C(name,_segment_ct) *new_segment = M_MEMORY_ALLOC (M_C(name,_segment_ct)); \
|
||||
if (M_UNLIKELY (new_segment == NULL)) { \
|
||||
@@ -128,6 +139,7 @@
|
||||
segment = new_segment; \
|
||||
count = 0; \
|
||||
} \
|
||||
/* Return the object as the last element of the current segment */ \
|
||||
ret = &segment->tab[count]; \
|
||||
segment->count = count + 1; \
|
||||
MEMPOOLI_CONTRACT(mem, type); \
|
||||
@@ -141,12 +153,15 @@
|
||||
/* NOTE: Unsafe cast: suppose that the given pointer \
|
||||
was allocated by the previous alloc function. */ \
|
||||
M_C(name,_union_ct) *ret = (M_C(name,_union_ct) *)(uintptr_t)ptr; \
|
||||
/* Add the object back in the free list */ \
|
||||
ret->next = mem->free_list; \
|
||||
mem->free_list = ret; \
|
||||
/* NOTE: the objects are NOT given back to the system until the mempool \
|
||||
is fully cleared */ \
|
||||
MEMPOOLI_CONTRACT(mem, type); \
|
||||
} \
|
||||
|
||||
|
||||
/* MEMPOOL contract */
|
||||
#define MEMPOOLI_CONTRACT(mempool, type) do { \
|
||||
assert((mempool) != NULL); \
|
||||
assert((mempool)->current_segment != NULL); \
|
||||
|
||||
+14
-4
@@ -26,7 +26,7 @@
|
||||
#define MSTARLIB_PRIOQUEUE_H
|
||||
|
||||
#include "m-core.h"
|
||||
#include "m-array.h"
|
||||
#include "m-array.h" /* Priority queue are built upon array */
|
||||
|
||||
/* Priority queue based on binary heap implementation */
|
||||
|
||||
@@ -108,10 +108,11 @@
|
||||
/* Definition of the internal array used to construct the priority queue */ \
|
||||
ARRAY_DEF(M_C(name, _array), type, oplist) \
|
||||
\
|
||||
\
|
||||
/* Define the priority queue over the defined array */ \
|
||||
typedef struct M_C(name, _s) { \
|
||||
M_C(name, _array_t) array; \
|
||||
} prioqueue_t[1]; \
|
||||
/* Define the pointer references to the priority queue */ \
|
||||
typedef struct M_C(name, _s) *M_C(name, _ptr); \
|
||||
typedef const struct M_C(name, _s) *M_C(name, _srcptr); \
|
||||
\
|
||||
@@ -216,8 +217,11 @@
|
||||
static inline void \
|
||||
M_C(name, _push)(prioqueue_t p, type const x) \
|
||||
{ \
|
||||
/* Push back the new element at the end of the array */ \
|
||||
M_C(name, _array_push_back)(p->array, x); \
|
||||
\
|
||||
/* Reorder the array by swapping with its parent \
|
||||
* until it reaches the right position */ \
|
||||
size_t i = M_C(name, _array_size)(p->array)-1; \
|
||||
while (i > 0) { \
|
||||
size_t j = M_C(name, _i_parent)(i); \
|
||||
@@ -237,25 +241,31 @@
|
||||
static inline void \
|
||||
M_C(name, _pop)(type *x, prioqueue_t p) \
|
||||
{ \
|
||||
/* Swap the front element with the last element */ \
|
||||
size_t size = M_C(name, _array_size)(p->array)-1; \
|
||||
M_C(name, _array_swap_at) (p->array, 0, size); \
|
||||
/* Swap the new last element */ \
|
||||
M_C(name, _array_pop_back)(x, p->array); \
|
||||
\
|
||||
/* Reorder the heap */ \
|
||||
size_t i = 0; \
|
||||
while (true) { \
|
||||
size_t child = M_C(name, _i_lchild)(i); \
|
||||
if (child >= size) break; \
|
||||
if (child >= size) \
|
||||
break; \
|
||||
size_t otherChild = M_C(name, _i_rchild)(i); \
|
||||
if (otherChild < size \
|
||||
&& M_C(name, _i_cmp)(p, otherChild, child) < 0 ) { \
|
||||
child = otherChild; \
|
||||
} \
|
||||
if (M_C(name, _i_cmp)(p, i, child) <= 0) break; \
|
||||
if (M_C(name, _i_cmp)(p, i, child) <= 0) \
|
||||
break; \
|
||||
M_C(name, _array_swap_at) (p->array, i, child); \
|
||||
i = child; \
|
||||
} \
|
||||
} \
|
||||
\
|
||||
/* Define iterators over the array iterator */ \
|
||||
static inline void \
|
||||
M_C(name, _it)(it_t it, prioqueue_t const v) \
|
||||
{ \
|
||||
|
||||
+1
-1
@@ -176,7 +176,7 @@ typedef enum {
|
||||
rbtreei_color_e color; \
|
||||
} node_t; \
|
||||
\
|
||||
/* Red/Black tree */ \
|
||||
/* Define the Red/Black tree */ \
|
||||
typedef struct M_C(name, _s) { \
|
||||
size_t size; /* Number of elements in the tree */ \
|
||||
node_t *node; /* Root node of the tree */ \
|
||||
|
||||
Reference in new issue
Block a user