|
11 | 11 | * Portions Copyright (c) 1994, Regents of the University of California
|
12 | 12 | *
|
13 | 13 | * IDENTIFICATION
|
14 |
| - * $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.69 2006/11/08 19:27:24 tgl Exp $ |
| 14 | + * $PostgreSQL: pgsql/src/backend/utils/mmgr/aset.c,v 1.70 2006/12/27 22:30:48 tgl Exp $ |
15 | 15 | *
|
16 | 16 | * NOTE:
|
17 | 17 | * This is a new (Feb. 05, 1999) implementation of the allocation set
|
@@ -141,6 +141,7 @@ typedef struct AllocSetContext
|
141 | 141 | Size initBlockSize; /* initial block size */
|
142 | 142 | Size maxBlockSize; /* maximum block size */
|
143 | 143 | Size nextBlockSize; /* next block size to allocate */
|
| 144 | + Size allocChunkLimit; /* effective chunk size limit */ |
144 | 145 | AllocBlock keeper; /* if not NULL, keep this block over resets */
|
145 | 146 | } AllocSetContext;
|
146 | 147 |
|
@@ -328,6 +329,20 @@ AllocSetContextCreate(MemoryContext parent,
|
328 | 329 | context->maxBlockSize = maxBlockSize;
|
329 | 330 | context->nextBlockSize = initBlockSize;
|
330 | 331 |
|
| 332 | + /* |
| 333 | + * Compute the allocation chunk size limit for this context. It can't |
| 334 | + * be more than ALLOC_CHUNK_LIMIT because of the fixed number of |
| 335 | + * freelists. If maxBlockSize is small then requests exceeding the |
| 336 | + * maxBlockSize should be treated as large chunks, too. We have to |
| 337 | + * have allocChunkLimit a power of two, because the requested and |
| 338 | + * actually-allocated sizes of any chunk must be on the same side of |
| 339 | + * the limit, else we get confused about whether the chunk is "big". |
| 340 | + */ |
| 341 | + context->allocChunkLimit = ALLOC_CHUNK_LIMIT; |
| 342 | + while (context->allocChunkLimit > |
| 343 | + (Size) (maxBlockSize - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ)) |
| 344 | + context->allocChunkLimit >>= 1; |
| 345 | + |
331 | 346 | /*
|
332 | 347 | * Grab always-allocated space, if requested
|
333 | 348 | */
|
@@ -512,7 +527,7 @@ AllocSetAlloc(MemoryContext context, Size size)
|
512 | 527 | * If requested size exceeds maximum for chunks, allocate an entire block
|
513 | 528 | * for this request.
|
514 | 529 | */
|
515 |
| - if (size > ALLOC_CHUNK_LIMIT) |
| 530 | + if (size > set->allocChunkLimit) |
516 | 531 | {
|
517 | 532 | chunk_size = MAXALIGN(size);
|
518 | 533 | blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
|
@@ -775,7 +790,7 @@ AllocSetFree(MemoryContext context, void *pointer)
|
775 | 790 | set->header.name, chunk);
|
776 | 791 | #endif
|
777 | 792 |
|
778 |
| - if (chunk->size > ALLOC_CHUNK_LIMIT) |
| 793 | + if (chunk->size > set->allocChunkLimit) |
779 | 794 | {
|
780 | 795 | /*
|
781 | 796 | * Big chunks are certain to have been allocated as single-chunk
|
@@ -868,7 +883,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
|
868 | 883 | return pointer;
|
869 | 884 | }
|
870 | 885 |
|
871 |
| - if (oldsize > ALLOC_CHUNK_LIMIT) |
| 886 | + if (oldsize > set->allocChunkLimit) |
872 | 887 | {
|
873 | 888 | /*
|
874 | 889 | * The chunk must have been allocated as a single-chunk block. Find
|
@@ -943,7 +958,7 @@ AllocSetRealloc(MemoryContext context, void *pointer, Size size)
|
943 | 958 | */
|
944 | 959 | AllocPointer newPointer;
|
945 | 960 |
|
946 |
| - if (size <= ALLOC_CHUNK_LIMIT) |
| 961 | + if (size <= set->allocChunkLimit) |
947 | 962 | {
|
948 | 963 | AllocBlock block = set->blocks;
|
949 | 964 | char *chunk_end;
|
@@ -1122,7 +1137,7 @@ AllocSetCheck(MemoryContext context)
|
1122 | 1137 | name, (unsigned long) chsize, chunk, block);
|
1123 | 1138 |
|
1124 | 1139 | /* single-chunk block? */
|
1125 |
| - if (chsize > ALLOC_CHUNK_LIMIT && |
| 1140 | + if (chsize > set->allocChunkLimit && |
1126 | 1141 | chsize + ALLOC_CHUNKHDRSZ != blk_used)
|
1127 | 1142 | elog(WARNING, "problem in alloc set %s: bad single-chunk %p in block %p",
|
1128 | 1143 | name, chunk, block);
|
|
0 commit comments