Add m_ prefix for GENINT module,

as it is purely internal (no need to prevent user space breakage).

It will put more stuff in the global m_ prefix
This commit is contained in:
Patrick Pelissier committed 2021-12-03 22:08:15 +01:00
1 parent d22c0b05ef
commit 50669a320c
5 files changed
+86 -88

No files matched your search

+6 -6
View File
@@ -574,9 +574,9 @@ typedef struct m_gc_lfmp_thread_s {
typedef struct m_gc_s { typedef struct m_gc_s {
m_gc_atomic_ticket_ct ticket; m_gc_atomic_ticket_ct ticket;
m_gc_tid_t max_thread; m_gc_tid_t max_thread;
genint_t thread_alloc; m_genint_t thread_alloc;
m_gc_lfmp_thread_ct *thread_data; m_gc_lfmp_thread_ct *thread_data;
m_gM_CMEMP00L_list_ct *mempool_list; m_gM_CMEMP00L_list_ct *mempool_list;
} m_gc_t[1]; } m_gc_t[1];
static inline void static inline void
@@ -586,7 +586,7 @@ m_gc_init(m_gc_t gc_mem, size_t max_thread)
M_ASSERT(max_thread > 0 && max_thread < INT_MAX); M_ASSERT(max_thread > 0 && max_thread < INT_MAX);
atomic_init(&gc_mem->ticket, 0UL); atomic_init(&gc_mem->ticket, 0UL);
genint_init(gc_mem->thread_alloc, (unsigned int) max_thread); m_genint_init(gc_mem->thread_alloc, (unsigned int) max_thread);
gc_mem->thread_data = M_MEMORY_REALLOC(m_gc_lfmp_thread_ct, NULL, max_thread); gc_mem->thread_data = M_MEMORY_REALLOC(m_gc_lfmp_thread_ct, NULL, max_thread);
if (gc_mem->thread_data == NULL) { if (gc_mem->thread_data == NULL) {
M_MEMORY_FULL(max_thread * sizeof(m_gc_lfmp_thread_ct)); M_MEMORY_FULL(max_thread * sizeof(m_gc_lfmp_thread_ct));
@@ -610,7 +610,7 @@ m_gc_clear(m_gc_t gc_mem)
} }
M_MEMORY_FREE(gc_mem->thread_data); M_MEMORY_FREE(gc_mem->thread_data);
gc_mem->thread_data = NULL; gc_mem->thread_data = NULL;
genint_clear(gc_mem->thread_alloc); m_genint_clear(gc_mem->thread_alloc);
} }
static inline m_gc_tid_t static inline m_gc_tid_t
@@ -618,7 +618,7 @@ m_gc_attach_thread(m_gc_t gc_mem)
{ {
M_ASSERT(gc_mem != NULL && gc_mem->max_thread > 0); M_ASSERT(gc_mem != NULL && gc_mem->max_thread > 0);
unsigned id = genint_pop(gc_mem->thread_alloc); unsigned id = m_genint_pop(gc_mem->thread_alloc);
return M_ASSIGN_CAST(m_gc_tid_t, id); return M_ASSIGN_CAST(m_gc_tid_t, id);
} }
@@ -629,7 +629,7 @@ m_gc_detach_thread(m_gc_t gc_mem, m_gc_tid_t id)
M_ASSERT(id < gc_mem->max_thread); M_ASSERT(id < gc_mem->max_thread);
M_ASSERT(atomic_load(&gc_mem->thread_data[id].ticket) == ULONG_MAX); M_ASSERT(atomic_load(&gc_mem->thread_data[id].ticket) == ULONG_MAX);
genint_push(gc_mem->thread_alloc, id); m_genint_push(gc_mem->thread_alloc, id);
} }
static inline void static inline void
+31 -33
View File
@@ -45,42 +45,40 @@ M_BEGIN_PROTECTED_CODE
enough. enough.
*/ */
// TO DO: We may want a specialization with constant N value.
// Define the limb size used by genint // Define the limb size used by genint
typedef unsigned long long genint_limb_ct; typedef unsigned long long m_genint_limb_ct;
/* Define a generator of unique integer (Lock Free) */ /* Define a generator of unique integer (Lock Free) */
typedef struct genint_s { typedef struct m_genint_s {
unsigned int n; // size of the container unsigned int n; // size of the container
unsigned int max; // number of allocated limb - 1 unsigned int max; // number of allocated limb - 1
genint_limb_ct mask0; // mask of the last limb (constant) m_genint_limb_ct mask0; // mask of the last limb (constant)
genint_limb_ct mask_master; // mask of the master limb that controls others (constant) m_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 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 atomic_ullong *data; // the bitfield which informs if an integer is used or not
} genint_t[1]; } m_genint_t[1];
// Define the max absolute supported value. It should be 2048 on most implementations. // Define the max absolute supported value. It should be 2048 on most implementations.
#define GENINT_MAX_ALLOC (M_GEN1NT_LIMBSIZE * (M_GEN1NT_LIMBSIZE - M_GEN1NT_ABA_CPT)) #define M_GENINT_MAX_ALLOC (M_GEN1NT_LIMBSIZE * (M_GEN1NT_LIMBSIZE - M_GEN1NT_ABA_CPT))
// Define the size of a limb in bits. // Define the size of a limb in bits.
#define M_GEN1NT_LIMBSIZE ((unsigned)(sizeof(genint_limb_ct) * CHAR_BIT)) #define M_GEN1NT_LIMBSIZE ((unsigned)(sizeof(m_genint_limb_ct) * CHAR_BIT))
// Define the contract of a genint // Define the contract of a genint
#define M_GEN1NT_CONTRACT(s) do { \ #define M_GEN1NT_CONTRACT(s) do { \
M_ASSERT (s != NULL); \ M_ASSERT (s != NULL); \
M_ASSERT (s->n > 0 && s->n <= GENINT_MAX_ALLOC); \ M_ASSERT (s->n > 0 && s->n <= M_GENINT_MAX_ALLOC); \
M_ASSERT ((s->max+1) * M_GEN1NT_LIMBSIZE >= s->n); \ M_ASSERT ((s->max+1) * M_GEN1NT_LIMBSIZE >= s->n); \
M_ASSERT (s->data != NULL); \ M_ASSERT (s->data != NULL); \
} while (0) } while (0)
// Define the limb one // Define the limb one
#define M_GEN1NT_ONE ((genint_limb_ct)1) #define M_GEN1NT_ONE ((m_genint_limb_ct)1)
#define M_GEN1NT_FULL_MASK ULLONG_MAX #define M_GEN1NT_FULL_MASK ULLONG_MAX
// Value returned in case of error (not integer available). // Value returned in case of error (not integer available).
#define GENINT_ERROR (UINT_MAX) #define M_GENINT_ERROR (UINT_MAX)
/* 32 bits of the master mask are kept for handling the ABA problem. /* 32 bits of the master mask are kept for handling the ABA problem.
* NOTE: May be too much. 16 bits should be more than enough. TBC * NOTE: May be too much. 16 bits should be more than enough. TBC
@@ -106,9 +104,9 @@ typedef struct genint_s {
* for all threads. * for all threads.
*/ */
static inline void static inline void
genint_init(genint_t s, unsigned int n) m_genint_init(m_genint_t s, unsigned int n)
{ {
M_ASSERT (s != NULL && n > 0 && n <= GENINT_MAX_ALLOC); M_ASSERT (s != NULL && n > 0 && n <= M_GENINT_MAX_ALLOC);
const size_t alloc = (n + M_GEN1NT_LIMBSIZE - 1) / M_GEN1NT_LIMBSIZE; const size_t alloc = (n + M_GEN1NT_LIMBSIZE - 1) / M_GEN1NT_LIMBSIZE;
const unsigned int index = n % M_GEN1NT_LIMBSIZE; const unsigned int index = n % M_GEN1NT_LIMBSIZE;
atomic_ullong *ptr = M_MEMORY_REALLOC (atomic_ullong, NULL, alloc); atomic_ullong *ptr = M_MEMORY_REALLOC (atomic_ullong, NULL, alloc);
@@ -121,15 +119,15 @@ genint_init(genint_t s, unsigned int n)
s->max = (unsigned int) (alloc-1); s->max = (unsigned int) (alloc-1);
s->mask0 = (index == 0) ? M_GEN1NT_FULL_MASK : ~((M_GEN1NT_ONE<<(M_GEN1NT_LIMBSIZE-index))-1); s->mask0 = (index == 0) ? M_GEN1NT_FULL_MASK : ~((M_GEN1NT_ONE<<(M_GEN1NT_LIMBSIZE-index))-1);
s->mask_master = (((M_GEN1NT_ONE << alloc) - 1) << (M_GEN1NT_LIMBSIZE-alloc)) >> M_GEN1NT_ABA_CPT; s->mask_master = (((M_GEN1NT_ONE << alloc) - 1) << (M_GEN1NT_LIMBSIZE-alloc)) >> M_GEN1NT_ABA_CPT;
atomic_init (&s->master, (genint_limb_ct)0); atomic_init (&s->master, (m_genint_limb_ct)0);
for(unsigned int i = 0; i < alloc; i++) for(unsigned int i = 0; i < alloc; i++)
atomic_init(&s->data[i], (genint_limb_ct)0); atomic_init(&s->data[i], (m_genint_limb_ct)0);
M_GEN1NT_CONTRACT(s); M_GEN1NT_CONTRACT(s);
} }
/* Clear an integer generator (Destructor) */ /* Clear an integer generator (Destructor) */
static inline void static inline void
genint_clear(genint_t s) m_genint_clear(m_genint_t s)
{ {
M_GEN1NT_CONTRACT(s); M_GEN1NT_CONTRACT(s);
M_MEMORY_FREE(s->data); M_MEMORY_FREE(s->data);
@@ -138,7 +136,7 @@ genint_clear(genint_t s)
/* Return the maximum integer that the generator will provide */ /* Return the maximum integer that the generator will provide */
static inline size_t static inline size_t
genint_size(genint_t s) m_genint_size(m_genint_t s)
{ {
M_GEN1NT_CONTRACT(s); M_GEN1NT_CONTRACT(s);
return s->n; return s->n;
@@ -147,22 +145,22 @@ genint_size(genint_t s)
/* Get an unique integer from the integer generator. /* Get an unique integer from the integer generator.
* NOTE: For a typical case, the amortized cost is one CAS per pop. */ * NOTE: For a typical case, the amortized cost is one CAS per pop. */
static inline unsigned int static inline unsigned int
genint_pop(genint_t s) m_genint_pop(m_genint_t s)
{ {
M_GEN1NT_CONTRACT(s); M_GEN1NT_CONTRACT(s);
// First read master to see which limb is not full. // First read master to see which limb is not full.
genint_limb_ct master = atomic_load(&s->master); m_genint_limb_ct master = atomic_load(&s->master);
// While master is not full // While master is not full
while ((master >> M_GEN1NT_ABA_CPT) != s->mask_master) { while ((master >> M_GEN1NT_ABA_CPT) != s->mask_master) {
// Let's get the index i of the first not full limb according to master. // Let's get the index i of the first not full limb according to master.
unsigned int i = m_core_clz64(~master); unsigned int i = m_core_clz64(~master);
M_ASSERT (i < M_GEN1NT_LIMBSIZE); M_ASSERT (i < M_GEN1NT_LIMBSIZE);
// Let's compute the mask of this limb representing the limb as being full // Let's compute the mask of this limb representing the limb as being full
genint_limb_ct mask = s->mask0; m_genint_limb_ct mask = s->mask0;
mask = (i == s->max) ? mask : M_GEN1NT_FULL_MASK; mask = (i == s->max) ? mask : M_GEN1NT_FULL_MASK;
unsigned int bit; unsigned int bit;
// Let's load this limb, // Let's load this limb,
genint_limb_ct next, org = atomic_load(&s->data[i]); m_genint_limb_ct next, org = atomic_load(&s->data[i]);
do { do {
// If it is now full, we have been preempted by another. // If it is now full, we have been preempted by another.
if (M_UNLIKELY (org == mask)) if (M_UNLIKELY (org == mask))
@@ -181,7 +179,7 @@ genint_pop(genint_t s)
// If the limb is now full, try to update master // If the limb is now full, try to update master
if (M_UNLIKELY(next == mask)) { if (M_UNLIKELY(next == mask)) {
while (true) { while (true) {
genint_limb_ct newMaster; m_genint_limb_ct newMaster;
if (next == mask) { if (next == mask) {
newMaster = M_GEN1NT_MASTER_SET(master, i); newMaster = M_GEN1NT_MASTER_SET(master, i);
} else { } else {
@@ -201,21 +199,21 @@ genint_pop(genint_t s)
master = atomic_load(&s->master); master = atomic_load(&s->master);
} }
M_GEN1NT_CONTRACT(s); M_GEN1NT_CONTRACT(s);
return GENINT_ERROR; // No more resource available return M_GENINT_ERROR; // No more resource available
} }
/* Restore a used integer in the integer generator. /* Restore a used integer in the integer generator.
* NOTE: For a typical case, the amortized cost is one CAS per pop */ * NOTE: For a typical case, the amortized cost is one CAS per pop */
static inline void static inline void
genint_push(genint_t s, unsigned int n) m_genint_push(m_genint_t s, unsigned int n)
{ {
M_GEN1NT_CONTRACT(s); M_GEN1NT_CONTRACT(s);
M_ASSERT (n < s->n); M_ASSERT (n < s->n);
const unsigned int i = n / M_GEN1NT_LIMBSIZE; const unsigned int i = n / M_GEN1NT_LIMBSIZE;
const unsigned int bit = M_GEN1NT_LIMBSIZE - 1 - (n % M_GEN1NT_LIMBSIZE); const unsigned int bit = M_GEN1NT_LIMBSIZE - 1 - (n % M_GEN1NT_LIMBSIZE);
genint_limb_ct master = atomic_load(&s->master); m_genint_limb_ct master = atomic_load(&s->master);
// Load the limb // Load the limb
genint_limb_ct next, org = atomic_load(&s->data[i]); m_genint_limb_ct next, org = atomic_load(&s->data[i]);
do { do {
M_ASSERT ((org & (M_GEN1NT_ONE << bit)) != 0); M_ASSERT ((org & (M_GEN1NT_ONE << bit)) != 0);
// Reset it // Reset it
@@ -223,13 +221,13 @@ genint_push(genint_t s, unsigned int n)
// Try to unreserve it. // Try to unreserve it.
} while (!atomic_compare_exchange_weak (&s->data[i], &org, next)); } while (!atomic_compare_exchange_weak (&s->data[i], &org, next));
// if the limb was marked as full by master // if the limb was marked as full by master
genint_limb_ct mask = s->mask0; m_genint_limb_ct mask = s->mask0;
mask = (i == s->max) ? mask : M_GEN1NT_FULL_MASK; mask = (i == s->max) ? mask : M_GEN1NT_FULL_MASK;
if (M_UNLIKELY (next != mask)) { if (M_UNLIKELY (next != mask)) {
// Let's compute the mask of this limb representing the limb as being full // 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 // Let's try to update master to say that this limb is not full
while (true) { while (true) {
genint_limb_ct newMaster; m_genint_limb_ct newMaster;
if (next == mask) { if (next == mask) {
newMaster = M_GEN1NT_MASTER_SET(master, i); newMaster = M_GEN1NT_MASTER_SET(master, i);
} else { } else {
+13 -13
View File
@@ -380,7 +380,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
} M_C(name, _atype_ct); \ } M_C(name, _atype_ct); \
\ \
typedef struct M_C(name, _s) { \ typedef struct M_C(name, _s) { \
genint_t core; \ m_genint_t core; \
M_C(name, _atype_ct) *buffer; \ M_C(name, _atype_ct) *buffer; \
} shared_t[1]; \ } shared_t[1]; \
\ \
@@ -406,7 +406,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
M_CALL_INIT(oplist, s->buffer[i].x); \ M_CALL_INIT(oplist, s->buffer[i].x); \
atomic_init (&s->buffer[i].cpt, 0U); \ atomic_init (&s->buffer[i].cpt, 0U); \
} \ } \
genint_init(s->core, (unsigned int) n); \ m_genint_init(s->core, (unsigned int) n); \
M_SHAR3D_RESOURCE_CONTRACT(s); \ M_SHAR3D_RESOURCE_CONTRACT(s); \
} \ } \
\ \
@@ -414,13 +414,13 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
M_C(name, _clear)(shared_t s) \ M_C(name, _clear)(shared_t s) \
{ \ { \
M_SHAR3D_RESOURCE_CONTRACT(s); \ M_SHAR3D_RESOURCE_CONTRACT(s); \
size_t n = genint_size(s->core); \ size_t n = m_genint_size(s->core); \
for(size_t i = 0; i < n; i++) { \ for(size_t i = 0; i < n; i++) { \
M_CALL_CLEAR(oplist, s->buffer[i].x); \ M_CALL_CLEAR(oplist, s->buffer[i].x); \
} \ } \
M_CALL_FREE(oplist, s->buffer); \ M_CALL_FREE(oplist, s->buffer); \
s->buffer = NULL; \ s->buffer = NULL; \
genint_clear(s->core); \ m_genint_clear(s->core); \
} \ } \
\ \
static inline void \ static inline void \
@@ -428,10 +428,10 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
{ \ { \
M_SHAR3D_RESOURCE_CONTRACT(s); \ M_SHAR3D_RESOURCE_CONTRACT(s); \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
unsigned int idx = genint_pop(s->core); \ unsigned int idx = m_genint_pop(s->core); \
it->idx = idx; \ it->idx = idx; \
it->ref = s; \ it->ref = s; \
if (M_LIKELY (idx != GENINT_ERROR)) { \ if (M_LIKELY (idx != M_GENINT_ERROR)) { \
M_ASSERT(atomic_load(&s->buffer[idx].cpt) == 0); \ M_ASSERT(atomic_load(&s->buffer[idx].cpt) == 0); \
atomic_store(&s->buffer[idx].cpt, 1U); \ atomic_store(&s->buffer[idx].cpt, 1U); \
} \ } \
@@ -441,13 +441,13 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
M_C(name, _end_p)(it_t it) \ M_C(name, _end_p)(it_t it) \
{ \ { \
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
return it->idx == GENINT_ERROR; \ return it->idx == M_GENINT_ERROR; \
} \ } \
\ \
static inline type * \ static inline type * \
M_C(name, _ref)(it_t it) \ M_C(name, _ref)(it_t it) \
{ \ { \
M_ASSERT (it != NULL && it->ref != NULL && it->idx != GENINT_ERROR); \ M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \
M_SHAR3D_RESOURCE_CONTRACT(it->ref); \ M_SHAR3D_RESOURCE_CONTRACT(it->ref); \
return &it->ref->buffer[it->idx].x; \ return &it->ref->buffer[it->idx].x; \
} \ } \
@@ -455,7 +455,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
static inline type const * \ static inline type const * \
M_C(name, _cref)(it_t it) \ M_C(name, _cref)(it_t it) \
{ \ { \
M_ASSERT (it != NULL && it->ref != NULL && it->idx != GENINT_ERROR); \ M_ASSERT (it != NULL && it->ref != NULL && it->idx != M_GENINT_ERROR); \
M_SHAR3D_RESOURCE_CONTRACT(it->ref); \ M_SHAR3D_RESOURCE_CONTRACT(it->ref); \
return M_CONST_CAST (type, &it->ref->buffer[it->idx].x); \ return M_CONST_CAST (type, &it->ref->buffer[it->idx].x); \
} \ } \
@@ -467,12 +467,12 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
M_ASSERT (it != NULL); \ M_ASSERT (it != NULL); \
M_ASSERT (it->ref == s); \ M_ASSERT (it->ref == s); \
unsigned int idx = it->idx; \ unsigned int idx = it->idx; \
if (M_LIKELY (idx != GENINT_ERROR)) { \ if (M_LIKELY (idx != M_GENINT_ERROR)) { \
unsigned int c = atomic_fetch_sub (&it->ref->buffer[idx].cpt, 1U); \ unsigned int c = atomic_fetch_sub (&it->ref->buffer[idx].cpt, 1U); \
if (c == 1) { \ if (c == 1) { \
genint_push(it->ref->core, idx); \ m_genint_push(it->ref->core, idx); \
} \ } \
it->idx = GENINT_ERROR; \ it->idx = M_GENINT_ERROR; \
} \ } \
} \ } \
\ \
@@ -484,7 +484,7 @@ static inline int m_shar3d_integer_cref(int *p) { return *p; }
itd->ref = its->ref; \ itd->ref = its->ref; \
unsigned int idx = its->idx; \ unsigned int idx = its->idx; \
itd->idx = idx; \ itd->idx = idx; \
if (M_LIKELY (idx != GENINT_ERROR)) { \ if (M_LIKELY (idx != M_GENINT_ERROR)) { \
unsigned int c = atomic_fetch_add(&itd->ref->buffer[idx].cpt, 1U); \ unsigned int c = atomic_fetch_add(&itd->ref->buffer[idx].cpt, 1U); \
M_ASSERT (c >= 1); \ M_ASSERT (c >= 1); \
} \ } \
+16 -16
View File
@@ -347,7 +347,7 @@ M_BEGIN_PROTECTED_CODE
// 2 more buffer than the number of readers are needed // 2 more buffer than the number of readers are needed
#define M_SNAPSH0T_SPMC_EXTRA_BUFFER 2 #define M_SNAPSH0T_SPMC_EXTRA_BUFFER 2
#define M_SNAPSH0T_SPMC_MAX_READER (GENINT_MAX_ALLOC-M_SNAPSH0T_SPMC_EXTRA_BUFFER) #define M_SNAPSH0T_SPMC_MAX_READER (M_GENINT_MAX_ALLOC-M_SNAPSH0T_SPMC_EXTRA_BUFFER)
/* Internal 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 M_SNAPSH0T_SPMC_INT_FLAG) - lastNext: last published written index + next flag (format M_SNAPSH0T_SPMC_INT_FLAG)
@@ -361,7 +361,7 @@ typedef struct m_snapshot_mrsw_s {
unsigned int currentWrite; unsigned int currentWrite;
size_t n_reader; size_t n_reader;
atomic_uint *cptTab; atomic_uint *cptTab;
genint_t freeList; m_genint_t freeList;
} m_snapshot_mrsw_ct[1]; } m_snapshot_mrsw_ct[1];
// can't check currentWrite due to potential data race on it // can't check currentWrite due to potential data race on it
@@ -391,17 +391,17 @@ m_snapsh0t_mrsw_init(m_snapshot_mrsw_ct s, size_t n)
s->cptTab = ptr; s->cptTab = ptr;
for(size_t i = 0; i < n; i++) for(size_t i = 0; i < n; i++)
atomic_init(&s->cptTab[i], 0U); atomic_init(&s->cptTab[i], 0U);
genint_init (s->freeList, (unsigned int) n); m_genint_init (s->freeList, (unsigned int) n);
// Get a free buffer and set it as available for readers // Get a free buffer and set it as available for readers
unsigned int w = genint_pop(s->freeList); unsigned int w = m_genint_pop(s->freeList);
M_ASSERT (w != GENINT_ERROR); M_ASSERT (w != M_GENINT_ERROR);
atomic_store(&s->cptTab[w], 1U); atomic_store(&s->cptTab[w], 1U);
atomic_init(&s->lastNext, M_SNAPSH0T_SPMC_INT_FLAG(w, true)); atomic_init(&s->lastNext, M_SNAPSH0T_SPMC_INT_FLAG(w, true));
// Get working buffer // Get working buffer
s->currentWrite = genint_pop(s->freeList); s->currentWrite = m_genint_pop(s->freeList);
M_ASSERT (s->currentWrite != GENINT_ERROR); M_ASSERT (s->currentWrite != M_GENINT_ERROR);
atomic_store(&s->cptTab[s->currentWrite], 1U); atomic_store(&s->cptTab[s->currentWrite], 1U);
M_SNAPSH0T_SPMC_INT_CONTRACT(s); M_SNAPSH0T_SPMC_INT_CONTRACT(s);
} }
@@ -412,7 +412,7 @@ m_snapsh0t_mrsw_clear(m_snapshot_mrsw_ct s)
{ {
M_SNAPSH0T_SPMC_INT_CONTRACT(s); M_SNAPSH0T_SPMC_INT_CONTRACT(s);
M_MEMORY_FREE (s->cptTab); M_MEMORY_FREE (s->cptTab);
genint_clear(s->freeList); m_genint_clear(s->freeList);
s->cptTab = NULL; s->cptTab = NULL;
s->n_reader = 0; s->n_reader = 0;
} }
@@ -462,8 +462,8 @@ m_snapsh0t_mrsw_write_idx(m_snapshot_mrsw_ct s, unsigned int idx)
if (c != 1) { if (c != 1) {
// If someone else keeps a ref on the buffer, we can't reuse it // If someone else keeps a ref on the buffer, we can't reuse it
// get another free one. // get another free one.
idx = genint_pop(s->freeList); idx = m_genint_pop(s->freeList);
M_ASSERT(idx != GENINT_ERROR); M_ASSERT(idx != M_GENINT_ERROR);
} else { } else {
// No other thread keep track of this buffer. // No other thread keep track of this buffer.
// Reuse it. // Reuse it.
@@ -491,8 +491,8 @@ m_snapsh0t_mrsw_write_start(m_snapshot_mrsw_ct s)
{ {
M_SNAPSH0T_SPMC_INT_CONTRACT(s); M_SNAPSH0T_SPMC_INT_CONTRACT(s);
// Get a new buffer. // Get a new buffer.
unsigned int idx = genint_pop(s->freeList); unsigned int idx = m_genint_pop(s->freeList);
M_ASSERT (idx != GENINT_ERROR); M_ASSERT (idx != M_GENINT_ERROR);
M_ASSERT (idx < s->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER); M_ASSERT (idx < s->n_reader + M_SNAPSH0T_SPMC_EXTRA_BUFFER);
M_ASSERT (atomic_load(&s->cptTab[idx]) == 0); M_ASSERT (atomic_load(&s->cptTab[idx]) == 0);
atomic_store(&s->cptTab[idx], 1U); atomic_store(&s->cptTab[idx], 1U);
@@ -517,7 +517,7 @@ m_snapsh0t_mrsw_write_end(m_snapshot_mrsw_ct s, unsigned int idx)
unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1U); unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1U);
M_ASSERT (c != 0 && c <= s->n_reader + 1); M_ASSERT (c != 0 && c <= s->n_reader + 1);
if (c == 1) { if (c == 1) {
genint_push(s->freeList, idx); m_genint_push(s->freeList, idx);
} }
M_SNAPSH0T_SPMC_INT_CONTRACT(s); M_SNAPSH0T_SPMC_INT_CONTRACT(s);
} }
@@ -558,7 +558,7 @@ m_snapsh0t_mrsw_read_start(m_snapshot_mrsw_ct s)
c = atomic_fetch_sub(&s->cptTab[idx], 1U); c = atomic_fetch_sub(&s->cptTab[idx], 1U);
M_ASSERT (c != 0 && c <= s->n_reader + 1); M_ASSERT (c != 0 && c <= s->n_reader + 1);
if (c == 1) { if (c == 1) {
genint_push(s->freeList, idx); m_genint_push(s->freeList, idx);
} }
} }
M_SNAPSH0T_SPMC_INT_CONTRACT(s); M_SNAPSH0T_SPMC_INT_CONTRACT(s);
@@ -577,7 +577,7 @@ m_snapsh0t_mrsw_read_end(m_snapshot_mrsw_ct s, unsigned int idx)
if (c == 1) { if (c == 1) {
// Buffer no longer used by any reader thread. // Buffer no longer used by any reader thread.
// Push back index in free list // Push back index in free list
genint_push(s->freeList, idx); m_genint_push(s->freeList, idx);
} }
M_SNAPSH0T_SPMC_INT_CONTRACT(s); M_SNAPSH0T_SPMC_INT_CONTRACT(s);
} }
@@ -730,7 +730,7 @@ m_snapsh0t_mrsw_read_end(m_snapshot_mrsw_ct s, unsigned int idx)
{ \ { \
M_C(name, _mrsw_init)(snap->core, nReader + nWriter -1 ); \ M_C(name, _mrsw_init)(snap->core, nReader + nWriter -1 ); \
unsigned int idx = snap->core->core->currentWrite; \ unsigned int idx = snap->core->core->currentWrite; \
snap->core->core->currentWrite = GENINT_ERROR; \ snap->core->core->currentWrite = M_GENINT_ERROR; \
m_snapsh0t_mrsw_write_end(snap->core->core, idx); \ m_snapsh0t_mrsw_write_end(snap->core->core, idx); \
} \ } \
\ \
+20 -20
View File
@@ -30,30 +30,30 @@
static void test(size_t n) static void test(size_t n)
{ {
genint_t s; m_genint_t s;
size_t i; size_t i;
genint_init(s, (unsigned int) n); m_genint_init(s, (unsigned int) n);
for(int k = 0; k < 3; k++) { for(int k = 0; k < 3; k++) {
for(size_t j = 0; j< n ; j++) { for(size_t j = 0; j< n ; j++) {
i = genint_pop(s); i = m_genint_pop(s);
assert (i == j); assert (i == j);
} }
i = genint_pop(s); i = m_genint_pop(s);
assert (i == GENINT_ERROR); assert (i == M_GENINT_ERROR);
assert (genint_pop(s) == GENINT_ERROR); assert (m_genint_pop(s) == M_GENINT_ERROR);
for(size_t j = 0; j< n ; j++) { for(size_t j = 0; j< n ; j++) {
genint_push(s, (unsigned int) ((j + (size_t) k) % n )); m_genint_push(s, (unsigned int) ((j + (size_t) k) % n ));
} }
} }
genint_clear(s); m_genint_clear(s);
} }
/*******************************************************/ /*******************************************************/
genint_t global; m_genint_t global;
atomic_bool tab_g[MAX_N]; atomic_bool tab_g[MAX_N];
static void conso(void *p) static void conso(void *p)
@@ -62,19 +62,19 @@ static void conso(void *p)
for(int i = 0; i < 100000; i++) { for(int i = 0; i < 100000; i++) {
unsigned int tab[4]; unsigned int tab[4];
for(int j= 0; j < 4; j++) { for(int j= 0; j < 4; j++) {
tab[j] = genint_pop(global); tab[j] = m_genint_pop(global);
if (tab[j] != GENINT_ERROR) { if (tab[j] != M_GENINT_ERROR) {
assert (tab[j] < n); assert (tab[j] < n);
assert (atomic_load(&tab_g[tab[j]]) == false); assert (atomic_load(&tab_g[tab[j]]) == false);
atomic_store(&tab_g[tab[j]], true); atomic_store(&tab_g[tab[j]], true);
} }
} }
for(int j = 0; j < 4; j++) { for(int j = 0; j < 4; j++) {
if (tab[j] != GENINT_ERROR) { if (tab[j] != M_GENINT_ERROR) {
assert (tab[j] < n); assert (tab[j] < n);
assert (atomic_load(&tab_g[tab[j]]) == true); assert (atomic_load(&tab_g[tab[j]]) == true);
atomic_store(&tab_g[tab[j]], false); atomic_store(&tab_g[tab[j]], false);
genint_push(global, tab[j]); m_genint_push(global, tab[j]);
} }
} }
} }
@@ -84,7 +84,7 @@ static void test2(size_t n)
{ {
m_thread_t idx[4]; m_thread_t idx[4];
genint_init(global, (unsigned int) n); m_genint_init(global, (unsigned int) n);
for(int i = 0; i < MAX_N; i++) for(int i = 0; i < MAX_N; i++)
atomic_init(&tab_g[i], false); atomic_init(&tab_g[i], false);
@@ -95,7 +95,7 @@ static void test2(size_t n)
m_thread_join(idx[i]); m_thread_join(idx[i]);
} }
genint_clear(global); m_genint_clear(global);
} }
// In this test, the dimension of the global and the number of threads // In this test, the dimension of the global and the number of threads
@@ -104,10 +104,10 @@ static void conso2(void *p)
{ {
size_t n = *(size_t*)p; size_t n = *(size_t*)p;
for(int i = 0; i < 1000000; i++) { for(int i = 0; i < 1000000; i++) {
unsigned int j = genint_pop(global); unsigned int j = m_genint_pop(global);
assert (j != GENINT_ERROR); assert (j != M_GENINT_ERROR);
assert (j < n); assert (j < n);
genint_push(global, j); m_genint_push(global, j);
} }
} }
@@ -116,14 +116,14 @@ static void test3(size_t n)
m_thread_t idx[MAX_N]; m_thread_t idx[MAX_N];
assert (n <= MAX_N); assert (n <= MAX_N);
genint_init(global, (unsigned int) n); m_genint_init(global, (unsigned int) n);
for(size_t i = 0; i < n; i++) { for(size_t i = 0; i < n; i++) {
m_thread_create (idx[i], conso2, (void*)&n); m_thread_create (idx[i], conso2, (void*)&n);
} }
for(size_t i = 0; i < n;i++) { for(size_t i = 0; i < n;i++) {
m_thread_join(idx[i]); m_thread_join(idx[i]);
} }
genint_clear(global); m_genint_clear(global);
} }
int main(void) int main(void)