Skip to content

Commit a635ab4

Browse files
committed
Short-circuit AllocSetReset if nothing has been palloc'd in the memory
context since the previous AllocSetReset. Original patch by Atsushi Ogawa, editorialized on a little bit by Tom Lane.
1 parent 91a21b5 commit a635ab4

File tree

1 file changed

+35
-13
lines changed

1 file changed

+35
-13
lines changed

src/backend/utils/mmgr/aset.c

Lines changed: 35 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
* Portions Copyright (c) 1994, Regents of the University of California
1212
*
1313
* IDENTIFICATION
14-
* $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.62 2005/06/04 22:57:22 momjian Exp $
14+
* $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.63 2005/09/01 18:15:42 tgl Exp $
1515
*
1616
* NOTE:
1717
* This is a new (Feb. 05, 1999) implementation of the allocation set
@@ -123,13 +123,20 @@ typedef void *AllocPointer;
123123

124124
/*
125125
* AllocSetContext is our standard implementation of MemoryContext.
126+
*
127+
* Note: isReset means there is nothing for AllocSetReset to do. This is
128+
* different from the aset being physically empty (empty blocks list) because
129+
* we may still have a keeper block. It's also different from the set being
130+
* logically empty, because we don't attempt to detect pfree'ing the last
131+
* active chunk.
126132
*/
127133
typedef struct AllocSetContext
128134
{
129135
MemoryContextData header; /* Standard memory-context fields */
130136
/* Info about storage allocated in this context: */
131137
AllocBlock blocks; /* head of list of blocks in this set */
132138
AllocChunk freelist[ALLOCSET_NUM_FREELISTS]; /* free chunk lists */
139+
bool isReset; /* T = no space alloced since last reset */
133140
/* Allocation parameters for this context: */
134141
Size initBlockSize; /* initial block size */
135142
Size maxBlockSize; /* maximum block size */
@@ -347,6 +354,8 @@ AllocSetContextCreate(MemoryContext parent,
347354
context->keeper = block;
348355
}
349356

357+
context->isReset = true;
358+
350359
return (MemoryContext) context;
351360
}
352361

@@ -386,26 +395,28 @@ static void
386395
AllocSetReset(MemoryContext context)
387396
{
388397
AllocSet set = (AllocSet) context;
389-
AllocBlock block = set->blocks;
398+
AllocBlock block;
390399

391400
AssertArg(AllocSetIsValid(set));
392401

402+
/* Nothing to do if no pallocs since startup or last reset */
403+
if (set->isReset)
404+
return;
405+
393406
#ifdef MEMORY_CONTEXT_CHECKING
394407
/* Check for corruption and leaks before freeing */
395408
AllocSetCheck(context);
396409
#endif
397410

398-
/* Nothing to do if context has never contained any data */
399-
if (block == NULL)
400-
return;
401-
402411
/* Clear chunk freelists */
403412
MemSetAligned(set->freelist, 0, sizeof(set->freelist));
404413

414+
block = set->blocks;
415+
405416
/* New blocks list is either empty or just the keeper block */
406417
set->blocks = set->keeper;
407418

408-
do
419+
while (block != NULL)
409420
{
410421
AllocBlock next = block->next;
411422

@@ -432,7 +443,8 @@ AllocSetReset(MemoryContext context)
432443
}
433444
block = next;
434445
}
435-
while (block != NULL);
446+
447+
set->isReset = true;
436448
}
437449

438450
/*
@@ -538,6 +550,8 @@ AllocSetAlloc(MemoryContext context, Size size)
538550
set->blocks = block;
539551
}
540552

553+
set->isReset = false;
554+
541555
AllocAllocInfo(set, chunk);
542556
return AllocChunkGetPointer(chunk);
543557
}
@@ -576,6 +590,9 @@ AllocSetAlloc(MemoryContext context, Size size)
576590
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E;
577591
#endif
578592

593+
/* isReset must be false already */
594+
Assert(!set->isReset);
595+
579596
AllocAllocInfo(set, chunk);
580597
return AllocChunkGetPointer(chunk);
581598
}
@@ -748,6 +765,8 @@ AllocSetAlloc(MemoryContext context, Size size)
748765
((char *) AllocChunkGetPointer(chunk))[size] = 0x7E;
749766
#endif
750767

768+
set->isReset = false;
769+
751770
AllocAllocInfo(set, chunk);
752771
return AllocChunkGetPointer(chunk);
753772
}
@@ -846,6 +865,9 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
846865
set->header.name, chunk);
847866
#endif
848867

868+
/* isReset must be false already */
869+
Assert(!set->isReset);
870+
849871
/*
850872
* Chunk sizes are aligned to power of 2 in AllocSetAlloc(). Maybe the
851873
* allocated area already is >= the new size. (In particular, we
@@ -1009,12 +1031,12 @@ AllocSetIsEmpty(MemoryContext context)
10091031
AllocSet set = (AllocSet) context;
10101032

10111033
/*
1012-
* For now, we say "empty" only if the context never contained any
1013-
* space at all. We could examine the freelists to determine if all
1014-
* space has been freed, but it's not really worth the trouble for
1015-
* present uses of this functionality.
1034+
* For now, we say "empty" only if the context is new or just reset.
1035+
* We could examine the freelists to determine if all space has been
1036+
* freed, but it's not really worth the trouble for present uses of
1037+
* this functionality.
10161038
*/
1017-
if (set->blocks == NULL)
1039+
if (set->isReset)
10181040
return true;
10191041
return false;
10201042
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy