Add MRMW snapshot

This commit is contained in:
Patrick Pelissier committed 2018-02-18 08:27:10 +01:00
1 parent c5de5e07d8
commit 6de4c4092f
2 files changed
+101 -1

No files matched your search

+100 -1
View File
@@ -46,6 +46,13 @@
((name, __VA_ARGS__, M_GLOBAL_OPLIST_OR_DEF(__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.
USAGE: SNAPSHOT_OPLIST(name[, 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);
// Get a free buffer and set it as available for readers
unsigned int w = genint_pop(s->freeList);
assert (w != -1U);
atomic_store(&s->cptTab[w], 1);
atomic_init(&s->lastNext, SNAPSHOTI_MRSW_INT_FLAG(w, true));
// Get working buffer
s->currentWrite = genint_pop(s->freeList);
assert (s->currentWrite != -1U);
atomic_store(&s->cptTab[s->currentWrite], 1);
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);
assert (c != 0 && c <= s->n + 1);
// Get a new buffer.
if (c != 1)
if (c != 1) {
// If someone else keeps a ref on the buffer, we can't reuse it
// get another free one
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);
@@ -369,6 +380,35 @@ static inline unsigned int snapshot_mrsw_int_write(snapshot_mrsw_int_t s)
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)
{
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
/******************************** 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
+1
View File
@@ -50,6 +50,7 @@ SNAPSHOT_SRSW_DEF(snapshot_uint, unsigned int)
SNAPSHOT_SRSW_DEF(snapshot_mpz, mpz_t,
(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_MRMW_DEF(snapshot_mrmw_data, data_t, DATA_OPLIST)
END_COVERAGE
SNAPSHOT_DEF(snapshot_data, data_t, DATA_OPLIST )