aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2003-09-13 22:25:38 +0000
committerTom Lane <tgl@sss.pgh.pa.us>2003-09-13 22:25:38 +0000
commit4cf6e9e081be62c28ecdeb8ca2672651d107925a (patch)
tree05a98e669d69a487514485da9afb297f4d790f3b
parentc472b8366f5bec1da4d5d5b894f47508bbc8d5d6 (diff)
downloadpostgresql-4cf6e9e081be62c28ecdeb8ca2672651d107925a.tar.gz
postgresql-4cf6e9e081be62c28ecdeb8ca2672651d107925a.zip
Avoid corner cases where aset.c would unnecessarily make malloc()
requests of sizes that aren't powers of 2. Per observation from David Schultz, 28-Aug.
-rw-r--r--src/backend/utils/mmgr/aset.c33
1 files changed, 15 insertions, 18 deletions
diff --git a/src/backend/utils/mmgr/aset.c b/src/backend/utils/mmgr/aset.c
index fddcad7a29b..b36596734d7 100644
--- a/src/backend/utils/mmgr/aset.c
+++ b/src/backend/utils/mmgr/aset.c
@@ -11,7 +11,7 @@
* Portions Copyright (c) 1994, Regents of the University of California
*
* IDENTIFICATION
- * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.52 2003/08/04 02:40:08 momjian Exp $
+ * $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.53 2003/09/13 22:25:38 tgl Exp $
*
* NOTE:
* This is a new (Feb. 05, 1999) implementation of the allocation set
@@ -650,32 +650,29 @@ AllocSetAlloc(MemoryContext context, Size size)
}
else
{
- /* Get size of prior block */
- blksize = set->blocks->endptr - ((char *) set->blocks);
-
/*
- * Special case: if very first allocation was for a large
- * chunk (or we have a small "keeper" block), could have an
- * undersized top block. Do something reasonable.
+ * Use first power of 2 that is larger than previous block,
+ * but not more than the allowed limit. (We don't simply double
+ * the prior block size, because in some cases this could be a
+ * funny size, eg if very first allocation was for an odd-sized
+ * large chunk.)
*/
- if (blksize < set->initBlockSize)
- blksize = set->initBlockSize;
- else
- {
- /* Crank it up, but not past max */
+ Size pblksize = set->blocks->endptr - ((char *) set->blocks);
+
+ blksize = set->initBlockSize;
+ while (blksize <= pblksize)
blksize <<= 1;
- if (blksize > set->maxBlockSize)
- blksize = set->maxBlockSize;
- }
+ if (blksize > set->maxBlockSize)
+ blksize = set->maxBlockSize;
}
/*
* If initBlockSize is less than ALLOC_CHUNK_LIMIT, we could need
- * more space...
+ * more space... but try to keep it a power of 2.
*/
required_size = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
- if (blksize < required_size)
- blksize = required_size;
+ while (blksize < required_size)
+ blksize <<= 1;
/* Try to allocate it */
block = (AllocBlock) malloc(blksize);