Add MRMW snapshot
This commit is contained in:
1 parent
c5de5e07d8
commit
6de4c4092f
2 files changed
+101
-1
No files matched your search
+100
-1
@@ -46,6 +46,13 @@
|
|||||||
((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__) ), \
|
((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__) ), \
|
||||||
(name, __VA_ARGS__ )))
|
(name, __VA_ARGS__ )))
|
||||||
|
|
||||||
|
/* Define a MRMW snapshot and it function
|
||||||
|
USAGE: SNAPSHOT_MRMW_DEF(name, type[, oplist]) */
|
||||||
|
#define SNAPSHOT_MRMW_DEF(name, ...) \
|
||||||
|
SNAPSHOTI_MRMW_DEF(M_IF_NARGS_EQ1(__VA_ARGS__) \
|
||||||
|
((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__VA_ARGS__) ), \
|
||||||
|
(name, __VA_ARGS__ )))
|
||||||
|
|
||||||
/* Define the oplist of a snapshot.
|
/* Define the oplist of a snapshot.
|
||||||
USAGE: SNAPSHOT_OPLIST(name[, oplist]) */
|
USAGE: SNAPSHOT_OPLIST(name[, oplist]) */
|
||||||
#define SNAPSHOT_OPLIST(...) \
|
#define SNAPSHOT_OPLIST(...) \
|
||||||
@@ -311,10 +318,12 @@ static inline void snapshot_mrsw_int_init(snapshot_mrsw_int_t s, size_t n)
|
|||||||
genint_init (s->freeList, n);
|
genint_init (s->freeList, 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 = genint_pop(s->freeList);
|
||||||
|
assert (w != -1U);
|
||||||
atomic_store(&s->cptTab[w], 1);
|
atomic_store(&s->cptTab[w], 1);
|
||||||
atomic_init(&s->lastNext, SNAPSHOTI_MRSW_INT_FLAG(w, true));
|
atomic_init(&s->lastNext, SNAPSHOTI_MRSW_INT_FLAG(w, true));
|
||||||
// Get working buffer
|
// Get working buffer
|
||||||
s->currentWrite = genint_pop(s->freeList);
|
s->currentWrite = genint_pop(s->freeList);
|
||||||
|
assert (s->currentWrite != -1U);
|
||||||
atomic_store(&s->cptTab[s->currentWrite], 1);
|
atomic_store(&s->cptTab[s->currentWrite], 1);
|
||||||
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
}
|
}
|
||||||
@@ -350,10 +359,12 @@ static inline unsigned int snapshot_mrsw_int_write_idx(snapshot_mrsw_int_t s, un
|
|||||||
unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
||||||
assert (c != 0 && c <= s->n + 1);
|
assert (c != 0 && c <= s->n + 1);
|
||||||
// Get a new buffer.
|
// Get a new buffer.
|
||||||
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 = genint_pop(s->freeList);
|
||||||
|
assert(idx != -1U);
|
||||||
|
}
|
||||||
assert (idx < s->n + SNAPSHOTI_MRSW_EXTRA_BUFFER);
|
assert (idx < s->n + SNAPSHOTI_MRSW_EXTRA_BUFFER);
|
||||||
assert (atomic_load(&s->cptTab[idx]) == 0);
|
assert (atomic_load(&s->cptTab[idx]) == 0);
|
||||||
atomic_store(&s->cptTab[idx], 1);
|
atomic_store(&s->cptTab[idx], 1);
|
||||||
@@ -369,6 +380,35 @@ static inline unsigned int snapshot_mrsw_int_write(snapshot_mrsw_int_t s)
|
|||||||
return s->currentWrite;
|
return s->currentWrite;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline unsigned int snapshot_mrsw_int_write_start(snapshot_mrsw_int_t s)
|
||||||
|
{
|
||||||
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
|
// Get a new buffer.
|
||||||
|
unsigned int idx = genint_pop(s->freeList);
|
||||||
|
assert (idx != -1U);
|
||||||
|
assert (idx < s->n + SNAPSHOTI_MRSW_EXTRA_BUFFER);
|
||||||
|
assert (atomic_load(&s->cptTab[idx]) == 0);
|
||||||
|
atomic_store(&s->cptTab[idx], 1);
|
||||||
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void snapshot_mrsw_int_write_end(snapshot_mrsw_int_t s, unsigned int idx)
|
||||||
|
{
|
||||||
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
|
unsigned int newNext, previous = atomic_load(&s->lastNext);
|
||||||
|
do {
|
||||||
|
newNext = SNAPSHOTI_MRSW_INT_FLAG(idx, true);
|
||||||
|
} while (!atomic_compare_exchange_weak(&s->lastNext, &previous, newNext));
|
||||||
|
|
||||||
|
// Free the previous write buffer
|
||||||
|
idx = SNAPSHOTI_MRSW_INT_FLAG_W(previous);
|
||||||
|
unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
||||||
|
assert (c != 0 && c <= s->n + 1);
|
||||||
|
genint_push(s->freeList, idx);
|
||||||
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
|
}
|
||||||
|
|
||||||
static inline unsigned int snapshot_mrsw_int_read_start(snapshot_mrsw_int_t s)
|
static inline unsigned int snapshot_mrsw_int_read_start(snapshot_mrsw_int_t s)
|
||||||
{
|
{
|
||||||
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
@@ -496,4 +536,63 @@ static inline void snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned in
|
|||||||
\
|
\
|
||||||
//TODO: _set_, _init_set
|
//TODO: _set_, _init_set
|
||||||
|
|
||||||
|
|
||||||
|
/******************************** INTERNAL MRMW **********************************/
|
||||||
|
|
||||||
|
// MRMW is built upon MRSW
|
||||||
|
|
||||||
|
// Defered evaluation (TBC if it really helps).
|
||||||
|
#define SNAPSHOTI_MRMW_DEF(arg) SNAPSHOTI_MRMW_DEF2 arg
|
||||||
|
|
||||||
|
#define SNAPSHOTI_MRMW_DEF2(name, type, oplist) \
|
||||||
|
\
|
||||||
|
SNAPSHOTI_MRSW_DEF((M_C(name, _mrsw), type, oplist)) \
|
||||||
|
\
|
||||||
|
typedef struct M_C(name, _s) { \
|
||||||
|
M_C(name, _mrsw_t) core; \
|
||||||
|
} M_C(name, _t)[1]; \
|
||||||
|
\
|
||||||
|
typedef type M_C(name, _type_t); \
|
||||||
|
\
|
||||||
|
static inline void M_C(name, _init)(M_C(name, _t) snap, size_t nReader, size_t nWriter) \
|
||||||
|
{ \
|
||||||
|
M_C(name, _mrsw_init)(snap->core, nReader + nWriter -1 ); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static inline void M_C(name, _clear)(M_C(name, _t) snap) \
|
||||||
|
{ \
|
||||||
|
M_C(name, _mrsw_clear)(snap->core); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static inline type *M_C(name, _write_start)(M_C(name, _t) snap) \
|
||||||
|
{ \
|
||||||
|
SNAPSHOTI_MRSW_CONTRACT(snap->core); \
|
||||||
|
const unsigned int idx = snapshot_mrsw_int_write_start(snap->core->core); \
|
||||||
|
return &snap->core->data[idx].x; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static inline void M_C(name, _write_end)(M_C(name, _t) snap, type *old) \
|
||||||
|
{ \
|
||||||
|
SNAPSHOTI_MRSW_CONTRACT(snap->core); \
|
||||||
|
const M_C(name, _mrsw_aligned_type_t) *oldx; \
|
||||||
|
oldx = M_CTYPE_FROM_FIELD(M_C(name, _mrsw_aligned_type_t), old, type, x); \
|
||||||
|
assert (oldx >= snap->core->data); \
|
||||||
|
assert (oldx < snap->core->data + snap->core->core->n + SNAPSHOTI_MRSW_EXTRA_BUFFER); \
|
||||||
|
const unsigned int idx = oldx - snap->core->data; \
|
||||||
|
snapshot_mrsw_int_write_end(snap->core->core, idx); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static inline const type *M_C(name, _read_start)(M_C(name, _t) snap) \
|
||||||
|
{ \
|
||||||
|
return M_C(name, _mrsw_read_start)(snap->core); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static inline void M_C(name, _read_end)(M_C(name, _t) snap, const type *old) \
|
||||||
|
{ \
|
||||||
|
M_C(name, _mrsw_read_end)(snap->core, old); \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
|
||||||
|
//TODO: _set_, _init_set
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -50,6 +50,7 @@ SNAPSHOT_SRSW_DEF(snapshot_uint, unsigned int)
|
|||||||
SNAPSHOT_SRSW_DEF(snapshot_mpz, mpz_t,
|
SNAPSHOT_SRSW_DEF(snapshot_mpz, mpz_t,
|
||||||
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear)))
|
(INIT(mpz_init), INIT_SET(mpz_init_set), SET(mpz_set), CLEAR(mpz_clear)))
|
||||||
SNAPSHOT_MRSW_DEF(snapshot_mrsw_data, data_t, DATA_OPLIST)
|
SNAPSHOT_MRSW_DEF(snapshot_mrsw_data, data_t, DATA_OPLIST)
|
||||||
|
SNAPSHOT_MRMW_DEF(snapshot_mrmw_data, data_t, DATA_OPLIST)
|
||||||
END_COVERAGE
|
END_COVERAGE
|
||||||
SNAPSHOT_DEF(snapshot_data, data_t, DATA_OPLIST )
|
SNAPSHOT_DEF(snapshot_data, data_t, DATA_OPLIST )
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user