inline pool_base pool_by_pptr(const persistent_ptr<T> ptr) { auto pop = pmemobj_pool_by_oid(ptr.raw()); if (!pop) throw pool_error("Object not in an open pool."); return pool_base(pop); }
/* * pmemobj_alloc_usable_size -- returns usable size of object */ size_t pmemobj_alloc_usable_size(PMEMoid oid) { LOG(3, "oid.off 0x%016jx", oid.off); if (oid.off == 0) return 0; PMEMobjpool *pop = pmemobj_pool_by_oid(oid); ASSERTne(pop, NULL); ASSERT(OBJ_OID_IS_VALID(pop, oid)); return (pmalloc_usable_size(pop, oid.off - OBJ_OOB_SIZE) - OBJ_OOB_SIZE); }
/* * pocli_pmemobj_pool_by_oid -- pmemobj_pool_by_oid() command */ static enum pocli_ret pocli_pmemobj_pool_by_oid(struct pocli_ctx *ctx, struct pocli_args *args) { if (args->argc != 2) return POCLI_ERR_ARGS; PMEMoid *oid; enum pocli_ret ret; if ((ret = pocli_args_obj(ctx, args, 1, &oid))) return ret; PMEMobjpool *pop = pmemobj_pool_by_oid(*oid); pocli_printf(ctx, "%s(%p): uuid = 0x%llx\n", args->argv[0], pmemobj_direct(*oid), pop->uuid_lo); return ret; }
/* * pmemobj_free -- frees an existing object */ void pmemobj_free(PMEMoid *oidp) { ASSERTne(oidp, NULL); LOG(3, "oid.off 0x%016jx", oidp->off); /* log notice message if used inside a transaction */ _POBJ_DEBUG_NOTICE_IN_TX(); if (oidp->off == 0) return; PMEMobjpool *pop = pmemobj_pool_by_oid(*oidp); ASSERTne(pop, NULL); ASSERT(OBJ_OID_IS_VALID(pop, *oidp)); obj_free(pop, oidp); }
/* * pmemobj_next - returns next object of specified type */ PMEMoid pmemobj_next(PMEMoid oid) { LOG(3, "oid.off 0x%016jx", oid.off); if (oid.off == 0) return OID_NULL; PMEMobjpool *pop = pmemobj_pool_by_oid(oid); ASSERTne(pop, NULL); ASSERT(OBJ_OID_IS_VALID(pop, oid)); struct oob_header *pobj = OOB_HEADER_FROM_OID(pop, oid); type_num_t user_type = pobj->data.user_type; ASSERT(user_type < PMEMOBJ_NUM_OID_TYPES); if (pobj->oob.pe_next.off != pop->store->bytype[user_type].head.pe_first.off) return pobj->oob.pe_next; else return OID_NULL; }
int main(int argc, char *argv[]) { START(argc, argv, "obj_direct"); if (argc != 3) UT_FATAL("usage: %s [directory] [# of pools]", argv[0]); int npools = atoi(argv[2]); const char *dir = argv[1]; int r; PMEMobjpool *pops[npools]; void *guard_after[npools]; char path[MAX_PATH_LEN]; for (int i = 0; i < npools; ++i) { snprintf(path, MAX_PATH_LEN, "%s/testfile%d", dir, i); pops[i] = pmemobj_create(path, LAYOUT_NAME, PMEMOBJ_MIN_POOL, S_IWUSR | S_IRUSR); /* * Reserve a page after the pool for address checks, if it * doesn't map precisely at that address - it's OK. */ guard_after[i] = MMAP((char *)pops[i] + PMEMOBJ_MIN_POOL, Ut_pagesize, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); UT_ASSERTne(guard_after[i], NULL); if (pops[i] == NULL) UT_FATAL("!pmemobj_create"); } PMEMoid oids[npools]; for (int i = 0; i < npools; ++i) { r = pmemobj_alloc(pops[i], &oids[i], ALLOC_SIZE, 1, NULL, NULL); UT_ASSERTeq(r, 0); } PMEMoid invalid = {123, 321}; UT_ASSERTeq(pmemobj_pool_by_oid(OID_NULL), NULL); UT_ASSERTeq(pmemobj_pool_by_oid(invalid), NULL); for (int i = 0; i < npools; ++i) { UT_ASSERTeq(pmemobj_pool_by_oid(oids[i]), pops[i]); } UT_ASSERTeq(pmemobj_pool_by_ptr(NULL), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr((void *)0xCBA), NULL); for (int i = 0; i < npools; ++i) { void *before_pool = (char *)pops[i] - 1; void *after_pool = (char *)pops[i] + PMEMOBJ_MIN_POOL + 1; void *edge = (char *)pops[i] + PMEMOBJ_MIN_POOL; void *middle = (char *)pops[i] + (PMEMOBJ_MIN_POOL / 2); void *in_oid = (char *)pmemobj_direct(oids[i]) + (ALLOC_SIZE / 2); UT_ASSERTeq(pmemobj_pool_by_ptr(before_pool), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(after_pool), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(edge), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(middle), pops[i]); UT_ASSERTeq(pmemobj_pool_by_ptr(in_oid), pops[i]); pmemobj_close(pops[i]); UT_ASSERTeq(pmemobj_pool_by_ptr(middle), NULL); UT_ASSERTeq(pmemobj_pool_by_ptr(in_oid), NULL); MUNMAP(guard_after[i], Ut_pagesize); } DONE(NULL); }