|
89 | 89 | *
|
90 | 90 | * With the current parameters, request sizes up to 8K are treated as chunks,
|
91 | 91 | * larger requests go into dedicated blocks. Change ALLOCSET_NUM_FREELISTS
|
92 |
| - * to adjust the boundary point. |
| 92 | + * to adjust the boundary point. (But in contexts with small maxBlockSize, |
| 93 | + * we may set the allocChunkLimit to less than 8K, so as to avoid space |
| 94 | + * wastage.) |
93 | 95 | *--------------------
|
94 | 96 | */
|
95 | 97 |
|
96 | 98 | #define ALLOC_MINBITS 3 /* smallest chunk size is 8 bytes */
|
97 | 99 | #define ALLOCSET_NUM_FREELISTS 11
|
98 | 100 | #define ALLOC_CHUNK_LIMIT (1 << (ALLOCSET_NUM_FREELISTS-1+ALLOC_MINBITS))
|
99 | 101 | /* Size of largest chunk that we use a fixed size for */
|
| 102 | +#define ALLOC_CHUNK_FRACTION 4 |
| 103 | +/* We allow chunks to be at most 1/4 of maxBlockSize (less overhead) */ |
100 | 104 |
|
101 | 105 | /*--------------------
|
102 | 106 | * The first block allocated for an allocset has size initBlockSize.
|
@@ -380,15 +384,20 @@ AllocSetContextCreate(MemoryContext parent,
|
380 | 384 | /*
|
381 | 385 | * Compute the allocation chunk size limit for this context. It can't be
|
382 | 386 | * more than ALLOC_CHUNK_LIMIT because of the fixed number of freelists.
|
383 |
| - * If maxBlockSize is small then requests exceeding the maxBlockSize |
384 |
| - * should be treated as large chunks, too. We have to have |
385 |
| - * allocChunkLimit a power of two, because the requested and |
386 |
| - * actually-allocated sizes of any chunk must be on the same side of the |
387 |
| - * limit, else we get confused about whether the chunk is "big". |
| 387 | + * If maxBlockSize is small then requests exceeding the maxBlockSize, or |
| 388 | + * even a significant fraction of it, should be treated as large chunks |
| 389 | + * too. For the typical case of maxBlockSize a power of 2, the chunk size |
| 390 | + * limit will be at most 1/8th maxBlockSize, so that given a stream of |
| 391 | + * requests that are all the maximum chunk size we will waste at most |
| 392 | + * 1/8th of the allocated space. |
| 393 | + * |
| 394 | + * We have to have allocChunkLimit a power of two, because the requested |
| 395 | + * and actually-allocated sizes of any chunk must be on the same side of |
| 396 | + * the limit, else we get confused about whether the chunk is "big". |
388 | 397 | */
|
389 | 398 | context->allocChunkLimit = ALLOC_CHUNK_LIMIT;
|
390 |
| - while (context->allocChunkLimit > |
391 |
| - (Size) (maxBlockSize - ALLOC_BLOCKHDRSZ - ALLOC_CHUNKHDRSZ)) |
| 399 | + while ((Size) (context->allocChunkLimit + ALLOC_CHUNKHDRSZ) > |
| 400 | + (Size) ((maxBlockSize - ALLOC_BLOCKHDRSZ) / ALLOC_CHUNK_FRACTION)) |
392 | 401 | context->allocChunkLimit >>= 1;
|
393 | 402 |
|
394 | 403 | /*
|
|
0 commit comments