static int32_t testPoolClear(OMRPortLibrary *portLib, J9Pool *currentPool) { uintptr_t expectedCapacityAfterClear = pool_capacity(currentPool); pool_clear(currentPool); if (0 != pool_numElements(currentPool)) { return -1; } else if (expectedCapacityAfterClear != pool_capacity(currentPool)) { return -2; } return 0; }
static int32_t testPoolRemoveElement(OMRPortLibrary *portLib, J9Pool *currentPool) { uintptr_t expectedNumElements = pool_numElements(currentPool); pool_state state; uintptr_t startCount, endCount; uintptr_t expectedCapacityAfterRemovals = currentPool->elementsPerPuddle; if (currentPool->flags & POOL_NEVER_FREE_PUDDLES) { expectedCapacityAfterRemovals = pool_capacity(currentPool); } do { uint8_t *element = (uint8_t *)pool_startDo(currentPool, &state); startCount = pool_numElements(currentPool); do { expectedNumElements--; if (!pool_includesElement(currentPool, element)) { return -1; } pool_removeElement(currentPool, element); if (pool_numElements(currentPool) != expectedNumElements) { return -2; } if (pool_includesElement(currentPool, element)) { return -3; } /* Remove every other element each time - this deliberately creates fragmentation */ element = pool_nextDo(&state); if (NULL != element) { element = pool_nextDo(&state); } } while (NULL != element); endCount = pool_numElements(currentPool); } while ((endCount > 0) && (startCount != endCount)); if (expectedNumElements != 0) { return -5; } else if (expectedCapacityAfterRemovals != pool_capacity(currentPool)) { return -6; } return 0; }
/** * Ensures that the pool is large enough for newCapacity elements. * This has the side effect of setting the POOL_NEVER_FREE_PUDDLES flag. * Without this, the pool could shrink back down to its original size. * Note that this does not take into account the number of elements already * used in the pool. * * @param[in] aPool The pool * @param[in] newCapacity The desired new-size of the pool * * @return 0 on success * @return -1 on failure * */ uintptr_t pool_ensureCapacity(J9Pool *aPool, uintptr_t newCapacity) { uintptr_t numElements; uintptr_t result = 0; Trc_pool_ensureCapacity_Entry(aPool, newCapacity); numElements = pool_capacity(aPool); /* mark each pool as POOL_NEVER_FREE_PUDDLES */ aPool->flags |= POOL_NEVER_FREE_PUDDLES; if (newCapacity > numElements) { J9PoolPuddleList *puddleList; J9PoolPuddle *newPuddle, *lastPuddle; uintptr_t newSize = newCapacity - numElements; puddleList = J9POOL_PUDDLELIST(aPool); lastPuddle = J9POOLPUDDLELIST_NEXTPUDDLE(puddleList); for (;;) { if (lastPuddle->nextPuddle == 0) { break; } lastPuddle = J9POOLPUDDLE_NEXTPUDDLE(lastPuddle); } while (newSize > 0) { J9PoolPuddle *puddle; if (newSize < aPool->elementsPerPuddle) { newSize = aPool->elementsPerPuddle; } newPuddle = poolPuddle_new(aPool); if (newPuddle == 0) { Trc_pool_ensureCapacity_OutOfMemory(newCapacity); result = -1; } /* Stick it at the end of the list. */ NNWSRP_SET(lastPuddle->nextPuddle, newPuddle); NNWSRP_SET(newPuddle->prevPuddle, lastPuddle); /* And also at the top of the available puddle list. */ puddle = WSRP_GET(puddleList->nextAvailablePuddle, J9PoolPuddle *); if (puddle) { NNWSRP_SET(newPuddle->nextAvailablePuddle, puddle); } NNWSRP_SET(puddleList->nextAvailablePuddle, newPuddle); lastPuddle = newPuddle; newSize -= aPool->elementsPerPuddle; } }