mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2025-12-20 15:10:08 +01:00
[script] Slab allocator
Allocate small objects from a pool and maintain a per-size free-list.
This commit is contained in:
parent
83f0e6cf62
commit
c5c04528b5
2 changed files with 85 additions and 2 deletions
|
|
@ -41,6 +41,10 @@
|
|||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifndef MAX
|
||||
#define MAX(a,b) (((a)>=(b))?(a):(b))
|
||||
#endif
|
||||
|
||||
csi_status_t
|
||||
_csi_error (csi_status_t status)
|
||||
{
|
||||
|
|
@ -90,19 +94,74 @@ _csi_free (csi_t *ctx, void *ptr)
|
|||
void *
|
||||
_csi_slab_alloc (csi_t *ctx, int size)
|
||||
{
|
||||
int chunk_size;
|
||||
csi_chunk_t *chunk;
|
||||
void *ptr;
|
||||
|
||||
if (_csi_unlikely (ctx->status))
|
||||
return NULL;
|
||||
|
||||
return malloc (size);
|
||||
chunk_size = 2 * sizeof (void *);
|
||||
chunk_size = (size + chunk_size - 1) / chunk_size;
|
||||
|
||||
if (ctx->slabs[chunk_size].free_list) {
|
||||
ptr = ctx->slabs[chunk_size].free_list;
|
||||
ctx->slabs[chunk_size].free_list = *(void **) ptr;
|
||||
return ptr;
|
||||
}
|
||||
|
||||
chunk = ctx->slabs[chunk_size].chunk;
|
||||
if (chunk == NULL || ! chunk->rem) {
|
||||
int cnt = MAX (128, 8192 / (chunk_size * 2 * sizeof (void *)));
|
||||
|
||||
chunk = _csi_alloc (ctx,
|
||||
sizeof (csi_chunk_t) +
|
||||
cnt * chunk_size * 2 * sizeof (void *));
|
||||
if (_csi_unlikely (chunk == NULL))
|
||||
return NULL;
|
||||
|
||||
chunk->rem = cnt;
|
||||
chunk->ptr = (char *) (chunk + 1);
|
||||
chunk->next = ctx->slabs[chunk_size].chunk;
|
||||
ctx->slabs[chunk_size].chunk = chunk;
|
||||
}
|
||||
|
||||
ptr = chunk->ptr;
|
||||
chunk->ptr += chunk_size * 2 * sizeof (void *);
|
||||
chunk->rem--;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
void
|
||||
_csi_slab_free (csi_t *ctx, void *ptr, int size)
|
||||
{
|
||||
int chunk_size;
|
||||
void **free_list;
|
||||
|
||||
if (_csi_unlikely (ptr == NULL))
|
||||
return;
|
||||
|
||||
free (ptr);
|
||||
chunk_size = 2 * sizeof (void *);
|
||||
chunk_size = (size + chunk_size - 1) / chunk_size;
|
||||
|
||||
free_list = ptr;
|
||||
*free_list = ctx->slabs[chunk_size].free_list;
|
||||
ctx->slabs[chunk_size].free_list = ptr;
|
||||
}
|
||||
|
||||
static void
|
||||
_csi_slab_fini (csi_t *ctx)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < sizeof (ctx->slabs) / sizeof (ctx->slabs[0]); i++) {
|
||||
while (ctx->slabs[i].chunk != NULL) {
|
||||
csi_chunk_t *chunk = ctx->slabs[i].chunk;
|
||||
ctx->slabs[i].chunk = chunk->next;
|
||||
_csi_free (ctx, chunk);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static csi_status_t
|
||||
|
|
@ -318,6 +377,8 @@ _csi_fini (csi_t *ctx)
|
|||
|
||||
_csi_hash_table_foreach (&ctx->strings, _intern_string_pluck, ctx);
|
||||
_csi_hash_table_fini (&ctx->strings);
|
||||
|
||||
_csi_slab_fini (ctx);
|
||||
}
|
||||
|
||||
csi_status_t
|
||||
|
|
|
|||
|
|
@ -409,6 +409,17 @@ struct _csi_file {
|
|||
const csi_filter_funcs_t *filter;
|
||||
};
|
||||
|
||||
union _csi_union_object {
|
||||
void *ptr[2];
|
||||
csi_stack_t stack;
|
||||
csi_array_t arry;
|
||||
csi_dictionary_t dictionary;
|
||||
csi_matrix_t matrix;
|
||||
csi_string_t string;
|
||||
csi_file_t file;
|
||||
csi_object_t object;
|
||||
};
|
||||
|
||||
struct _csi_scanner {
|
||||
csi_status_t status;
|
||||
|
||||
|
|
@ -432,6 +443,12 @@ struct _csi_scanner {
|
|||
|
||||
typedef cairo_script_interpreter_hooks_t csi_hooks_t;
|
||||
|
||||
typedef struct _csi_chunk {
|
||||
struct _csi_chunk *next;
|
||||
int rem;
|
||||
char *ptr;
|
||||
} csi_chunk_t;
|
||||
|
||||
struct _cairo_script_interpreter {
|
||||
int ref_count;
|
||||
csi_status_t status;
|
||||
|
|
@ -445,6 +462,11 @@ struct _cairo_script_interpreter {
|
|||
|
||||
csi_scanner_t scanner;
|
||||
|
||||
struct {
|
||||
csi_chunk_t *chunk;
|
||||
void *free_list;
|
||||
} slabs[(sizeof (union _csi_union_object) + (2*sizeof (void *)-1))/ (2*sizeof (void*))];
|
||||
|
||||
/* caches of live data */
|
||||
csi_list_t *_images;
|
||||
csi_list_t *_faces;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue