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 */
127133typedef struct AllocSetContext
128134{
129135MemoryContextData header ;/* Standard memory-context fields */
130136/* Info about storage allocated in this context: */
131137AllocBlock blocks ;/* head of list of blocks in this set */
132138AllocChunk freelist [ALLOCSET_NUM_FREELISTS ];/* free chunk lists */
139+ bool isReset ;/* T = no space alloced since last reset */
133140/* Allocation parameters for this context: */
134141Size initBlockSize ;/* initial block size */
135142Size maxBlockSize ;/* maximum block size */
@@ -347,6 +354,8 @@ AllocSetContextCreate(MemoryContext parent,
347354context -> keeper = block ;
348355}
349356
357+ context -> isReset = true;
358+
350359return (MemoryContext )context ;
351360}
352361
@@ -386,26 +395,28 @@ static void
386395AllocSetReset (MemoryContext context )
387396{
388397AllocSet set = (AllocSet )context ;
389- AllocBlock block = set -> blocks ;
398+ AllocBlock block ;
390399
391400AssertArg (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 */
395408AllocSetCheck (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 */
403412MemSetAligned (set -> freelist ,0 ,sizeof (set -> freelist ));
404413
414+ block = set -> blocks ;
415+
405416/* New blocks list is either empty or just the keeper block */
406417set -> blocks = set -> keeper ;
407418
408- do
419+ while ( block != NULL )
409420{
410421AllocBlock next = block -> next ;
411422
@@ -432,7 +443,8 @@ AllocSetReset(MemoryContext context)
432443}
433444block = next ;
434445}
435- while (block != NULL );
446+
447+ set -> isReset = true;
436448}
437449
438450/*
@@ -538,6 +550,8 @@ AllocSetAlloc(MemoryContext context, Size size)
538550set -> blocks = block ;
539551}
540552
553+ set -> isReset = false;
554+
541555AllocAllocInfo (set ,chunk );
542556return 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+
579596AllocAllocInfo (set ,chunk );
580597return 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+
751770AllocAllocInfo (set ,chunk );
752771return AllocChunkGetPointer (chunk );
753772}
@@ -846,6 +865,9 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
846865set -> 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)
10091031AllocSet set = (AllocSet )context ;
10101032
10111033/*
1012- * For now, we say "empty" only if the contextnever 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 contextis 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 )
10181040return true;
10191041return false;
10201042}