[Haskell-cafe] Rewrite NetBSD kernel driver using Ajhc Haskell compiler
Kiwamu Okabe
kiwamu at debian.or.jp
Thu Feb 20 09:01:08 UTC 2014
Hi Johnny,
On Thu, Feb 20, 2014 at 5:37 PM, Johnny Billquist <bqt at update.uu.se> wrote:
> Are you saying that you essentially avoid GC by creating a large fresh heap
> every time you call something written in Haskell, and then delete the heap
> when the Haskell function returns? And that the current piece of code
> running in Haskell is short enough that GC never is done?
No, does not delete. Pool it.
See following code compiled by Ajhc.
Ajhc compile Haskell code into C code.
https://gist.github.com/master-q/9109334
Please note auichIntr() function that is entry point C => Haskell.
https://gist.github.com/master-q/9109334#file-hsmain-c-L2051
int
auichIntr(HsPtr x272)
{
arena_t arena;
gc_t gc;
gc = NULL;
arena = NULL;
jhc_alloc_init(&gc,&arena);
jhc_hs_init(gc,arena);
int x273 = ((int)fFE$__CCall_auichIntr(gc,arena,(uintptr_t)x272));
jhc_alloc_fini(gc,arena);
return x273;
}
The code post-calls jhc_alloc_fini() that pool Haskell heap (named
megablock) into free_megablocks.
https://github.com/ajhc/ajhc/blob/d93468e34f4514209048d4a92b1549e079ccd3fb/rts/rts/gc_jgc.c#L251
void
jhc_alloc_fini(gc_t gc,arena_t arena) {
-- snip --
SLIST_FOREACH(pg, &arena->monolithic_blocks, link) {
SLIST_INSERT_HEAD(&free_monolithic_blocks, pg, link);
}
SLIST_FOREACH(mb, &arena->megablocks, next) {
SLIST_INSERT_HEAD(&free_megablocks, mb, next);
}
if(arena->current_megablock) {
SLIST_INSERT_HEAD(&free_megablocks,
arena->current_megablock, next);
}
Also s_alloc(), Haskell heap allocator, try to get Haskell heap from the pool.
If not found, it posix_memalign new megablock.
https://github.com/ajhc/ajhc/blob/d93468e34f4514209048d4a92b1549e079ccd3fb/rts/rts/gc_jgc.c#L392
struct s_megablock *
s_new_megablock(arena_t arena)
{
jhc_rts_lock();
struct s_megablock *mb = SLIST_FIRST(&free_megablocks);
if (mb) {
SLIST_REMOVE(&free_megablocks, mb, s_megablock, next);
} else {
mb = malloc(sizeof(*mb));
#ifdef _JHC_JGC_LIMITED_NUM_MEGABLOCK
static int count = 0;
if (count >= _JHC_JGC_LIMITED_NUM_MEGABLOCK) {
abort();
}
mb->base = aligned_megablock + (MEGABLOCK_SIZE) * count;
count++;
#else
mb->base = jhc_aligned_alloc(MEGABLOCK_SIZE);
#endif
Regards,
--
Kiwamu Okabe
More information about the Haskell-Cafe
mailing list