summaryrefslogtreecommitdiff
path: root/source/fitz/pool.c
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2018-01-23 12:42:22 +0100
committerTor Andersson <tor.andersson@artifex.com>2018-01-24 14:13:19 +0100
commit813144d395bbeac926645f805e03ef9c29aad214 (patch)
tree53b2604a8952fcb1bfa8e4c53f10f1b2362c7158 /source/fitz/pool.c
parent2bc74c6683f4e45c4d7f60c652f906f2bc97db34 (diff)
downloadmupdf-813144d395bbeac926645f805e03ef9c29aad214.tar.xz
Allow oversize allocations in pool allocator.
Diffstat (limited to 'source/fitz/pool.c')
-rw-r--r--source/fitz/pool.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/source/fitz/pool.c b/source/fitz/pool.c
index a2cb6ffe..845fc40d 100644
--- a/source/fitz/pool.c
+++ b/source/fitz/pool.c
@@ -1,9 +1,13 @@
#include "mupdf/fitz.h"
#include <string.h>
+#include <stdio.h>
typedef struct fz_pool_node_s fz_pool_node;
+#define POOL_SIZE (64<<10) /* default size of pool blocks */
+#define POOL_SELF (4<<10) /* size where allocs are put into their own blocks */
+
struct fz_pool_s
{
fz_pool_node *head, *tail;
@@ -13,34 +17,47 @@ struct fz_pool_s
struct fz_pool_node_s
{
fz_pool_node *next;
- char mem[64 << 10]; /* 64k blocks */
+ char mem[1];
};
fz_pool *fz_new_pool(fz_context *ctx)
{
fz_pool *pool = fz_malloc_struct(ctx, fz_pool);
- fz_pool_node *node = fz_malloc_struct(ctx, fz_pool_node);
+ fz_pool_node *node = fz_calloc(ctx, offsetof(fz_pool_node, mem) + POOL_SIZE, 1);
pool->head = pool->tail = node;
pool->pos = node->mem;
- pool->end = node->mem + sizeof node->mem;
+ pool->end = node->mem + POOL_SIZE;
return pool;
}
+static void *fz_pool_alloc_oversize(fz_context *ctx, fz_pool *pool, size_t size)
+{
+ fz_pool_node *node;
+
+ /* link in memory at the head of the list */
+ node = fz_calloc(ctx, offsetof(fz_pool_node, mem) + size, 1);
+ node->next = pool->head;
+ pool->head = node;
+
+ return node->mem;
+}
+
void *fz_pool_alloc(fz_context *ctx, fz_pool *pool, size_t size)
{
char *ptr;
+ if (size >= POOL_SELF)
+ return fz_pool_alloc_oversize(ctx, pool, size);
+
/* round size to pointer alignment (we don't expect to use doubles) */
size = ((size + sizeof(void*) - 1) / sizeof(void*)) * sizeof(void*);
if (pool->pos + size > pool->end)
{
- fz_pool_node *node = fz_malloc_struct(ctx, fz_pool_node);
+ fz_pool_node *node = fz_calloc(ctx, offsetof(fz_pool_node, mem) + POOL_SIZE, 1);
pool->tail = pool->tail->next = node;
pool->pos = node->mem;
- pool->end = node->mem + sizeof node->mem;
- if (pool->pos + size > pool->end)
- fz_throw(ctx, FZ_ERROR_GENERIC, "out of memory: allocation too large to fit in pool");
+ pool->end = node->mem + POOL_SIZE;
}
ptr = pool->pos;
pool->pos += size;