/* * Tests whether we free old generation memory from rollover account, * irrespective of their owner account */ void test__MemoryAccounting_Free__FreesOldGenFromRollover(void **state) { assert_true(ActiveMemoryAccount == TopMemoryAccount); uint64 activeBalance = ActiveMemoryAccount->allocated - ActiveMemoryAccount->freed; uint64 oldRolloverBalance = RolloverMemoryAccount->allocated - RolloverMemoryAccount->freed; void *testAlloc = palloc(NEW_ALLOC_SIZE); assert_true(activeBalance < (ActiveMemoryAccount->allocated - ActiveMemoryAccount->freed)); MemoryAccounting_Reset(); uint64 rolloverBalance = RolloverMemoryAccount->allocated - RolloverMemoryAccount->freed; /* Rollover should assume the ownership of prev-generation allocations */ assert_true(rolloverBalance > 0 && rolloverBalance > oldRolloverBalance); pfree(testAlloc); /* * After we freed our previous allocation, the rollover balance * should be reduced by at least NEW_ALLOC_SIZE amount */ assert_true(RolloverMemoryAccount->allocated - RolloverMemoryAccount->freed <= (rolloverBalance - NEW_ALLOC_SIZE)); }
/* * MemoryContextInit * Start up the memory-context subsystem. * * This must be called before creating contexts or allocating memory in * contexts. TopMemoryContext and ErrorContext are initialized here; * other contexts must be created afterwards. * * In normal multi-backend operation, this is called once during * postmaster startup, and not at all by individual backend startup * (since the backends inherit an already-initialized context subsystem * by virtue of being forked off the postmaster). * * In a standalone backend this must be called during backend startup. */ void MemoryContextInit(void) { AssertState(TopMemoryContext == NULL); AssertState(CurrentMemoryContext == NULL); AssertState(MemoryAccountMemoryContext == NULL); /* * Initialize TopMemoryContext as an AllocSetContext with slow growth rate * --- we don't really expect much to be allocated in it. * * (There is special-case code in MemoryContextCreate() for this call.) */ TopMemoryContext = AllocSetContextCreate((MemoryContext) NULL, "TopMemoryContext", 0, 8 * 1024, 8 * 1024); /* * Not having any other place to point CurrentMemoryContext, make it point * to TopMemoryContext. Caller should change this soon! */ CurrentMemoryContext = TopMemoryContext; /* * Initialize ErrorContext as an AllocSetContext with slow growth rate --- * we don't really expect much to be allocated in it. More to the point, * require it to contain at least 8K at all times. This is the only case * where retained memory in a context is *essential* --- we want to be * sure ErrorContext still has some memory even if we've run out * elsewhere! */ ErrorContext = AllocSetContextCreate(TopMemoryContext, "ErrorContext", 8 * 1024, 8 * 1024, 8 * 1024); MemoryAccounting_Reset(); }
/* Tests whether we ignore sharedHeader if it is not from the current generation */ void test__AllocAllocInfo__IgnoresOldGenSharedHeaders(void **state) { void *testAlloc1 = palloc(NEW_ALLOC_SIZE); StandardChunkHeader *header1 = (StandardChunkHeader *) ((char *) testAlloc1 - STANDARDCHUNKHEADERSIZE); MemoryAccounting_Reset(); /* Should not reuse sharedHeader as the generation has changed */ void *testAlloc2 = palloc(NEW_ALLOC_SIZE); StandardChunkHeader *header2 = (StandardChunkHeader *) ((char *) testAlloc2 - STANDARDCHUNKHEADERSIZE); /* * No header sharing as the generation has changed during * the call of MemoryAccounting_Reset() */ assert_true(header1->sharedHeader != header2->sharedHeader); pfree(testAlloc1); pfree(testAlloc2); }