summaryrefslogtreecommitdiff
path: root/fitz/base_memory.c
diff options
context:
space:
mode:
Diffstat (limited to 'fitz/base_memory.c')
-rw-r--r--fitz/base_memory.c57
1 files changed, 49 insertions, 8 deletions
diff --git a/fitz/base_memory.c b/fitz/base_memory.c
index 79ae38b0..17a701e2 100644
--- a/fitz/base_memory.c
+++ b/fitz/base_memory.c
@@ -1,9 +1,48 @@
#include "fitz.h"
+static void *
+do_scavenging_malloc(fz_context *ctx, unsigned int size)
+{
+ void *p;
+ int phase = 0;
+
+ /* LOCK */
+ do {
+ p = ctx->alloc->malloc(ctx->alloc->user, size);
+ if (p != NULL)
+ return p;
+ } while (fz_store_scavenge(ctx, size, &phase));
+ /* UNLOCK */
+
+ return NULL;
+}
+
+static void *
+do_scavenging_realloc(fz_context *ctx, void *p, unsigned int size)
+{
+ void *q;
+ int phase = 0;
+
+ /* LOCK */
+ do {
+ q = ctx->alloc->realloc(ctx->alloc->user, p, size);
+ if (q != NULL)
+ return q;
+ } while (fz_store_scavenge(ctx, size, &phase));
+ /* UNLOCK */
+
+ return NULL;
+}
+
void *
fz_malloc(fz_context *ctx, unsigned int size)
{
- void *p = ctx->alloc->malloc(ctx->alloc->user, size);
+ void *p;
+
+ if (size == 0)
+ return NULL;
+
+ p = do_scavenging_malloc(ctx, size);
if (!p)
fz_throw(ctx, "malloc of %d bytes failed", size);
return p;
@@ -12,7 +51,7 @@ fz_malloc(fz_context *ctx, unsigned int size)
void *
fz_malloc_no_throw(fz_context *ctx, unsigned int size)
{
- return ctx->alloc->malloc(ctx->alloc->user, size);
+ return do_scavenging_malloc(ctx, size);
}
void *
@@ -26,7 +65,7 @@ fz_malloc_array(fz_context *ctx, unsigned int count, unsigned int size)
if (count > UINT_MAX / size)
fz_throw(ctx, "malloc of array (%d x %d bytes) failed (integer overflow)", count, size);
- p = ctx->alloc->malloc(ctx->alloc->user, count * size);
+ p = do_scavenging_malloc(ctx, count * size);
if (!p)
fz_throw(ctx, "malloc of array (%d x %d bytes) failed", count, size);
return p;
@@ -44,7 +83,7 @@ fz_malloc_array_no_throw(fz_context *ctx, unsigned int count, unsigned int size)
return NULL;
}
- return ctx->alloc->malloc(ctx->alloc->user, count * size);
+ return do_scavenging_malloc(ctx, count * size);
}
void *
@@ -60,7 +99,7 @@ fz_calloc(fz_context *ctx, unsigned int count, unsigned int size)
fz_throw(ctx, "calloc (%d x %d bytes) failed (integer overflow)", count, size);
}
- p = ctx->alloc->malloc(ctx->alloc->user, count * size);
+ p = do_scavenging_malloc(ctx, count * size);
if (!p)
{
fz_throw(ctx, "calloc (%d x %d bytes) failed", count, size);
@@ -83,7 +122,7 @@ fz_calloc_no_throw(fz_context *ctx, unsigned int count, unsigned int size)
return NULL;
}
- p = ctx->alloc->malloc(ctx->alloc->user, count * size);
+ p = do_scavenging_malloc(ctx, count * size);
if (p)
{
memset(p, 0, count*size);
@@ -105,7 +144,7 @@ fz_resize_array(fz_context *ctx, void *p, unsigned int count, unsigned int size)
if (count > UINT_MAX / size)
fz_throw(ctx, "resize array (%d x %d bytes) failed (integer overflow)", count, size);
- np = ctx->alloc->realloc(ctx->alloc->user, p, count * size);
+ np = do_scavenging_realloc(ctx, p, count * size);
if (!np)
fz_throw(ctx, "resize array (%d x %d bytes) failed", count, size);
return np;
@@ -126,13 +165,15 @@ fz_resize_array_no_throw(fz_context *ctx, void *p, unsigned int count, unsigned
return NULL;
}
- return ctx->alloc->realloc(ctx->alloc->user, p, count * size);
+ return do_scavenging_realloc(ctx, p, count * size);
}
void
fz_free(fz_context *ctx, void *p)
{
+ /* LOCK */
ctx->alloc->free(ctx->alloc->user, p);
+ /* UNLOCK */
}
char *