allowed vmprim.alloc_heap() to create a bigger heap than requested.
enhanced the standard implementation(std.c) to attempt HUGETLB if the requested heap size is over 1/2 of the huge page size
This commit is contained in:
parent
aa8f8fac2d
commit
1d0c7a8bbc
16
bin/main-s.c
16
bin/main-s.c
@ -504,7 +504,6 @@ int main (int argc, char* argv[])
|
||||
static hcl_bopt_lng_t lopt[] =
|
||||
{
|
||||
{ ":log", 'l' },
|
||||
{ "large-pages", '\0' },
|
||||
{ ":worker-max-count", '\0' },
|
||||
{ ":worker-stack-size", '\0' },
|
||||
{ ":worker-idle-timeout", '\0' },
|
||||
@ -535,8 +534,6 @@ int main (int argc, char* argv[])
|
||||
hcl_ntime_t worker_idle_timeout = { 0, 0 };
|
||||
hcl_oow_t actor_heap_size = MIN_ACTOR_HEAP_SIZE;
|
||||
hcl_ntime_t actor_max_runtime = { 0, 0 };
|
||||
int large_pages = 0;
|
||||
hcl_bitmask_t trait;
|
||||
|
||||
setlocale (LC_ALL, "");
|
||||
|
||||
@ -557,15 +554,11 @@ int main (int argc, char* argv[])
|
||||
|
||||
case 'm':
|
||||
actor_heap_size = strtoul(opt.arg, HCL_NULL, 0);
|
||||
if (actor_heap_size <= MIN_ACTOR_HEAP_SIZE) actor_heap_size = MIN_ACTOR_HEAP_SIZE;
|
||||
if (actor_heap_size > 0 && actor_heap_size <= MIN_ACTOR_HEAP_SIZE) actor_heap_size = MIN_ACTOR_HEAP_SIZE;
|
||||
break;
|
||||
|
||||
case '\0':
|
||||
if (hcl_comp_bcstr(opt.lngopt, "large-pages") == 0)
|
||||
{
|
||||
large_pages = 1;
|
||||
}
|
||||
else if (hcl_comp_bcstr(opt.lngopt, "worker-max-count") == 0)
|
||||
if (hcl_comp_bcstr(opt.lngopt, "worker-max-count") == 0)
|
||||
{
|
||||
worker_max_count = strtoul(opt.arg, HCL_NULL, 0);
|
||||
}
|
||||
@ -646,11 +639,6 @@ int main (int argc, char* argv[])
|
||||
if (handle_incpath(server, incpath) <= -1) goto oops;
|
||||
}
|
||||
|
||||
hcl_server_getoption (server, HCL_SERVER_TRAIT, &trait);
|
||||
if (large_pages) trait |= HCL_SERVER_TRAIT_USE_LARGE_PAGES;
|
||||
else trait &= ~HCL_SERVER_TRAIT_USE_LARGE_PAGES;
|
||||
hcl_server_setoption (server, HCL_SERVER_TRAIT, &trait);
|
||||
|
||||
hcl_server_setoption (server, HCL_SERVER_WORKER_MAX_COUNT, &worker_max_count);
|
||||
hcl_server_setoption (server, HCL_SERVER_WORKER_STACK_SIZE, &worker_stack_size);
|
||||
hcl_server_setoption (server, HCL_SERVER_WORKER_IDLE_TIMEOUT, &worker_idle_timeout);
|
||||
|
@ -665,7 +665,6 @@ int main (int argc, char* argv[])
|
||||
{ ":heapsize", '\0' },
|
||||
{ ":log", 'l' },
|
||||
|
||||
{ "large-pages", '\0' },
|
||||
{ HCL_NULL, '\0' }
|
||||
};
|
||||
static hcl_bopt_t opt =
|
||||
@ -677,7 +676,6 @@ int main (int argc, char* argv[])
|
||||
const char* logopt = HCL_NULL;
|
||||
hcl_oow_t heapsize = DEFAULT_HEAPSIZE;
|
||||
int verbose = 0;
|
||||
int large_pages = 0;
|
||||
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
const char* dbgopt = HCL_NULL;
|
||||
@ -711,11 +709,6 @@ int main (int argc, char* argv[])
|
||||
heapsize = strtoul(opt.arg, HCL_NULL, 0);
|
||||
break;
|
||||
}
|
||||
else if (hcl_comp_bcstr(opt.lngopt, "large-pages") == 0)
|
||||
{
|
||||
large_pages = 1;
|
||||
break;
|
||||
}
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
else if (hcl_comp_bcstr(opt.lngopt, "debug") == 0)
|
||||
{
|
||||
|
6
lib/gc.c
6
lib/gc.c
@ -740,6 +740,12 @@ int hcl_ignite (hcl_t* hcl)
|
||||
{
|
||||
hcl_oow_t i;
|
||||
|
||||
if (!hcl->heap)
|
||||
{
|
||||
hcl->heap = hcl_makeheap(hcl, hcl->_reqheapsz);
|
||||
if (HCL_UNLIKELY(!hcl->heap)) return -1;
|
||||
}
|
||||
|
||||
if (!hcl->_nil)
|
||||
{
|
||||
hcl->_nil = hcl_makenil(hcl);
|
||||
|
@ -816,6 +816,7 @@ hcl_client_t* hcl_client_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_client_p
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
/* replace the vmprim.log_write function */
|
||||
hcl->vmprim.log_write = log_write_for_dummy;
|
||||
|
||||
xtn = (client_hcl_xtn_t*)hcl_getxtn(hcl);
|
||||
|
24
lib/hcl-s.c
24
lib/hcl-s.c
@ -653,30 +653,10 @@ static void fini_hcl (hcl_t* hcl)
|
||||
hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_t* worker)
|
||||
{
|
||||
hcl_server_proto_t* proto;
|
||||
hcl_vmprim_t vmprim;
|
||||
hcl_cb_t hclcb;
|
||||
worker_hcl_xtn_t* xtn;
|
||||
hcl_bitmask_t trait;
|
||||
|
||||
#if 0
|
||||
HCL_MEMSET (&vmprim, 0, HCL_SIZEOF(vmprim));
|
||||
if (worker->server->cfg.trait & HCL_SERVER_TRAIT_USE_LARGE_PAGES)
|
||||
{
|
||||
vmprim.alloc_heap = hcl_vmprim_alloc_heap;
|
||||
vmprim.free_heap = hcl_vmprim_free_heap;
|
||||
}
|
||||
vmprim.log_write = log_write;
|
||||
vmprim.syserrstrb = hcl_vmprim_syserrstrb;
|
||||
vmprim.assertfail = hcl_vmprim_assertfail;
|
||||
vmprim.dl_startup = hcl_vmprim_dl_startup;
|
||||
vmprim.dl_cleanup = hcl_vmprim_dl_cleanup;
|
||||
vmprim.dl_open = hcl_vmprim_dl_open;
|
||||
vmprim.dl_close = hcl_vmprim_dl_close;
|
||||
vmprim.dl_getsym = hcl_vmprim_dl_getsym;
|
||||
vmprim.vm_gettime = hcl_vmprim_vm_gettime;
|
||||
vmprim.vm_sleep = hcl_vmprim_vm_sleep;
|
||||
#endif
|
||||
|
||||
proto = (hcl_server_proto_t*)hcl_server_allocmem(worker->server, HCL_SIZEOF(*proto));
|
||||
if (!proto) return HCL_NULL;
|
||||
|
||||
@ -684,11 +664,10 @@ hcl_server_proto_t* hcl_server_proto_open (hcl_oow_t xtnsize, hcl_server_worker_
|
||||
proto->worker = worker;
|
||||
proto->exec_runtime_event_index = HCL_TMR_INVALID_INDEX;
|
||||
|
||||
/* TODO: LARGE_PAGES */
|
||||
proto->hcl = hcl_openstdwithmmgr(hcl_server_getmmgr(proto->worker->server), HCL_SIZEOF(*xtn), worker->server->cfg.actor_heap_size, HCL_NULL);
|
||||
if (!proto->hcl) goto oops;
|
||||
|
||||
/* change the log_write primitive forcibly */
|
||||
/* replace the vmprim.log_write function */
|
||||
proto->hcl->vmprim.log_write = log_write;
|
||||
|
||||
xtn = (worker_hcl_xtn_t*)hcl_getxtn(proto->hcl);
|
||||
@ -1544,6 +1523,7 @@ hcl_server_t* hcl_server_open (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_server_p
|
||||
hcl = hcl_openstdwithmmgr(mmgr, HCL_SIZEOF(*xtn), 2048, errnum);
|
||||
if (!hcl) goto oops;
|
||||
|
||||
/* replace the vmprim.log_write function */
|
||||
hcl->vmprim.log_write = log_write_for_dummy;
|
||||
|
||||
tmr = hcl_tmr_open(hcl, 0, 1024); /* TOOD: make the timer's default size configurable */
|
||||
|
@ -51,10 +51,8 @@ enum hcl_server_trait_t
|
||||
{
|
||||
#if defined(HCL_BUILD_DEBUG)
|
||||
HCL_SERVER_TRAIT_DEBUG_GC = (1 << 0),
|
||||
HCL_SERVER_TRAIT_DEBUG_BIGINT = (1 << 1),
|
||||
HCL_SERVER_TRAIT_DEBUG_BIGINT = (1 << 1)
|
||||
#endif
|
||||
|
||||
HCL_SERVER_TRAIT_USE_LARGE_PAGES = (1 << 2)
|
||||
};
|
||||
typedef enum hcl_server_trait_t hcl_server_trait_t;
|
||||
|
||||
|
@ -157,14 +157,13 @@ int hcl_init (hcl_t* hcl, hcl_mmgr_t* mmgr, hcl_oow_t heapsz, const hcl_vmprim_t
|
||||
hcl->proc_map_free_first = -1;
|
||||
hcl->proc_map_free_last = -1;
|
||||
|
||||
hcl->heap = hcl_makeheap(hcl, heapsz);
|
||||
if (HCL_UNLIKELY(!hcl->heap)) goto oops;
|
||||
/* remember the requested heap size. but push back the actuall heap creation to hcl_ignite() */
|
||||
hcl->_reqheapsz = heapsz;
|
||||
|
||||
if (hcl->vmprim.dl_startup) hcl->vmprim.dl_startup (hcl);
|
||||
return 0;
|
||||
|
||||
oops:
|
||||
if (hcl->heap) hcl_killheap (hcl, hcl->heap);
|
||||
if (modtab_inited) hcl_rbt_fini (&hcl->modtab);
|
||||
if (hcl->gci.stack.ptr)
|
||||
{
|
||||
@ -309,7 +308,7 @@ void hcl_fini (hcl_t* hcl)
|
||||
hcl->gci.stack.len = 0;
|
||||
}
|
||||
|
||||
hcl_killheap (hcl, hcl->heap);
|
||||
if (hcl->heap) hcl_killheap (hcl, hcl->heap);
|
||||
|
||||
if (hcl->log.ptr)
|
||||
{
|
||||
|
@ -918,7 +918,7 @@ typedef enum hcl_log_mask_t hcl_log_mask_t;
|
||||
|
||||
typedef void* (*hcl_alloc_heap_t) (
|
||||
hcl_t* hcl,
|
||||
hcl_oow_t size
|
||||
hcl_oow_t* size /* [IN] requested size, [OUT] allocated size */
|
||||
);
|
||||
|
||||
typedef void (*hcl_free_heap_t) (
|
||||
@ -1392,6 +1392,7 @@ struct hcl_t
|
||||
} log;
|
||||
/* ========================= */
|
||||
|
||||
hcl_oow_t _reqheapsz;
|
||||
hcl_heap_t* heap;
|
||||
|
||||
/* ========================= */
|
||||
|
14
lib/heap.c
14
lib/heap.c
@ -44,8 +44,10 @@ static void xma_free (hcl_mmgr_t* mmgr, void* ptr)
|
||||
hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size)
|
||||
{
|
||||
hcl_heap_t* heap;
|
||||
hcl_oow_t alloc_size;
|
||||
|
||||
heap = (hcl_heap_t*)hcl->vmprim.alloc_heap(hcl, HCL_SIZEOF(*heap) + size);
|
||||
alloc_size = HCL_SIZEOF(*heap) + size;
|
||||
heap = (hcl_heap_t*)hcl->vmprim.alloc_heap(hcl, &alloc_size);
|
||||
if (HCL_UNLIKELY(!heap))
|
||||
{
|
||||
const hcl_ooch_t* oldmsg = hcl_backuperrmsg(hcl);
|
||||
@ -53,11 +55,13 @@ hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size)
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
HCL_MEMSET (heap, 0, HCL_SIZEOF(*heap) + size);
|
||||
/* the vmprim.alloc_heap() function is allowed to create a bigger heap than the requested size.
|
||||
* if the created heap is bigger than requested, the heap will be utilized in full. */
|
||||
HCL_ASSERT (hcl, alloc_size >= HCL_SIZEOF(*heap) + size);
|
||||
HCL_MEMSET (heap, 0, alloc_size);
|
||||
|
||||
heap->base = (hcl_uint8_t*)(heap + 1);
|
||||
heap->size = size;
|
||||
|
||||
heap->size = alloc_size;
|
||||
|
||||
if (size <= 0)
|
||||
{
|
||||
@ -71,7 +75,7 @@ hcl_heap_t* hcl_makeheap (hcl_t* hcl, hcl_oow_t size)
|
||||
if (HCL_UNLIKELY(!heap->xma))
|
||||
{
|
||||
hcl->vmprim.free_heap (hcl, heap);
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSMEM, "unable to allocate xma");
|
||||
hcl_seterrbfmt (hcl, HCL_ESYSMEM, "unable to allocate a memory manager over a heap");
|
||||
return HCL_NULL;
|
||||
}
|
||||
|
||||
|
90
lib/std.c
90
lib/std.c
@ -975,7 +975,36 @@ static void _assertfail (hcl_t* hcl, const hcl_bch_t* expr, const hcl_bch_t* fil
|
||||
* HEAP ALLOCATION
|
||||
* ----------------------------------------------------------------- */
|
||||
|
||||
static void* alloc_heap (hcl_t* hcl, hcl_oow_t size)
|
||||
static int get_huge_page_size (hcl_t* hcl, hcl_oow_t* page_size)
|
||||
{
|
||||
FILE* fp;
|
||||
char buf[256];
|
||||
|
||||
fp = fopen("/proc/meminfo", "r");
|
||||
if (!fp) return -1;
|
||||
|
||||
while (!feof(fp))
|
||||
{
|
||||
if (fgets(buf, sizeof(buf) - 1, fp) == NULL) goto oops;
|
||||
|
||||
if (strncmp(buf, "Hugepagesize: ", 13) == 0)
|
||||
{
|
||||
unsigned long int tmp;
|
||||
tmp = strtoul(&buf[13], NULL, 10);
|
||||
if (tmp == HCL_TYPE_MAX(unsigned long int) && errno == ERANGE) goto oops;
|
||||
|
||||
*page_size = tmp * 1024; /* KBytes to Bytes */
|
||||
fclose (fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
oops:
|
||||
fclose (fp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void* alloc_heap (hcl_t* hcl, hcl_oow_t* size)
|
||||
{
|
||||
#if defined(HAVE_MMAP) && defined(HAVE_MUNMAP) && defined(MAP_ANONYMOUS)
|
||||
/* It's called via hcl_makeheap() when HCL creates a GC heap.
|
||||
@ -990,37 +1019,60 @@ static void* alloc_heap (hcl_t* hcl, hcl_oow_t size)
|
||||
|
||||
hcl_oow_t* ptr;
|
||||
int flags;
|
||||
hcl_oow_t actual_size;
|
||||
hcl_oow_t req_size, align, aligned_size;
|
||||
|
||||
req_size = HCL_SIZEOF(hcl_oow_t) + *size;
|
||||
flags = MAP_PRIVATE | MAP_ANONYMOUS;
|
||||
|
||||
#if defined(MAP_HUGETLB)
|
||||
flags |= MAP_HUGETLB;
|
||||
#endif
|
||||
|
||||
#if defined(MAP_UNINITIALIZED)
|
||||
flags |= MAP_UNINITIALIZED;
|
||||
#endif
|
||||
|
||||
actual_size = HCL_SIZEOF(hcl_oow_t) + size;
|
||||
actual_size = HCL_ALIGN_POW2(actual_size, 2 * 1024 * 1024);
|
||||
ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||
#if defined(MAP_HUGETLB)
|
||||
if (get_huge_page_size(hcl, &align) <= -1) align = 2 * 1024 * 1024; /* default to 2MB */
|
||||
if (req_size > align / 2)
|
||||
{
|
||||
/* if the requested size is large enough, attempt HUGETLB */
|
||||
flags |= MAP_HUGETLB;
|
||||
}
|
||||
else
|
||||
{
|
||||
align = sysconf(_SC_PAGESIZE);
|
||||
}
|
||||
#else
|
||||
align = sysconf(_SC_PAGESIZE);
|
||||
#endif
|
||||
|
||||
aligned_size = HCL_ALIGN_POW2(req_size, align);
|
||||
ptr = (hcl_oow_t*)mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||
#if defined(MAP_HUGETLB)
|
||||
if (ptr == MAP_FAILED && (flags & MAP_HUGETLB))
|
||||
{
|
||||
flags &= ~MAP_HUGETLB;
|
||||
align = sysconf(_SC_PAGESIZE);
|
||||
aligned_size = HCL_ALIGN_POW2(req_size, align);
|
||||
ptr = (hcl_oow_t*)mmap(NULL, aligned_size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||
if (ptr == MAP_FAILED)
|
||||
{
|
||||
#if defined(MAP_HUGETLB)
|
||||
flags &= ~MAP_HUGETLB;
|
||||
ptr = (hcl_oow_t*)mmap(NULL, actual_size, PROT_READ | PROT_WRITE, flags, -1, 0);
|
||||
if (ptr == MAP_FAILED) return HCL_NULL;
|
||||
#else
|
||||
hcl_seterrwithsyserr (hcl, 0, errno);
|
||||
return HCL_NULL;
|
||||
#endif
|
||||
}
|
||||
*ptr = actual_size;
|
||||
}
|
||||
#else
|
||||
if (ptr == MAP_FAILED)
|
||||
{
|
||||
hcl_seterrwithsyserr (hcl, 0, errno);
|
||||
return HCL_NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
*ptr = aligned_size;
|
||||
*size = aligned_size - HCL_SIZEOF(hcl_oow_t);
|
||||
|
||||
return (void*)(ptr + 1);
|
||||
|
||||
#else
|
||||
return HCL_MMGR_ALLOC(hcl->_mmgr, size);
|
||||
return HCL_MMGR_ALLOC(hcl->_mmgr, *size);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -2864,6 +2916,7 @@ static void cb_vm_cleanup (hcl_t* hcl)
|
||||
MUTEX_DESTROY (&xtn->ev.reg.smtx);
|
||||
#endif
|
||||
}
|
||||
|
||||
/* -----------------------------------------------------------------
|
||||
* STANDARD HCL
|
||||
* ----------------------------------------------------------------- */
|
||||
@ -2875,11 +2928,8 @@ hcl_t* hcl_openstdwithmmgr (hcl_mmgr_t* mmgr, hcl_oow_t xtnsize, hcl_oow_t heaps
|
||||
hcl_cb_t cb;
|
||||
|
||||
HCL_MEMSET (&vmprim, 0, HCL_SIZEOF(vmprim));
|
||||
//if (large_pages)
|
||||
//{
|
||||
vmprim.alloc_heap = alloc_heap;
|
||||
vmprim.free_heap = free_heap;
|
||||
//}
|
||||
vmprim.log_write = log_write;
|
||||
vmprim.syserrstrb = _syserrstrb;
|
||||
vmprim.assertfail = _assertfail;
|
||||
|
Loading…
Reference in New Issue
Block a user