Add test for int snapshot MRSW
This commit is contained in:
1 parent
3bda360196
commit
a4753be5ae
2 files changed
+50
-6
No files matched your search
+19
-6
@@ -284,6 +284,7 @@ typedef struct snapshot_mrsw_int_s {
|
|||||||
assert (SNAPSHOTI_MRSW_INT_FLAG_W(atomic_load(&s->lastNext)) \
|
assert (SNAPSHOTI_MRSW_INT_FLAG_W(atomic_load(&s->lastNext)) \
|
||||||
<= s->n + SNAPSHOTI_MRSW_EXTRA_BUFFER); \
|
<= s->n + SNAPSHOTI_MRSW_EXTRA_BUFFER); \
|
||||||
assert (s->cptTab != NULL); \
|
assert (s->cptTab != NULL); \
|
||||||
|
assert (atomic_load(&s->cptTab[s->currentWrite]) == 1); \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
static inline void snapshot_mrsw_int_init(snapshot_mrsw_int_t s, size_t n)
|
static inline void snapshot_mrsw_int_init(snapshot_mrsw_int_t s, size_t n)
|
||||||
@@ -303,9 +304,11 @@ 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);
|
||||||
|
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);
|
||||||
|
atomic_store(&s->cptTab[s->currentWrite], 1);
|
||||||
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,8 +339,17 @@ static inline unsigned int snapshot_mrsw_int_write(snapshot_mrsw_int_t s)
|
|||||||
// Reuse previous buffer as it was not used by any reader
|
// Reuse previous buffer as it was not used by any reader
|
||||||
s->currentWrite = SNAPSHOTI_MRSW_INT_FLAG_W(previous);
|
s->currentWrite = SNAPSHOTI_MRSW_INT_FLAG_W(previous);
|
||||||
} else {
|
} else {
|
||||||
|
// Free the write index
|
||||||
|
idx = SNAPSHOTI_MRSW_INT_FLAG_W(previous);
|
||||||
|
unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
||||||
|
assert (c != 0 && c <= s->n + 1);
|
||||||
// Get a new buffer.
|
// Get a new buffer.
|
||||||
s->currentWrite = genint_pop(s->freeList);
|
if (c != 1)
|
||||||
|
idx = genint_pop(s->freeList);
|
||||||
|
s->currentWrite = idx;
|
||||||
|
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);
|
SNAPSHOTI_MRSW_INT_CONTRACT(s);
|
||||||
return s->currentWrite;
|
return s->currentWrite;
|
||||||
@@ -353,18 +365,19 @@ static inline unsigned int snapshot_mrsw_int_read_start(snapshot_mrsw_int_t s)
|
|||||||
unsigned int newNext = SNAPSHOTI_MRSW_INT_FLAG(idx, false);
|
unsigned int newNext = SNAPSHOTI_MRSW_INT_FLAG(idx, false);
|
||||||
// Reserve the index
|
// Reserve the index
|
||||||
unsigned int c = atomic_fetch_add(&s->cptTab[idx], 1);
|
unsigned int c = atomic_fetch_add(&s->cptTab[idx], 1);
|
||||||
assert (c <= s->n);
|
assert (c <= s->n + 1);
|
||||||
|
// Try to ack it
|
||||||
if (atomic_compare_exchange_weak(&s->lastNext, &previous, newNext))
|
if (atomic_compare_exchange_weak(&s->lastNext, &previous, newNext))
|
||||||
break;
|
break;
|
||||||
// If we have been preempted by another read thread
|
// If we have been preempted by another read thread
|
||||||
if (idx == SNAPSHOTI_MRSW_INT_FLAG_W(previous)) {
|
if (idx == SNAPSHOTI_MRSW_INT_FLAG_W(previous)) {
|
||||||
// This is still ok
|
// This is still ok if the index has not changed
|
||||||
assert (SNAPSHOTI_MRSW_INT_FLAG_N(previous) == false);
|
assert (SNAPSHOTI_MRSW_INT_FLAG_N(previous) == false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Free the reserved index
|
// Free the reserved index as we failed it to ack it
|
||||||
c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
||||||
assert (c != 0);
|
assert (c != 0 && c <= s->n+1);
|
||||||
if (c == 1)
|
if (c == 1)
|
||||||
genint_push(s->freeList, idx);
|
genint_push(s->freeList, idx);
|
||||||
}
|
}
|
||||||
@@ -378,7 +391,7 @@ static inline void snapshot_mrsw_int_read_end(snapshot_mrsw_int_t s, unsigned in
|
|||||||
assert (idx < s->n + SNAPSHOTI_MRSW_EXTRA_BUFFER);
|
assert (idx < s->n + SNAPSHOTI_MRSW_EXTRA_BUFFER);
|
||||||
// Decrement reference counter of the buffer
|
// Decrement reference counter of the buffer
|
||||||
unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
unsigned int c = atomic_fetch_sub(&s->cptTab[idx], 1);
|
||||||
assert (c != 0);
|
assert (c != 0 && c <= s->n+1);
|
||||||
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
|
||||||
|
|||||||
@@ -140,10 +140,41 @@ static void test_global(void)
|
|||||||
snapshot_data_clear(g_buff);
|
snapshot_data_clear(g_buff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_mrsw_int(void)
|
||||||
|
{
|
||||||
|
snapshot_mrsw_int_t idx;
|
||||||
|
snapshot_mrsw_int_init(idx, 1);
|
||||||
|
|
||||||
|
assert (snapshot_mrsw_int_get_write_idx(idx) == 1);
|
||||||
|
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 0);
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 1);
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 0);
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 1);
|
||||||
|
|
||||||
|
assert (snapshot_mrsw_int_read_start(idx) == 0);
|
||||||
|
snapshot_mrsw_int_read_end(idx, 0);
|
||||||
|
assert (snapshot_mrsw_int_read_start(idx) == 0);
|
||||||
|
snapshot_mrsw_int_read_end(idx, 0);
|
||||||
|
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 0);
|
||||||
|
|
||||||
|
assert (snapshot_mrsw_int_read_start(idx) == 1);
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 2);
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 0);
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 2);
|
||||||
|
snapshot_mrsw_int_read_end(idx, 1);
|
||||||
|
assert (snapshot_mrsw_int_read_start(idx) == 0);
|
||||||
|
assert (snapshot_mrsw_int_write(idx) == 1);
|
||||||
|
|
||||||
|
snapshot_mrsw_int_clear(idx);
|
||||||
|
}
|
||||||
|
|
||||||
int main(void)
|
int main(void)
|
||||||
{
|
{
|
||||||
test_uint();
|
test_uint();
|
||||||
test_global();
|
test_global();
|
||||||
|
test_mrsw_int();
|
||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user