static void arena_commit_test(mps_arena_t arena) { mps_pool_t pool; size_t committed; size_t reserved; size_t limit; void *p; mps_res_t res; committed = mps_arena_committed(arena); reserved = mps_arena_reserved(arena); cdie(reserved >= committed, "reserved < committed"); die(mps_pool_create(&pool, arena, mps_class_mv(), 0x1000, 1024, 16384), "commit pool create"); limit = mps_arena_commit_limit(arena); die(mps_arena_commit_limit_set(arena, committed), "commit_limit_set before"); do { res = mps_alloc(&p, pool, FILLER_OBJECT_SIZE); } while (res == MPS_RES_OK); die_expect(res, MPS_RES_COMMIT_LIMIT, "Commit limit allocation"); die(mps_arena_commit_limit_set(arena, limit), "commit_limit_set after"); res = mps_alloc(&p, pool, FILLER_OBJECT_SIZE); die_expect(res, MPS_RES_OK, "Allocation failed after raising commit_limit"); mps_pool_destroy(pool); }
static void deallocate(FBMState state, Addr base, Addr limit) { Res res; Index ib, il; Bool isAllocated; Addr outerBase = base, outerLimit = limit; /* interval containing [ib, il) */ RangeStruct range, freeRange; /* interval returned by the manager */ ib = indexOfAddr(state, base); il = indexOfAddr(state, limit); isAllocated = BTIsSetRange(state->allocTable, ib, il); NDeallocateTried++; if (isAllocated) { Size left, right, total; /* Sizes of block and two fragments */ /* Find the free blocks adjacent to the allocated block */ if (ib > 0 && !BTGet(state->allocTable, ib - 1)) { outerBase = addrOfIndex(state, lastEdge(state->allocTable, ArraySize, ib - 1)); } else { outerBase = base; } if (il < ArraySize && !BTGet(state->allocTable, il)) { outerLimit = addrOfIndex(state, nextEdge(state->allocTable, ArraySize, il)); } else { outerLimit = limit; } left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* TODO: check these values */ UNUSED(left); UNUSED(right); UNUSED(total); } RangeInit(&range, base, limit); switch (state->type) { case FBMTypeCBS: res = CBSInsert(&freeRange, state->the.cbs, &range); break; case FBMTypeFreelist: res = FreelistInsert(&freeRange, state->the.fl, &range); break; default: fail(); return; } if (verbose) { printf("deallocate: [%p,%p) -- %s\n", (void *)base, (void *)limit, isAllocated ? "succeed" : "fail"); describe(state); } if (!isAllocated) { die_expect((mps_res_t)res, MPS_RES_FAIL, "succeeded in inserting non-allocated block"); } else { /* isAllocated */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to insert allocated block"); NDeallocateSucceeded++; BTResRange(state->allocTable, ib, il); Insist(RangeBase(&freeRange) == outerBase); Insist(RangeLimit(&freeRange) == outerLimit); } }
static void allocate(FBMState state, Addr base, Addr limit) { Res res; Index ib, il; /* Indexed for base and limit */ Bool isFree; RangeStruct range, oldRange; Addr outerBase, outerLimit; /* interval containing [ib, il) */ ib = indexOfAddr(state, base); il = indexOfAddr(state, limit); isFree = BTIsResRange(state->allocTable, ib, il); NAllocateTried++; if (isFree) { Size left, right, total; /* Sizes of block and two fragments */ outerBase = addrOfIndex(state, lastEdge(state->allocTable, ArraySize, ib)); outerLimit = addrOfIndex(state, nextEdge(state->allocTable, ArraySize, il - 1)); left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* TODO: check these values */ UNUSED(left); UNUSED(right); UNUSED(total); } else { outerBase = outerLimit = NULL; } RangeInit(&range, base, limit); switch (state->type) { case FBMTypeCBS: res = CBSDelete(&oldRange, state->the.cbs, &range); break; case FBMTypeFreelist: res = FreelistDelete(&oldRange, state->the.fl, &range); break; default: fail(); return; } if (verbose) { printf("allocate: [%p,%p) -- %s\n", (void *)base, (void *)limit, isFree ? "succeed" : "fail"); describe(state); } if (!isFree) { die_expect((mps_res_t)res, MPS_RES_FAIL, "Succeeded in deleting allocated block"); } else { /* isFree */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to delete free block"); Insist(RangeBase(&oldRange) == outerBase); Insist(RangeLimit(&oldRange) == outerLimit); NAllocateSucceeded++; BTSetRange(state->allocTable, ib, il); } }
static void deallocate(CBS cbs, Addr block, BT allocTable, Addr base, Addr limit) { Res res; Index ib, il; Bool isAllocated; Addr outerBase = base, outerLimit = limit; /* interval containing [ib, il) */ Addr freeBase, freeLimit; /* interval returned by CBS */ ib = indexOfAddr(block, base); il = indexOfAddr(block, limit); isAllocated = BTIsSetRange(allocTable, ib, il); /* printf("deallocate: [%p, %p) -- %s\n", base, limit, isAllocated ? "succeed" : "fail"); */ NDeallocateTried++; if (isAllocated) { Size left, right, total; /* Sizes of block and two fragments */ /* Find the free blocks adjacent to the allocated block */ if (ib > 0 && !BTGet(allocTable, ib - 1)) { outerBase = addrOfIndex(block, lastEdge(allocTable, ArraySize, ib - 1)); } else { outerBase = base; } if (il < ArraySize && !BTGet(allocTable, il)) { outerLimit = addrOfIndex(block, nextEdge(allocTable, ArraySize, il)); } else { outerLimit = limit; } left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* based on detailed knowledge of CBS behaviour */ checkExpectations(); if (total >= MinSize && left < MinSize && right < MinSize) { if (left >= right) expectCallback(&CallbackNew, left, outerBase, outerLimit); else expectCallback(&CallbackNew, right, outerBase, outerLimit); } else if (left >= MinSize && right >= MinSize) { if (left >= right) { expectCallback(&CallbackDelete, right, (Addr)0, (Addr)0); expectCallback(&CallbackGrow, left, outerBase, outerLimit); } else { expectCallback(&CallbackDelete, left, (Addr)0, (Addr)0); expectCallback(&CallbackGrow, right, outerBase, outerLimit); } } else if (total >= MinSize) { if (left >= right) { Insist(left >= MinSize); Insist(right < MinSize); expectCallback(&CallbackGrow, left, outerBase, outerLimit); } else { Insist(left < MinSize); Insist(right >= MinSize); expectCallback(&CallbackGrow, right, outerBase, outerLimit); } } } res = CBSInsertReturningRange(&freeBase, &freeLimit, cbs, base, limit); if (!isAllocated) { die_expect((mps_res_t)res, MPS_RES_FAIL, "succeeded in inserting non-allocated block"); } else { /* isAllocated */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to insert allocated block"); NDeallocateSucceeded++; BTResRange(allocTable, ib, il); checkExpectations(); Insist(freeBase == outerBase); Insist(freeLimit == outerLimit); } }
static void allocate(CBS cbs, Addr block, BT allocTable, Addr base, Addr limit) { Res res; Index ib, il; /* Indexed for base and limit */ Bool isFree; ib = indexOfAddr(block, base); il = indexOfAddr(block, limit); isFree = BTIsResRange(allocTable, ib, il); /* printf("allocate: [%p, %p) -- %s\n", base, limit, isFree ? "succeed" : "fail"); */ NAllocateTried++; if (isFree) { Addr outerBase, outerLimit; /* interval containing [ib, il) */ Size left, right, total; /* Sizes of block and two fragments */ outerBase = addrOfIndex(block, lastEdge(allocTable, ArraySize, ib)); outerLimit = addrOfIndex(block, nextEdge(allocTable, ArraySize, il - 1)); left = AddrOffset(outerBase, base); right = AddrOffset(limit, outerLimit); total = AddrOffset(outerBase, outerLimit); /* based on detailed knowledge of CBS behaviour */ checkExpectations(); if (total >= MinSize && left < MinSize && right < MinSize) { if (left == (Size)0 && right == (Size)0) { expectCallback(&CallbackDelete, total, (Addr)0, (Addr)0); } else if (left >= right) { expectCallback(&CallbackDelete, total, outerBase, base); } else { expectCallback(&CallbackDelete, total, limit, outerLimit); } } else if (left >= MinSize && right >= MinSize) { if (left >= right) { expectCallback(&CallbackShrink, total, outerBase, base); expectCallback(&CallbackNew, (Size)0, limit, outerLimit); } else { expectCallback(&CallbackNew, (Size)0, outerBase, base); expectCallback(&CallbackShrink, total, limit, outerLimit); } } else if (total >= MinSize) { if (left >= right) { Insist(left >= MinSize); Insist(right < MinSize); expectCallback(&CallbackShrink, total, outerBase, base); } else { Insist(left < MinSize); Insist(right >= MinSize); expectCallback(&CallbackShrink, total, limit, outerLimit); } } } res = CBSDelete(cbs, base, limit); if (!isFree) { die_expect((mps_res_t)res, MPS_RES_FAIL, "Succeeded in deleting allocated block"); } else { /* isFree */ die_expect((mps_res_t)res, MPS_RES_OK, "failed to delete free block"); NAllocateSucceeded++; BTSetRange(allocTable, ib, il); checkExpectations(); } }