spmc
u32 spmc[2];
*val = get_reg_val(id, vcpu->arch.spmc[i]);
vcpu->arch.spmc[i] = set_reg_val(id, *val);
int spmc_owned_add(struct spmc __arena *spmc, u64 val);
int spmc_owned_remove(struct spmc __arena *spmc, u64 *val);
int spmc_steal(struct spmc __arena *spmc, u64 *val);
struct spmc __arena *spmc_create(void);
int spmc_destroy(struct spmc __arena *spmc);
spmc = spmc_create();
if (!spmc)
ret = spmc_destroy(spmc);
spmc = NULL;
ret = spmc_owned_remove(spmc, &val);
ret = spmc_steal(spmc, &val);
ret = spmc_owned_remove(spmc, &val);
static struct spmc __arena *spmc;
ret = spmc_owned_add(spmc, i);
ret = spmc_owned_add(spmc, i);
ret = spmc_owned_add(spmc, i);
if (spmc->cur->order > TEST_SPMC_RESIZE_ORDER)
ret = spmc_steal(spmc, &val);
ret = spmc_owned_add(spmc, base + i);
ret = spmc_owned_remove(spmc, &val);
ret = spmc_steal(spmc, &val);
ret = spmc_owned_remove(spmc, &newval);
spmc_destroy(spmc);
struct spmc __arena *spmc = spmc_create();
if (!spmc)
ret = spmc_owned_add(spmc, val);
ret = spmc_owned_remove(spmc, &newval);
spmc_destroy(spmc);
struct spmc __arena *spmc = spmc_create();
if (!spmc)
ret = spmc_owned_add(spmc, val);
ret = spmc_steal(spmc, &newval);
spmc_destroy(spmc);
struct spmc __arena *spmc = spmc_create();
if (!spmc)
ret = spmc_owned_remove(spmc, &val);
spmc_destroy(spmc);
struct spmc __arena *spmc = spmc_create();
if (!spmc)
ret = spmc_steal(spmc, &val);
spmc_destroy(spmc);
struct spmc __arena *spmc = spmc_create();
if (!spmc)
ret = spmc_owned_add(spmc, val);
ret = spmc_steal(spmc, &newval);
spmc_destroy(spmc);
struct spmc __arena *spmc = spmc_create();
if (!spmc)
ret = spmc_owned_add(spmc, val);
smp_store_release(&spmc->bottom, b + 1);
int spmc_owned_remove(struct spmc __arena *spmc, u64 *val)
if (unlikely(!spmc || !val))
b = READ_ONCE(spmc->bottom) - 1;
WRITE_ONCE(spmc->bottom, b);
t = READ_ONCE(spmc->top);
arr = READ_ONCE(spmc->cur);
WRITE_ONCE(spmc->bottom, t);
if (cmpxchg(&spmc->top, t, t + 1) != t)
WRITE_ONCE(spmc->bottom, t + 1);
int spmc_steal(struct spmc __arena *spmc, u64 *val)
if (unlikely(!spmc || !val))
t = smp_load_acquire(&spmc->top);
b = smp_load_acquire(&spmc->bottom);
arr = smp_load_acquire(&spmc->cur);
if (cmpxchg(&spmc->top, t, t + 1) != t)
struct spmc __arena *spmc_create(void)
struct spmc __arena *volatile spmc;
spmc = arena_malloc(sizeof(*spmc));
if (!spmc)
spmc->bottom = 0;
spmc->top = 0;
spmc->arr[i].data = NULL;
spmc->arr[i].order = i;
ret = spmc_order_init((struct spmc __arena *)spmc, 0);
arena_free(spmc);
spmc->cur = &spmc->arr[0];
return (struct spmc __arena *)spmc;
int spmc_destroy(struct spmc __arena *spmc)
if (unlikely(!spmc))
arena_free(spmc->arr[i].data);
arena_free(spmc);
int spmc_order_init(struct spmc __arena *spmc, int order)
volatile struct spmc_arr __arena *arr = &spmc->arr[order];
if (unlikely(!spmc))
int spmc_owned_add(struct spmc __arena *spmc, u64 val)
if (unlikely(!spmc))
b = smp_load_acquire(&spmc->bottom);
t = READ_ONCE(spmc->top);
arr = READ_ONCE(spmc->cur);
ret = spmc_order_init(spmc, arr->order + 1);
newarr = &spmc->arr[arr->order + 1];
smp_store_release(&spmc->cur, newarr);