[prev in list] [next in list] [prev in thread] [next in thread] 

List:       haskell-cafe
Subject:    Re: [Haskell-cafe] Rewrite NetBSD kernel driver using Ajhc Haskell compiler
From:       Kiwamu Okabe <kiwamu () debian ! or ! jp>
Date:       2014-02-20 9:01:08
Message-ID: CAEvX6dmJD4YbwMi1Mzj1JFiNq3zuksk93tf+ERD2nqxXucrYhw () mail ! gmail ! com
[Download RAW message or body]

Hi Johnny,

On Thu, Feb 20, 2014 at 5:37 PM, Johnny Billquist <bqt@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
_______________________________________________
Haskell-Cafe mailing list
Haskell-Cafe@haskell.org
http://www.haskell.org/mailman/listinfo/haskell-cafe
[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic