#include <njs_clang.h>
#include <njs_stub.h>
#include <njs_str.h>
+#include <njs_sprintf.h>
+#include <njs_malloc.h>
#include <njs_queue.h>
#include <njs_rbtree.h>
#include <njs_mp.h>
uint32_t page_alignment;
uint32_t cluster_size;
- const njs_mem_proto_t *proto;
- void *mem;
- void *trace;
-
njs_mp_slot_t slots[];
};
njs_mp_t *
-njs_mp_create(const njs_mem_proto_t *proto, void *mem,
- void *trace, size_t cluster_size, size_t page_alignment, size_t page_size,
+njs_mp_create(size_t cluster_size, size_t page_alignment, size_t page_size,
size_t min_chunk_size)
{
/* Alignment and sizes must be a power of 2. */
return NULL;
}
- return njs_mp_fast_create(proto, mem, trace, cluster_size, page_alignment,
- page_size, min_chunk_size);
+ return njs_mp_fast_create(cluster_size, page_alignment, page_size,
+ min_chunk_size);
}
njs_mp_t *
-njs_mp_fast_create(const njs_mem_proto_t *proto, void *mem,
- void *trace, size_t cluster_size, size_t page_alignment, size_t page_size,
+njs_mp_fast_create(size_t cluster_size, size_t page_alignment, size_t page_size,
size_t min_chunk_size)
{
njs_mp_t *mp;
chunk_size /= 2;
} while (chunk_size > min_chunk_size);
- mp = proto->zalloc(mem, sizeof(njs_mp_t) + slots * sizeof(njs_mp_slot_t));
+ mp = njs_zalloc(sizeof(njs_mp_t) + slots * sizeof(njs_mp_slot_t));
if (njs_fast_path(mp != NULL)) {
- mp->proto = proto;
- mp->mem = mem;
- mp->trace = trace;
-
mp->page_size = page_size;
mp->page_alignment = njs_max(page_alignment, NJS_MAX_ALIGNMENT);
mp->cluster_size = cluster_size;
njs_mp_block_t *block;
njs_rbtree_node_t *node, *next;
+ njs_debug_alloc("mp destroy\n");
+
next = njs_rbtree_root(&mp->blocks);
while (next != njs_rbtree_sentinel(&mp->blocks)) {
p = block->start;
if (block->type != NJS_MP_EMBEDDED_BLOCK) {
- mp->proto->free(mp->mem, block);
+ njs_free(block);
}
- mp->proto->free(mp->mem, p);
+ njs_free(p);
}
- mp->proto->free(mp->mem, mp);
+ njs_free(mp);
}
void *
njs_mp_alloc(njs_mp_t *mp, size_t size)
{
- if (mp->proto->trace != NULL) {
- mp->proto->trace(mp->trace, "mem cache alloc: %zd", size);
- }
+ njs_debug_alloc("mp alloc: %uz\n", size);
#if !(NJS_DEBUG_MEMORY)
void *
njs_mp_align(njs_mp_t *mp, size_t alignment, size_t size)
{
- if (mp->proto->trace != NULL) {
- mp->proto->trace(mp->trace,
- "mem cache align: @%zd:%zd", alignment, size);
- }
+ njs_debug_alloc("mp align: @%uz:%uz\n", alignment, size);
/* Alignment must be a power of 2. */
#endif
}
- if (mp->proto->trace != NULL) {
- mp->proto->trace(mp->trace, "mem cache chunk:%uz alloc: %p", size, p);
- }
+ njs_debug_alloc("mp chunk:%uz alloc: %p\n", size, p);
return p;
}
n = mp->cluster_size >> mp->page_size_shift;
- cluster = mp->proto->zalloc(mp->mem,
- sizeof(njs_mp_block_t)
- + n * sizeof(njs_mp_page_t));
+ cluster = njs_zalloc(sizeof(njs_mp_block_t) + n * sizeof(njs_mp_page_t));
if (njs_slow_path(cluster == NULL)) {
return NULL;
cluster->size = mp->cluster_size;
- cluster->start = mp->proto->align(mp->mem, mp->page_alignment,
- mp->cluster_size);
+ cluster->start = njs_memalign(mp->page_alignment, mp->cluster_size);
if (njs_slow_path(cluster->start == NULL)) {
- mp->proto->free(mp->mem, cluster);
+ njs_free(cluster);
return NULL;
}
}
if (njs_is_power_of_two(size)) {
- block = mp->proto->alloc(mp->mem, sizeof(njs_mp_block_t));
+ block = njs_malloc(sizeof(njs_mp_block_t));
if (njs_slow_path(block == NULL)) {
return NULL;
}
- p = mp->proto->align(mp->mem, alignment, size);
+ p = njs_memalign(alignment, size);
if (njs_slow_path(p == NULL)) {
- mp->proto->free(mp->mem, block);
+ njs_free(block);
return NULL;
}
} else {
aligned_size = njs_align_size(size, sizeof(uintptr_t));
- p = mp->proto->align(mp->mem, alignment,
- aligned_size + sizeof(njs_mp_block_t));
-
+ p = njs_memalign(alignment, aligned_size + sizeof(njs_mp_block_t));
if (njs_slow_path(p == NULL)) {
return NULL;
}
const char *err;
njs_mp_block_t *block;
- if (mp->proto->trace != NULL) {
- mp->proto->trace(mp->trace, "mem cache free %p", p);
- }
+ njs_debug_alloc("mp free: @%p\n", p);
block = njs_mp_find_block(&mp->blocks, p);
njs_rbtree_delete(&mp->blocks, &block->node);
if (block->type == NJS_MP_DISCRETE_BLOCK) {
- mp->proto->free(mp->mem, block);
+ njs_free(block);
}
- mp->proto->free(mp->mem, p);
+ njs_free(p);
return;
} else {
- err = "freed pointer points to middle of block: %p";
+ err = "freed pointer points to middle of block: %p\n";
}
} else {
- err = "freed pointer is out of mp: %p";
+ err = "freed pointer is out of mp: %p\n";
}
- if (mp->proto->alert != NULL) {
- mp->proto->alert(mp->trace, err, p);
- }
+ njs_debug_alloc(err, p);
}
p = cluster->start;
- mp->proto->free(mp->mem, cluster);
- mp->proto->free(mp->mem, p);
+ njs_free(cluster);
+ njs_free(p);
return NULL;
}
typedef struct njs_mp_s njs_mp_t;
-NJS_EXPORT njs_mp_t *njs_mp_create(const njs_mem_proto_t *proto, void *mem,
- void *trace, size_t cluster_size, size_t page_alignment, size_t page_size,
- size_t min_chunk_size)
- NJS_MALLOC_LIKE;
-NJS_EXPORT njs_mp_t * njs_mp_fast_create(const njs_mem_proto_t *proto,
- void *mem, void *trace, size_t cluster_size, size_t page_alignment,
- size_t page_size, size_t min_chunk_size)
+NJS_EXPORT njs_mp_t *njs_mp_create(size_t cluster_size, size_t page_alignment,
+ size_t page_size, size_t min_chunk_size) NJS_MALLOC_LIKE;
+NJS_EXPORT njs_mp_t * njs_mp_fast_create(size_t cluster_size,
+ size_t page_alignment, size_t page_size, size_t min_chunk_size)
NJS_MALLOC_LIKE;
NJS_EXPORT njs_bool_t njs_mp_is_empty(njs_mp_t *mp);
NJS_EXPORT void njs_mp_destroy(njs_mp_t *mp);
NJS_EXPORT void njs_mp_free(njs_mp_t *mp, void *p);
+#if (NJS_ALLOC_DEBUG)
+#define njs_debug_alloc(...) \
+ njs_stderror(__VA_ARGS__)
+
+#else
+
+#define njs_debug_alloc(...)
+
+#endif
+
+
#endif /* _NJS_MP_H_INCLUDED_ */
const njs_str_t njs_entry_anonymous = njs_str("anonymous");
-static void *
-njs_alloc(void *mem, size_t size)
-{
- return njs_malloc(size);
-}
-
-
-static void *
-njs_zalloc(void *mem, size_t size)
-{
- void *p;
-
- p = njs_malloc(size);
-
- if (p != NULL) {
- njs_memzero(p, size);
- }
-
- return p;
-}
-
-
-static void *
-njs_align(void *mem, size_t alignment, size_t size)
-{
- return njs_memalign(alignment, size);
-}
-
-
-static void
-njs_free2(void *mem, void *p)
-{
- njs_free(p);
-}
-
-
-const njs_mem_proto_t njs_vm_mp_proto = {
- njs_alloc,
- njs_zalloc,
- njs_align,
- NULL,
- njs_free2,
- NULL,
- NULL,
-};
-
-
static void *
njs_array_mem_alloc(void *mem, size_t size)
{
njs_arr_t *debug;
njs_regexp_pattern_t *pattern;
- mp = njs_mp_create(&njs_vm_mp_proto, NULL, NULL, 2 * njs_pagesize(),
- 128, 512, 16);
+ mp = njs_mp_fast_create(2 * njs_pagesize(), 128, 512, 16);
if (njs_slow_path(mp == NULL)) {
return NULL;
}
return NULL;
}
- nmp = njs_mp_create(&njs_vm_mp_proto, NULL, NULL, 2 * njs_pagesize(),
- 128, 512, 16);
+ nmp = njs_mp_fast_create(2 * njs_pagesize(), 128, 512, 16);
if (njs_slow_path(nmp == NULL)) {
return NULL;
}
}
-static void *
-lvlhsh_malloc(void *mem, size_t size)
-{
- return njs_malloc(size);
-}
-
-
-static void *
-lvlhsh_zalloc(void *mem, size_t size)
-{
- void *p;
-
- p = njs_malloc(size);
-
- if (p != NULL) {
- njs_memzero(p, size);
- }
-
- return p;
-}
-
-
-static void *
-lvlhsh_align(void *mem, size_t alignment, size_t size)
-{
- return njs_memalign(alignment, size);
-}
-
-
-static void
-lvlhsh_free(void *mem, void *p)
-{
- njs_free(p);
-}
-
-
-static void
-lvlhsh_alert(void *mem, const char *fmt, ...)
-{
- u_char buf[1024], *p;
- va_list args;
-
- va_start(args, fmt);
- p = njs_sprintf(buf, buf + sizeof(buf), fmt, args);
- va_end(args);
-
- (void) njs_stderror("alert: \"%*s\"\n", p - buf, buf);
-}
-
-
-static const njs_mem_proto_t lvl_mp_proto = {
- lvlhsh_malloc,
- lvlhsh_zalloc,
- lvlhsh_align,
- NULL,
- lvlhsh_free,
- lvlhsh_alert,
- NULL,
-};
-
-
static njs_int_t
lvlhsh_unit_test(njs_uint_t n)
{
const size_t page_alignment = 128;
const size_t cluster_size = 4096;
- pool = njs_mp_create(&lvl_mp_proto, NULL, NULL, cluster_size,
- page_alignment, page_size, min_chunk_size);
+ pool = njs_mp_create(cluster_size, page_alignment, page_size,
+ min_chunk_size);
if (pool == NULL) {
return NJS_ERROR;
}