From af13a3363cf7b1449b6088d3bbbafbb76e409057 Mon Sep 17 00:00:00 2001 From: hyung-hwan Date: Sun, 15 Jun 2025 17:23:23 +0900 Subject: [PATCH] added some more statistics in xma --- lib/hcl-xma.h | 22 ++++--- lib/hcl.c | 175 +++++++++++++++++++++++++------------------------- lib/xma.c | 145 ++++++++++++++++++++++++++++------------- 3 files changed, 200 insertions(+), 142 deletions(-) diff --git a/lib/hcl-xma.h b/lib/hcl-xma.h index 23579fb..6ee3ca3 100644 --- a/lib/hcl-xma.h +++ b/lib/hcl-xma.h @@ -72,9 +72,7 @@ */ #include -#ifdef HCL_BUILD_DEBUG -# define HCL_XMA_ENABLE_STAT -#endif +#define HCL_XMA_ENABLE_STAT /** @struct hcl_xma_t * The hcl_xma_t type defines a simple memory allocator over a memory zone. @@ -105,14 +103,22 @@ struct hcl_xma_t /** pre-computed value for fast xfree index calculation */ hcl_oow_t bdec; -#ifdef HCL_XMA_ENABLE_STAT +#if defined(HCL_XMA_ENABLE_STAT) struct { hcl_oow_t total; - hcl_oow_t alloc; - hcl_oow_t avail; - hcl_oow_t nused; - hcl_oow_t nfree; + hcl_oow_t alloc; /* allocated size */ + hcl_oow_t avail; /* available size */ + hcl_oow_t nused; /* nubmer of used blocks */ + hcl_oow_t nfree; /* number of free blocks */ + hcl_oow_t alloc_hwmark; /* high watermark - highest total memory ever allocated */ + hcl_oow_t nallocops; /* number of alloc operations */ + hcl_oow_t nallocgoodops; /* number of successful alloc operations */ + hcl_oow_t nallocbadops; /* number of failed alloc operations */ + hcl_oow_t nreallocops; /* number of realloc operations */ + hcl_oow_t nreallocgoodops; /* number of good realloc operations */ + hcl_oow_t nreallocbadops; /* number of failed realloc operations - could fall back to normal alloc*/ + hcl_oow_t nfreeops; /* number of free operations */ } stat; #endif }; diff --git a/lib/hcl.c b/lib/hcl.c index a45b99b..9c02995 100644 --- a/lib/hcl.c +++ b/lib/hcl.c @@ -29,7 +29,7 @@ hcl_t* hcl_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, const hcl_vmprim_t* vmprim hcl_t* hcl; /* if this assertion fails, correct the type definition in hcl.h */ - HCL_ASSERT (hcl, HCL_SIZEOF(hcl_oow_t) == HCL_SIZEOF(hcl_oop_t)); + HCL_ASSERT(hcl, HCL_SIZEOF(hcl_oow_t) == HCL_SIZEOF(hcl_oop_t)); hcl = (hcl_t*)HCL_MMGR_ALLOC(mmgr, HCL_SIZEOF(*hcl) + xtnsize); if (hcl) @@ -106,7 +106,7 @@ static void* alloc_heap (hcl_t* hcl, hcl_oow_t* size) static void free_heap (hcl_t* hcl, void* ptr) { - hcl_freemem (hcl, ptr); + hcl_freemem(hcl, ptr); } int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, const hcl_vmprim_t* vmprim) @@ -116,19 +116,19 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, const hcl_vmprim_t* vmprim) if (!vmprim->syserrstrb && !vmprim->syserrstru) { - hcl_seterrnum (hcl, HCL_EINVAL); + hcl_seterrnum(hcl, HCL_EINVAL); return -1; } #if !defined(HCL_BUILD_RELEASE) if (!vmprim->assertfail) { - hcl_seterrnum (hcl, HCL_EINVAL); + hcl_seterrnum(hcl, HCL_EINVAL); return -1; } #endif - HCL_MEMSET (hcl, 0, HCL_SIZEOF(*hcl)); + HCL_MEMSET(hcl, 0, HCL_SIZEOF(*hcl)); hcl->_instsize = HCL_SIZEOF(*hcl); hcl->_mmgr = mmgr; hcl->_cmgr = hcl_get_utf8_cmgr(); @@ -188,13 +188,13 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, const hcl_vmprim_t* vmprim) return 0; oops: - if (modtab_inited) hcl_rbt_fini (&hcl->modtab); + if (modtab_inited) hcl_rbt_fini(&hcl->modtab); if (hcl->gci.stack.ptr) { - hcl_freemem (hcl, hcl->gci.stack.ptr); + hcl_freemem(hcl, hcl->gci.stack.ptr); hcl->gci.stack.capa = 0; } - if (hcl->log.ptr) hcl_freemem (hcl, hcl->log.ptr); + if (hcl->log.ptr) hcl_freemem(hcl, hcl->log.ptr); hcl->log.capa = 0; return -1; } @@ -205,10 +205,10 @@ static hcl_rbt_walk_t unload_module (hcl_rbt_t* rbt, hcl_rbt_pair_t* pair, void* hcl_mod_data_t* mdp; mdp = (hcl_mod_data_t*)HCL_RBT_VPTR(pair); - HCL_ASSERT (hcl, mdp != HCL_NULL); + HCL_ASSERT(hcl, mdp != HCL_NULL); mdp->pair = HCL_NULL; /* to prevent hcl_closemod() from calling hcl_rbt_delete() */ - hcl_closemod (hcl, mdp); + hcl_closemod(hcl, mdp); return HCL_RBT_WALK_FORWARD; } @@ -218,14 +218,14 @@ void hcl_fini (hcl_t* hcl) hcl_cb_t* cb; hcl_oow_t i; - hcl_rbt_walk (&hcl->modtab, unload_module, hcl); - hcl_rbt_fini (&hcl->modtab); + hcl_rbt_walk(&hcl->modtab, unload_module, hcl); + hcl_rbt_fini(&hcl->modtab); if (hcl->log.len > 0) { /* flush pending log messages just in case. */ - HCL_ASSERT (hcl, hcl->log.ptr != HCL_NULL); - HCL_VMPRIM_LOG_WRITE (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len); + HCL_ASSERT(hcl, hcl->log.ptr != HCL_NULL); + HCL_VMPRIM_LOG_WRITE(hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len); } for (cb = hcl->cblist; cb; cb = cb->next) @@ -239,57 +239,57 @@ void hcl_fini (hcl_t* hcl) * callbacks. however, the actual logging might not be produced at * this point because one of the callbacks could arrange to stop * logging */ - HCL_ASSERT (hcl, hcl->log.ptr != HCL_NULL); - HCL_VMPRIM_LOG_WRITE (hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len); + HCL_ASSERT(hcl, hcl->log.ptr != HCL_NULL); + HCL_VMPRIM_LOG_WRITE(hcl, hcl->log.last_mask, hcl->log.ptr, hcl->log.len); } /* deregister all callbacks */ - while (hcl->cblist) hcl_deregcb (hcl, hcl->cblist); + while (hcl->cblist) hcl_deregcb(hcl, hcl->cblist); /* detach the user data io handlers just in case */ hcl_detachudio (hcl); if (hcl->sem_list) { - hcl_freemem (hcl, hcl->sem_list); + hcl_freemem(hcl, hcl->sem_list); hcl->sem_list_capa = 0; hcl->sem_list_count = 0; } if (hcl->sem_heap) { - hcl_freemem (hcl, hcl->sem_heap); + hcl_freemem(hcl, hcl->sem_heap); hcl->sem_heap_capa = 0; hcl->sem_heap_count = 0; } if (hcl->sem_io_tuple) { - hcl_freemem (hcl, hcl->sem_io_tuple); + hcl_freemem(hcl, hcl->sem_io_tuple); hcl->sem_io_tuple_capa = 0; hcl->sem_io_tuple_count = 0; } if (hcl->sem_io_map) { - hcl_freemem (hcl, hcl->sem_io_map); + hcl_freemem(hcl, hcl->sem_io_map); hcl->sem_io_map_capa = 0; } if (hcl->proc_map) { - hcl_freemem (hcl, hcl->proc_map); + hcl_freemem(hcl, hcl->proc_map); hcl->proc_map_capa = 0; hcl->proc_map_used = 0; hcl->proc_map_free_first = -1; hcl->proc_map_free_last = -1; } - hcl_purgecode (hcl, &hcl->code); + hcl_purgecode(hcl, &hcl->code); if (hcl->p.s.ptr) { - hcl_freemem (hcl, hcl->p.s.ptr); + hcl_freemem(hcl, hcl->p.s.ptr); hcl->p.s.ptr= HCL_NULL; hcl->p.s.capa = 0; hcl->p.s.size = 0; @@ -302,51 +302,51 @@ void hcl_fini (hcl_t* hcl) { next = hcl->gci.b->next; hcl->gci.bsz -= HCL_SIZEOF(hcl_obj_t) + hcl_getobjpayloadbytes(hcl, (hcl_oop_t)(hcl->gci.b + 1)); - hcl_freeheapmem (hcl, hcl->heap, hcl->gci.b); + hcl_freeheapmem(hcl, hcl->heap, hcl->gci.b); hcl->gci.b = next; } while (hcl->gci.b); - HCL_ASSERT (hcl, hcl->gci.bsz == 0); + HCL_ASSERT(hcl, hcl->gci.bsz == 0); } if (hcl->gci.stack.ptr) { - hcl_freemem (hcl, hcl->gci.stack.ptr); + hcl_freemem(hcl, hcl->gci.stack.ptr); hcl->gci.stack.ptr = 0; hcl->gci.stack.capa = 0; hcl->gci.stack.len = 0; } - if (hcl->heap) hcl_killheap (hcl, hcl->heap); + if (hcl->heap) hcl_killheap(hcl, hcl->heap); if (hcl->log.ptr) { - hcl_freemem (hcl, hcl->log.ptr); + hcl_freemem(hcl, hcl->log.ptr); hcl->log.capa = 0; hcl->log.len = 0; } if (hcl->option.log_target_u) { - hcl_freemem (hcl, hcl->option.log_target_u); + hcl_freemem(hcl, hcl->option.log_target_u); hcl->option.log_target_u = HCL_NULL; } if (hcl->option.log_target_b) { - hcl_freemem (hcl, hcl->option.log_target_b); + hcl_freemem(hcl, hcl->option.log_target_b); hcl->option.log_target_b = HCL_NULL; } for (i = 0; i < HCL_COUNTOF(hcl->option.mod); i++) { - if (hcl->option.mod[i].ptr) hcl_freemem (hcl, hcl->option.mod[i].ptr); + if (hcl->option.mod[i].ptr) hcl_freemem(hcl, hcl->option.mod[i].ptr); } if (hcl->inttostr.xbuf.ptr) { - hcl_freemem (hcl, hcl->inttostr.xbuf.ptr); + hcl_freemem(hcl, hcl->inttostr.xbuf.ptr); hcl->inttostr.xbuf.ptr = HCL_NULL; hcl->inttostr.xbuf.capa = 0; hcl->inttostr.xbuf.len = 0; @@ -354,14 +354,14 @@ void hcl_fini (hcl_t* hcl) if (hcl->inttostr.t.ptr) { - hcl_freemem (hcl, hcl->inttostr.t.ptr); + hcl_freemem(hcl, hcl->inttostr.t.ptr); hcl->inttostr.t.ptr = HCL_NULL; hcl->inttostr.t.capa = 0; } if (hcl->sprintf.xbuf.ptr) { - hcl_freemem (hcl, hcl->sprintf.xbuf.ptr); + hcl_freemem(hcl, hcl->sprintf.xbuf.ptr); hcl->sprintf.xbuf.ptr = HCL_NULL; hcl->sprintf.xbuf.capa = 0; hcl->sprintf.xbuf.len = 0; @@ -384,7 +384,7 @@ void hcl_resetcode (hcl_t* hcl) { hcl_oop_t key = HCL_CONS_CAR(v); if (!HCL_IS_SYMBOL(hcl,key) || !HCL_OBJ_GET_FLAGS_KERNEL(key)) - hcl_zapatsysdic (hcl, HCL_CONS_CAR(v)); + hcl_zapatsysdic(hcl, HCL_CONS_CAR(v)); } } @@ -393,7 +393,7 @@ void hcl_resetcode (hcl_t* hcl) hcl->code.lit.len = 0; /* clean up object memory */ - hcl_gc (hcl, 1); + hcl_gc(hcl, 1); } void hcl_clearcode (hcl_t* hcl) @@ -452,7 +452,7 @@ int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value) v2 = hcl_dupbtoucstr(hcl, (const hcl_bch_t*)value, HCL_NULL); if (HCL_UNLIKELY(!v2)) { - hcl_freemem (hcl, v1); + hcl_freemem(hcl, v1); return -1; } @@ -472,7 +472,7 @@ int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value) v2 = hcl_duputobcstr(hcl, (const hcl_uch_t*)value, HCL_NULL); if (HCL_UNLIKELY(!v2)) { - hcl_freemem (hcl, v1); + hcl_freemem(hcl, v1); return -1; } @@ -493,7 +493,7 @@ int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value) v2 = hcl_dupbtouchars(hcl, v->ptr, v->len, HCL_NULL); if (HCL_UNLIKELY(!v2)) { - hcl_freemem (hcl, v1); + hcl_freemem(hcl, v1); return -1; } @@ -514,7 +514,7 @@ int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value) v2 = hcl_duputobchars(hcl, v->ptr, v->len, HCL_NULL); if (HCL_UNLIKELY(!v2)) { - hcl_freemem (hcl, v1); + hcl_freemem(hcl, v1); return -1; } @@ -566,7 +566,7 @@ int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value) if (dup_str_opt(hcl, (const hcl_ooch_t*)value, &tmp) <= -1) return -1; idx = id - HCL_MOD_LIBDIRS; - if (hcl->option.mod[idx].ptr) hcl_freemem (hcl, hcl->option.mod[idx].ptr); + if (hcl->option.mod[idx].ptr) hcl_freemem(hcl, hcl->option.mod[idx].ptr); hcl->option.mod[idx] = tmp; return 0; @@ -582,13 +582,13 @@ int hcl_setoption (hcl_t* hcl, hcl_option_t id, const void* value) for (cb = hcl->cblist; cb; cb = cb->next) { - if (cb->on_option) cb->on_option (hcl, id, value); + if (cb->on_option) cb->on_option(hcl, id, value); } return 0; einval: - hcl_seterrnum (hcl, HCL_EINVAL); + hcl_seterrnum(hcl, HCL_EINVAL); return -1; } @@ -649,7 +649,7 @@ int hcl_getoption (hcl_t* hcl, hcl_option_t id, void* value) return 0; }; - hcl_seterrnum (hcl, HCL_EINVAL); + hcl_seterrnum(hcl, HCL_EINVAL); return -1; } @@ -690,10 +690,10 @@ void hcl_deregcb (hcl_t* hcl, hcl_cb_t* cb) if (cb->vm_checkbc) { - HCL_ASSERT (hcl, hcl->vm_checkbc_cb_count > 0); + HCL_ASSERT(hcl, hcl->vm_checkbc_cb_count > 0); hcl->vm_checkbc_cb_count--; } - hcl_freemem (hcl, cb); + hcl_freemem(hcl, cb); } void* hcl_allocmem (hcl_t* hcl, hcl_oow_t size) @@ -701,7 +701,7 @@ void* hcl_allocmem (hcl_t* hcl, hcl_oow_t size) void* ptr; ptr = HCL_MMGR_ALLOC(HCL_MMGR(hcl), size); - if (!ptr) hcl_seterrnum (hcl, HCL_ESYSMEM); + if (!ptr) hcl_seterrnum(hcl, HCL_ESYSMEM); return ptr; } @@ -710,7 +710,7 @@ void* hcl_callocmem (hcl_t* hcl, hcl_oow_t size) void* ptr; ptr = HCL_MMGR_ALLOC(HCL_MMGR(hcl), size); - if (!ptr) hcl_seterrnum (hcl, HCL_ESYSMEM); + if (!ptr) hcl_seterrnum(hcl, HCL_ESYSMEM); else HCL_MEMSET (ptr, 0, size); return ptr; } @@ -718,7 +718,7 @@ void* hcl_callocmem (hcl_t* hcl, hcl_oow_t size) void* hcl_reallocmem (hcl_t* hcl, void* ptr, hcl_oow_t size) { ptr = HCL_MMGR_REALLOC(HCL_MMGR(hcl), ptr, size); - if (!ptr) hcl_seterrnum (hcl, HCL_ESYSMEM); + if (!ptr) hcl_seterrnum(hcl, HCL_ESYSMEM); return ptr; } @@ -777,11 +777,11 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel if (namelen > HCL_COUNTOF(buf) - (MOD_PREFIX_LEN + 1 + 1)) { /* module name too long */ - hcl_seterrnum (hcl, HCL_EINVAL); /* TODO: change the error number to something more specific */ + hcl_seterrnum(hcl, HCL_EINVAL); /* TODO: change the error number to something more specific */ return HCL_NULL; } - hcl_copy_oochars (&buf[MOD_PREFIX_LEN], name, namelen); + hcl_copy_oochars(&buf[MOD_PREFIX_LEN], name, namelen); buf[MOD_PREFIX_LEN + namelen] = '\0'; #if defined(HCL_ENABLE_STATIC_MODULE) @@ -801,7 +801,7 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel { /* found the module in the static module table */ - HCL_MEMSET (&md, 0, HCL_SIZEOF(md)); + HCL_MEMSET(&md, 0, HCL_SIZEOF(md)); md.mod.inctx = hcl->option.mod_inctx; hcl_copy_oochars ((hcl_ooch_t*)md.mod.name, name, namelen); /* Note md.handle is HCL_NULL for a static module */ @@ -811,40 +811,40 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel pair = hcl_rbt_insert(&hcl->modtab, (hcl_ooch_t*)name, namelen, &md, HCL_SIZEOF(md)); if (HCL_UNLIKELY(!pair)) { - hcl_seterrbfmt (hcl, HCL_ESYSMEM, "insufficient system memory in storing static module handle"); + hcl_seterrbfmt(hcl, HCL_ESYSMEM, "insufficient system memory in storing static module handle"); return HCL_NULL; } mdp = (hcl_mod_data_t*)HCL_RBT_VPTR(pair); if (load(hcl, &mdp->mod) <= -1) { - hcl_rbt_delete (&hcl->modtab, (hcl_ooch_t*)name, namelen); + hcl_rbt_delete(&hcl->modtab, (hcl_ooch_t*)name, namelen); return HCL_NULL; } mdp->pair = pair; - HCL_DEBUG1 (hcl, "Opened a static module [%js]\n", mdp->mod.name); + HCL_DEBUG1(hcl, "Opened a static module [%js]\n", mdp->mod.name); return mdp; } else { #if !defined(HCL_ENABLE_DYNAMIC_MODULE) - HCL_DEBUG2 (hcl, "Cannot find a static module [%.*js]\n", namelen, name); - hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to find a static module [%.*js]", namelen, name); + HCL_DEBUG2(hcl, "Cannot find a static module [%.*js]\n", namelen, name); + hcl_seterrbfmt(hcl, HCL_ENOENT, "unable to find a static module [%.*js]", namelen, name); return HCL_NULL; #endif } #endif #if !defined(HCL_ENABLE_DYNAMIC_MODULE) - HCL_DEBUG2 (hcl, "Cannot open module [%.*js] - module loading disabled\n", namelen, name); - hcl_seterrbfmt (hcl, HCL_ENOIMPL, "unable to open module [%.*js] - module loading disabled", namelen, name); + HCL_DEBUG2(hcl, "Cannot open module [%.*js] - module loading disabled\n", namelen, name); + hcl_seterrbfmt(hcl, HCL_ENOIMPL, "unable to open module [%.*js] - module loading disabled", namelen, name); return HCL_NULL; #endif /* attempt to find a dynamic external module */ - HCL_MEMSET (&md, 0, HCL_SIZEOF(md)); + HCL_MEMSET(&md, 0, HCL_SIZEOF(md)); md.mod.inctx = hcl->option.mod_inctx; hcl_copy_oochars((hcl_ooch_t*)md.mod.name, name, namelen); if (hcl->vmprim.dl_open && hcl->vmprim.dl_getsym && hcl->vmprim.dl_close) @@ -854,8 +854,8 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel if (md.handle == HCL_NULL) { - HCL_DEBUG2 (hcl, "Cannot open a module [%.*js]\n", namelen, name); - hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to open a module [%.*js]", namelen, name); + HCL_DEBUG2(hcl, "Cannot open a module [%.*js]\n", namelen, name); + hcl_seterrbfmt(hcl, HCL_ENOENT, "unable to open a module [%.*js]", namelen, name); return HCL_NULL; } @@ -863,9 +863,9 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel load = (hcl_mod_load_t)hcl->vmprim.dl_getsym(hcl, md.handle, buf); if (!load) { - hcl_seterrbfmt (hcl, HCL_ERRNUM(hcl), "unable to get module symbol [%js] in [%.*js]", buf, namelen, name); - HCL_DEBUG3 (hcl, "Cannot get a module symbol [%js] in [%.*js]\n", buf, namelen, name); - hcl->vmprim.dl_close (hcl, md.handle); + hcl_seterrbfmt(hcl, HCL_ERRNUM(hcl), "unable to get module symbol [%js] in [%.*js]", buf, namelen, name); + HCL_DEBUG3(hcl, "Cannot get a module symbol [%js] in [%.*js]\n", buf, namelen, name); + hcl->vmprim.dl_close(hcl, md.handle); return HCL_NULL; } @@ -874,9 +874,9 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel pair = hcl_rbt_insert(&hcl->modtab, (void*)name, namelen, &md, HCL_SIZEOF(md)); if (pair == HCL_NULL) { - HCL_DEBUG2 (hcl, "Cannot register a module [%.*js]\n", namelen, name); - hcl_seterrbfmt (hcl, HCL_ESYSMEM, "unable to register a module [%.*js] for memory shortage", namelen, name); - hcl->vmprim.dl_close (hcl, md.handle); + HCL_DEBUG2(hcl, "Cannot register a module [%.*js]\n", namelen, name); + hcl_seterrbfmt(hcl, HCL_ESYSMEM, "unable to register a module [%.*js] for memory shortage", namelen, name); + hcl->vmprim.dl_close(hcl, md.handle); return HCL_NULL; } @@ -884,42 +884,42 @@ hcl_mod_data_t* hcl_openmod (hcl_t* hcl, const hcl_ooch_t* name, hcl_oow_t namel if (load(hcl, &mdp->mod) <= -1) { const hcl_ooch_t* oldmsg = hcl_backuperrmsg (hcl); - hcl_seterrbfmt (hcl, HCL_ERRNUM(hcl), "module initializer [%js] returned failure in [%.*js] - %js", buf, namelen, name, oldmsg); - HCL_DEBUG3 (hcl, "Module function [%js] returned failure in [%.*js]\n", buf, namelen, name); - hcl_rbt_delete (&hcl->modtab, name, namelen); - hcl->vmprim.dl_close (hcl, mdp->handle); + hcl_seterrbfmt(hcl, HCL_ERRNUM(hcl), "module initializer [%js] returned failure in [%.*js] - %js", buf, namelen, name, oldmsg); + HCL_DEBUG3(hcl, "Module function [%js] returned failure in [%.*js]\n", buf, namelen, name); + hcl_rbt_delete(&hcl->modtab, name, namelen); + hcl->vmprim.dl_close(hcl, mdp->handle); return HCL_NULL; } mdp->pair = pair; - HCL_DEBUG2 (hcl, "Opened a module [%js] - %p\n", mdp->mod.name, mdp->handle); + HCL_DEBUG2(hcl, "Opened a module [%js] - %p\n", mdp->mod.name, mdp->handle); /* the module loader must ensure to set a proper query handler */ - HCL_ASSERT (hcl, mdp->mod.query != HCL_NULL); + HCL_ASSERT(hcl, mdp->mod.query != HCL_NULL); return mdp; } void hcl_closemod (hcl_t* hcl, hcl_mod_data_t* mdp) { - if (mdp->mod.unload) mdp->mod.unload (hcl, &mdp->mod); + if (mdp->mod.unload) mdp->mod.unload(hcl, &mdp->mod); if (mdp->handle) { - hcl->vmprim.dl_close (hcl, mdp->handle); - HCL_DEBUG2 (hcl, "Closed a module [%js] - %p\n", mdp->mod.name, mdp->handle); + hcl->vmprim.dl_close(hcl, mdp->handle); + HCL_DEBUG2(hcl, "Closed a module [%js] - %p\n", mdp->mod.name, mdp->handle); mdp->handle = HCL_NULL; } else { - HCL_DEBUG1 (hcl, "Closed a static module [%js]\n", mdp->mod.name); + HCL_DEBUG1(hcl, "Closed a static module [%js]\n", mdp->mod.name); } if (mdp->pair) { /*mdp->pair = HCL_NULL;*/ /* this reset isn't needed as the area will get freed by hcl_rbt_delete()) */ - hcl_rbt_delete (&hcl->modtab, mdp->mod.name, hcl_count_oocstr(mdp->mod.name)); + hcl_rbt_delete(&hcl->modtab, mdp->mod.name, hcl_count_oocstr(mdp->mod.name)); } } @@ -943,8 +943,8 @@ hcl_pfbase_t* hcl_querymod (hcl_t* hcl, const hcl_ooch_t* pfid, hcl_oow_t pfidle * guarantee that a period is included in an primitive function identifer. * what if the compiler is broken? imagine a buggy compiler rewritten * in hcl itself? */ - HCL_DEBUG2 (hcl, "Internal error - no period in a primitive function identifier [%.*js] - buggy compiler?\n", pfidlen, pfid); - hcl_seterrbfmt (hcl, HCL_EINTERN, "no period in a primitive function identifier [%.*js]", pfidlen, pfid); + HCL_DEBUG2(hcl, "Internal error - no period in a primitive function identifier [%.*js] - buggy compiler?\n", pfidlen, pfid); + hcl_seterrbfmt(hcl, HCL_EINTERN, "no period in a primitive function identifier [%.*js]", pfidlen, pfid); return HCL_NULL; } @@ -958,7 +958,7 @@ hcl_pfbase_t* hcl_querymod (hcl_t* hcl, const hcl_ooch_t* pfid, hcl_oow_t pfidle if (pair) { mdp = (hcl_mod_data_t*)HCL_RBT_VPTR(pair); - HCL_ASSERT (hcl, mdp != HCL_NULL); + HCL_ASSERT(hcl, mdp != HCL_NULL); } else { @@ -970,15 +970,14 @@ hcl_pfbase_t* hcl_querymod (hcl_t* hcl, const hcl_ooch_t* pfid, hcl_oow_t pfidle if ((pfbase = mdp->mod.query(hcl, &mdp->mod, sep + 1, pfidlen - mod_name_len - 1)) == HCL_NULL) { /* the primitive function is not found. but keep the module open even if it's opened above */ - HCL_DEBUG3 (hcl, "Cannot find a primitive function [%.*js] in a module [%js]\n", pfidlen - mod_name_len - 1, sep + 1, mdp->mod.name); - hcl_seterrbfmt (hcl, HCL_ENOENT, "unable to find a primitive function [%.*js] in a module [%js]", pfidlen - mod_name_len - 1, sep + 1, mdp->mod.name); + HCL_DEBUG3(hcl, "Cannot find a primitive function [%.*js] in a module [%js]\n", pfidlen - mod_name_len - 1, sep + 1, mdp->mod.name); + hcl_seterrbfmt(hcl, HCL_ENOENT, "unable to find a primitive function [%.*js] in a module [%js]", pfidlen - mod_name_len - 1, sep + 1, mdp->mod.name); return HCL_NULL; } *mod = &mdp->mod; - HCL_DEBUG4 (hcl, "Found a primitive function [%.*js] in a module [%js] - %p\n", - pfidlen - mod_name_len - 1, sep + 1, mdp->mod.name, pfbase); + HCL_DEBUG4(hcl, "Found a primitive function [%.*js] in a module [%js] - %p\n", pfidlen - mod_name_len - 1, sep + 1, mdp->mod.name, pfbase); return pfbase; } @@ -1014,7 +1013,7 @@ hcl_pfbase_t* hcl_findpfbase (hcl_t* hcl, hcl_pfinfo_t* pfinfo, hcl_oow_t pfcoun } #endif - hcl_seterrnum (hcl, HCL_ENOENT); + hcl_seterrnum(hcl, HCL_ENOENT); return HCL_NULL; } diff --git a/lib/xma.c b/lib/xma.c index 8160e53..23355f5 100644 --- a/lib/xma.c +++ b/lib/xma.c @@ -250,7 +250,7 @@ int hcl_xma_init (hcl_xma_t* xma, hcl_mmgr_t* mmgr, void* zoneptr, hcl_oow_t zon first->free_prev = HCL_NULL; first->free_next = HCL_NULL; - HCL_MEMSET (xma, 0, HCL_SIZEOF(*xma)); + HCL_MEMSET(xma, 0, HCL_SIZEOF(*xma)); xma->_mmgr = mmgr; xma->bdec = szlog2(FIXED * ALIGN); /* precalculate the decrement value */ @@ -272,6 +272,15 @@ int hcl_xma_init (hcl_xma_t* xma, hcl_mmgr_t* mmgr, void* zoneptr, hcl_oow_t zon xma->stat.avail = zonesize - MBLKHDRSIZE; xma->stat.nfree = 1; xma->stat.nused = 0; + xma->stat.alloc_hwmark = 0; + + xma->stat.nallocops = 0; + xma->stat.nallocgoodops = 0; + xma->stat.nallocbadops = 0; + xma->stat.nreallocops = 0; + xma->stat.nreallocgoodops = 0; + xma->stat.nreallocbadops = 0; + xma->stat.nfreeops = 0; #endif return 0; @@ -343,7 +352,7 @@ static hcl_xma_fblk_t* alloc_from_freelist (hcl_xma_t* xma, hcl_oow_t xfi, hcl_o { hcl_oow_t rem; - detach_from_freelist (xma, cand); + detach_from_freelist(xma, cand); rem = cand->size - size; if (rem >= FBLKMINSIZE) @@ -366,7 +375,7 @@ static hcl_xma_fblk_t* alloc_from_freelist (hcl_xma_t* xma, hcl_oow_t xfi, hcl_o y->prev_size = cand->size; /* add the remaining part to the free list */ - attach_to_freelist (xma, (hcl_xma_fblk_t*)y); + attach_to_freelist(xma, (hcl_xma_fblk_t*)y); z = next_mblk(y); if ((hcl_uint8_t*)z < xma->end) z->prev_size = y->size; @@ -394,6 +403,7 @@ static hcl_xma_fblk_t* alloc_from_freelist (hcl_xma_t* xma, hcl_oow_t xfi, hcl_o xma->stat.nused++; xma->stat.alloc += cand->size; xma->stat.avail -= cand->size; + if (xma->stat.alloc > xma->stat.alloc_hwmark) xma->stat.alloc_hwmark = xma->stat.alloc; #endif return cand; } @@ -408,7 +418,11 @@ void* hcl_xma_alloc (hcl_xma_t* xma, hcl_oow_t size) hcl_xma_fblk_t* cand; hcl_oow_t xfi; - DBG_VERIFY (xma, "alloc start"); + DBG_VERIFY(xma, "alloc start"); + +#if defined(HCL_XMA_ENABLE_STAT) + xma->stat.nallocops++; +#endif /* round up 'size' to the multiples of ALIGN */ if (size < MINALLOCSIZE) size = MINALLOCSIZE; @@ -426,7 +440,7 @@ void* hcl_xma_alloc (hcl_xma_t* xma, hcl_oow_t size) assert (cand->free != 0); assert (cand->size == size); - detach_from_freelist (xma, cand); + detach_from_freelist(xma, cand); cand->free = 0; #if defined(HCL_XMA_ENABLE_STAT) @@ -434,13 +448,20 @@ void* hcl_xma_alloc (hcl_xma_t* xma, hcl_oow_t size) xma->stat.nused++; xma->stat.alloc += cand->size; xma->stat.avail -= cand->size; + if (xma->stat.alloc > xma->stat.alloc_hwmark) xma->stat.alloc_hwmark = xma->stat.alloc; #endif } else if (xfi == XFIMAX(xma)) { /* huge block */ cand = alloc_from_freelist(xma, XFIMAX(xma), size); - if (!cand) return HCL_NULL; + if (!cand) + { + #if defined(HCL_XMA_ENABLE_STAT) + xma->stat.nallocbadops++; + #endif + return HCL_NULL; + } } else { @@ -469,11 +490,20 @@ void* hcl_xma_alloc (hcl_xma_t* xma, hcl_oow_t size) cand = alloc_from_freelist(xma, xfi, size); if (cand) break; } - if (!cand) return HCL_NULL; + if (!cand) + { + #if defined(HCL_XMA_ENABLE_STAT) + xma->stat.nallocbadops++; + #endif + return HCL_NULL; + } } } - DBG_VERIFY (xma, "alloc end"); +#if defined(HCL_XMA_ENABLE_STAT) + xma->stat.nallocgoodops++; +#endif + DBG_VERIFY(xma, "alloc end"); return SYS_TO_USR(cand); } @@ -481,7 +511,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) { hcl_xma_mblk_t* blk = (hcl_xma_mblk_t*)USR_TO_SYS(b); - DBG_VERIFY (xma, "realloc merge start"); + DBG_VERIFY(xma, "realloc merge start"); /* rounds up 'size' to be multiples of ALIGN */ if (size < MINALLOCSIZE) size = MINALLOCSIZE; size = HCL_ALIGN_POW2(size, ALIGN); @@ -504,7 +534,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) assert (blk->size == n->prev_size); /* let's merge the current block with the next block */ - detach_from_freelist (xma, (hcl_xma_fblk_t*)n); + detach_from_freelist(xma, (hcl_xma_fblk_t*)n); rem = (MBLKHDRSIZE + n->size) - req; if (rem >= FBLKMINSIZE) @@ -521,7 +551,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) y->free = 1; y->size = rem - MBLKHDRSIZE; y->prev_size = blk->size; - attach_to_freelist (xma, (hcl_xma_fblk_t*)y); + attach_to_freelist(xma, (hcl_xma_fblk_t*)y); z = next_mblk(y); if ((hcl_uint8_t*)z < xma->end) z->prev_size = y->size; @@ -529,6 +559,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) #if defined(HCL_XMA_ENABLE_STAT) xma->stat.alloc += req; xma->stat.avail -= req; /* req + MBLKHDRSIZE(tmp) - MBLKHDRSIZE(n) */ + if (xma->stat.alloc > xma->stat.alloc_hwmark) xma->stat.alloc_hwmark = xma->stat.alloc; #endif } else @@ -546,6 +577,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) xma->stat.nfree--; xma->stat.alloc += MBLKHDRSIZE + n->size; xma->stat.avail -= n->size; + if (xma->stat.alloc > xma->stat.alloc_hwmark) xma->stat.alloc_hwmark = xma->stat.alloc; #endif } } @@ -566,7 +598,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) /* make the leftover block merge with the next block */ - detach_from_freelist (xma, (hcl_xma_fblk_t*)n); + detach_from_freelist(xma, (hcl_xma_fblk_t*)n); blk->size = size; @@ -576,7 +608,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) y->prev_size = blk->size; /* add 'y' to the free list */ - attach_to_freelist (xma, (hcl_xma_fblk_t*)y); + attach_to_freelist(xma, (hcl_xma_fblk_t*)y); z = next_mblk(y); /* get adjacent block to the merged block */ if ((hcl_uint8_t*)z < xma->end) z->prev_size = y->size; @@ -598,7 +630,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) y->size = rem - MBLKHDRSIZE; y->prev_size = blk->size; - attach_to_freelist (xma, (hcl_xma_fblk_t*)y); + attach_to_freelist(xma, (hcl_xma_fblk_t*)y); /*n = next_mblk(y); if ((hcl_uint8_t*)n < xma->end)*/ n->prev_size = y->size; @@ -611,7 +643,7 @@ static void* _realloc_merge (hcl_xma_t* xma, void* b, hcl_oow_t size) } } - DBG_VERIFY (xma, "realloc merge end"); + DBG_VERIFY(xma, "realloc merge end"); return b; } @@ -626,7 +658,7 @@ void* hcl_xma_realloc (hcl_xma_t* xma, void* b, hcl_oow_t size) { void* n; - if (b == HCL_NULL) + if (!b) { /* 'realloc' with NULL is the same as 'alloc' */ n = hcl_xma_alloc(xma, size); @@ -634,18 +666,30 @@ void* hcl_xma_realloc (hcl_xma_t* xma, void* b, hcl_oow_t size) else { /* try reallocation by merging the adjacent continuous blocks */ - n = _realloc_merge (xma, b, size); + #if defined(HAWK_XMA_ENABLE_STAT) + xma->stat.nreallocops++; + #endif + n = _realloc_merge(xma, b, size); if (!n) { + #if defined(HCL_XMA_ENABLE_STAT) + xma->stat.nreallocbadops++; + #endif /* reallocation by merging failed. fall back to the slow * allocation-copy-free scheme */ n = hcl_xma_alloc(xma, size); if (n) { - HCL_MEMCPY (n, b, size); - hcl_xma_free (xma, b); + HCL_MEMCPY(n, b, size); + hcl_xma_free(xma, b); } } + else + { + #if defined(HCL_XMA_ENABLE_STAT) + xma->stat.nreallocgoodops++; + #endif + } } return n; @@ -657,7 +701,7 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) hcl_xma_mblk_t* x, * y; hcl_oow_t org_blk_size; - DBG_VERIFY (xma, "free start"); + DBG_VERIFY(xma, "free start"); org_blk_size = blk->size; @@ -665,6 +709,7 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) /* update statistical variables */ xma->stat.nused--; xma->stat.alloc -= org_blk_size; + xma->stat.nfreeops++; #endif x = prev_mblk(blk); @@ -692,11 +737,11 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) hcl_oow_t ns = MBLKHDRSIZE + org_blk_size + MBLKHDRSIZE; hcl_oow_t bs = ns + y->size; - detach_from_freelist (xma, (hcl_xma_fblk_t*)x); - detach_from_freelist (xma, (hcl_xma_fblk_t*)y); + detach_from_freelist(xma, (hcl_xma_fblk_t*)x); + detach_from_freelist(xma, (hcl_xma_fblk_t*)y); x->size += bs; - attach_to_freelist (xma, (hcl_xma_fblk_t*)x); + attach_to_freelist(xma, (hcl_xma_fblk_t*)x); z = next_mblk(x); if ((hcl_uint8_t*)z < xma->end) z->prev_size = x->size; @@ -732,7 +777,7 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) hcl_xma_mblk_t* z = next_mblk(y); /* detach y from the free list */ - detach_from_freelist (xma, (hcl_xma_fblk_t*)y); + detach_from_freelist(xma, (hcl_xma_fblk_t*)y); /* update the block availability */ blk->free = 1; @@ -743,7 +788,7 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) if ((hcl_uint8_t*)z < xma->end) z->prev_size = blk->size; /* attach blk to the free list */ - attach_to_freelist (xma, (hcl_xma_fblk_t*)blk); + attach_to_freelist(xma, (hcl_xma_fblk_t*)blk); #if defined(HCL_XMA_ENABLE_STAT) xma->stat.avail += org_blk_size + MBLKHDRSIZE; @@ -765,14 +810,14 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) * | X | Y | * +-------------------------+------------+ */ - detach_from_freelist (xma, (hcl_xma_fblk_t*)x); + detach_from_freelist(xma, (hcl_xma_fblk_t*)x); x->size += MBLKHDRSIZE + org_blk_size; assert (y == next_mblk(x)); if ((hcl_uint8_t*)y < xma->end) y->prev_size = x->size; - attach_to_freelist (xma, (hcl_xma_fblk_t*)x); + attach_to_freelist(xma, (hcl_xma_fblk_t*)x); #if defined(HCL_XMA_ENABLE_STAT) xma->stat.avail += MBLKHDRSIZE + org_blk_size; @@ -781,7 +826,7 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) else { blk->free = 1; - attach_to_freelist (xma, (hcl_xma_fblk_t*)blk); + attach_to_freelist(xma, (hcl_xma_fblk_t*)blk); #if defined(HCL_XMA_ENABLE_STAT) xma->stat.nfree++; @@ -789,7 +834,7 @@ void hcl_xma_free (hcl_xma_t* xma, void* b) #endif } - DBG_VERIFY (xma, "free end"); + DBG_VERIFY(xma, "free end"); } void hcl_xma_dump (hcl_xma_t* xma, hcl_xma_dumper_t dumper, void* ctx) @@ -800,20 +845,21 @@ void hcl_xma_dump (hcl_xma_t* xma, hcl_xma_dumper_t dumper, void* ctx) hcl_oow_t isum; #endif - dumper (ctx, "\n"); + dumper(ctx, "[XMA DUMP]\n"); #if defined(HCL_XMA_ENABLE_STAT) - dumper (ctx, "== statistics ==\n"); - dumper (ctx, "total = %zu\n", xma->stat.total); - dumper (ctx, "alloc = %zu\n", xma->stat.alloc); - dumper (ctx, "avail = %zu\n", xma->stat.avail); + dumper(ctx, "== statistics ==\n"); + dumper(ctx, "Total = %zu\n", xma->stat.total); + dumper(ctx, "Alloc = %zu\n", xma->stat.alloc); + dumper(ctx, "Avail = %zu\n", xma->stat.avail); + dumper(ctx, "Alloc High Watermark = %zu\n", xma->stat.alloc_hwmark); #endif - dumper (ctx, "== blocks ==\n"); - dumper (ctx, " size avail address\n"); + dumper(ctx, "== blocks ==\n"); + dumper(ctx, " size avail address\n"); for (tmp = (hcl_xma_mblk_t*)xma->start, fsum = 0, asum = 0; (hcl_uint8_t*)tmp < xma->end; tmp = next_mblk(tmp)) { - dumper (ctx, " %-18zu %-5u %p\n", tmp->size, (unsigned int)tmp->free, tmp); + dumper(ctx, " %-18zu %-5u %p\n", tmp->size, (unsigned int)tmp->free, tmp); if (tmp->free) fsum += tmp->size; else asum += tmp->size; } @@ -822,21 +868,28 @@ void hcl_xma_dump (hcl_xma_t* xma, hcl_xma_dumper_t dumper, void* ctx) isum = (xma->stat.nfree + xma->stat.nused) * MBLKHDRSIZE; #endif - dumper (ctx, "---------------------------------------\n"); - dumper (ctx, "Allocated blocks: %18zu bytes\n", asum); - dumper (ctx, "Available blocks: %18zu bytes\n", fsum); + dumper(ctx, "---------------------------------------\n"); + dumper(ctx, "Allocated blocks : %18zu bytes\n", asum); + dumper(ctx, "Available blocks : %18zu bytes\n", fsum); #if defined(HCL_XMA_ENABLE_STAT) - dumper (ctx, "Internal use : %18zu bytes\n", isum); - dumper (ctx, "Total : %18zu bytes\n", (asum + fsum + isum)); + dumper(ctx, "Internal use : %18zu bytes\n", isum); + dumper(ctx, "Total : %18zu bytes\n", (asum + fsum + isum)); + dumper(ctx, "Alloc operations : %18zu\n", xma->stat.nallocops); + dumper(ctx, "Good alloc operations : %18zu\n", xma->stat.nallocgoodops); + dumper(ctx, "Bad alloc operations : %18zu\n", xma->stat.nallocbadops); + dumper(ctx, "Realloc operations : %18zu\n", xma->stat.nreallocops); + dumper(ctx, "Good realloc operations: %18zu\n", xma->stat.nreallocgoodops); + dumper(ctx, "Bad realloc operations : %18zu\n", xma->stat.nreallocbadops); + dumper(ctx, "Free operations : %18zu\n", xma->stat.nfreeops); #endif #if defined(HCL_XMA_ENABLE_STAT) - assert (asum == xma->stat.alloc); - assert (fsum == xma->stat.avail); - assert (isum == xma->stat.total - (xma->stat.alloc + xma->stat.avail)); - assert (asum + fsum + isum == xma->stat.total); + HCL_ASSERT(hcl, asum == xma->stat.alloc); + HCL_ASSERT(hcl, fsum == xma->stat.avail); + HCL_ASSERT(hcl, isum == xma->stat.total - (xma->stat.alloc + xma->stat.avail)); + HCL_ASSERT(hcl, asum + fsum + isum == xma->stat.total); #endif }