void cpvector_insert(struct cpvector *cpvec, void *ptr, int priority) { struct pvector *temp = cpvec->temp; struct pvector *old = cpvector_get_pvector(cpvec); ovs_assert(ptr != NULL); /* Check if can add to the end without reallocation. */ if (!temp && old->allocated > old->size && (!old->size || priority <= old->vector[old->size - 1].priority)) { old->vector[old->size].ptr = ptr; old->vector[old->size].priority = priority; /* Size increment must not be visible to the readers before the new * entry is stored. */ atomic_thread_fence(memory_order_release); ++old->size; } else { if (!temp) { cpvec->temp = pvector_dup(old); } pvector_push_back(&cpvec->temp, ptr, priority); } }
int main(int argc, char *argv[]) { START(argc, argv, "obj_pvector"); if (argc != 2) UT_FATAL("usage: %s [file]", argv[0]); const char *path = argv[1]; PMEMobjpool *pop; if ((pop = pmemobj_create(path, "obj_pvector", PMEMOBJ_MIN_POOL * 3, S_IWUSR | S_IRUSR)) == NULL) UT_FATAL("!pmemobj_create: %s", path); PMEMoid root = pmemobj_root(pop, sizeof(struct test_root)); struct test_root *r = (struct test_root *)pmemobj_direct(root); UT_ASSERTne(r, NULL); struct pvector_context *ctx = pvector_new(pop, &r->vec); uint64_t *val = pvector_push_back(ctx); *val = 5; val = pvector_push_back(ctx); *val = 10; val = pvector_push_back(ctx); *val = 15; uint64_t v; int n = 0; for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) { if (n == 0) UT_ASSERTeq(v, 5); if (n == 1) UT_ASSERTeq(v, 10); if (n == 2) UT_ASSERTeq(v, 15); if (n == 3) UT_ASSERT(0); n++; } uint64_t removed = pvector_pop_back(ctx, NULL); UT_ASSERTeq(removed, 15); n = 0; for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) { if (n == 0) UT_ASSERTeq(v, 5); if (n == 1) UT_ASSERTeq(v, 10); if (n == 3) UT_ASSERT(0); n++; } while (pvector_pop_back(ctx, vec_zero_entry) != 0) ; pvector_delete(ctx); ctx = pvector_new(pop, &r->vec); for (int i = 0; i < PVECTOR_INSERT_VALUES; ++i) { val = pvector_push_back(ctx); UT_ASSERTne(val, NULL); *val = i; pmemobj_persist(pop, val, sizeof(*val)); } n = 0; for (v = pvector_first(ctx); v != 0; v = pvector_next(ctx)) { UT_ASSERTeq(v, n); n++; } n = 0; for (int i = PVECTOR_INSERT_VALUES - 1; i >= 0; --i) { v = pvector_pop_back(ctx, NULL); UT_ASSERTeq(v, i); } UT_ASSERTeq(pvector_first(ctx), 0); pvector_delete(ctx); pmemobj_close(pop); DONE(NULL); }