[Haskell-cafe] [Rejected Paper] Experience Report: Writing NetBSD Sound Drivers in Haskell

John Meacham john at repetae.net
Tue Jun 10 10:55:21 UTC 2014


Oooh. and you documented jhc's RTS while you were at it. that is great :)




I have been thinking about a way to extend JGC to seamlessly handle
interfaces that utilize stack allocated C structs. The main target
being GMP. Right now I can do pretty well by having a 'self-pointing'
'self-cleaning' ForeignPtr. The definition of ForeignPtr is

> data ForeginPtr = ForeignPtr Addr_

However, it is a little magic in that you can allocate it in a larger
space than it would naturally take up, I can then have Addr_ point to
the word following it directly in memory. The garbage collector treats
it just like normal and needs no finalizer, as long as the ForeginPtr
is live, the area it points to is live since they are the same space,
as far as the code is concerned it could be pointing to an external C
structure. This is very efficient and a very fast way to throw around
C structures without having to worry about whether they were allocated
in haskell or in C.

However, things like GMP require the memory region to be initialized
and freed since it may have internal pointers. I could just continue
with standard foreign pointers, attaching a destructor, but this has a
couple problems

- I have to initialize the memory area, this is hard to do without
invoking the IO monad to ensure proper sequencing, for the result of
an addition, that seems heavy, it is hard for the complier to "see
through" an unsafePerformIO  when optimizing.

- every Integer will have to carry around two extra words, a self
pointer that always points to its own memory location, and a pointer
to a destructor that is always going to be the same.

- memory will be destructed when it is likely to immediately be
re-used as an Integer, it would be good to deforest this
destruct-construct pair.

To solve both I was thinking of assosciating a contructor/destructor
with a type rather than a value. By creating an entire block of the
same type, it can initialize the entire block at once, then delay the
destructor until the entire block is freed. since GMP ints can be
re-used in place, it would get rid of almost all initialization and
destruction overhead. A 'delayed destructor' if you will, that only
needs to be called if the memory location is going to be used for a
different type. Allocations in jhc are already tagged by type so this
isn't difficult to keep track of. I was thinking something like

data
   {-# CCONSTRUCTOR  "init_integer" #-}
   {-# CDESTRUCTOR delayed "fini_integer" #-}
   Integer_ :: #

data Integer = Integer Integer_

since Integer_ is unboxed, we can ensure they are only created in the
right heap by using a primitive to do so, there is no way for a user
to conjure up an unboxed type that doesn't take part in unboxed num
polymorphism so can be represented by 0# 1# etc.

    John



On Tue, Jun 10, 2014 at 3:13 AM, Kiwamu Okabe <kiwamu at debian.or.jp> wrote:
> Hi jhc-hackers,
>
> I have written a paper "Experience Report: Writing NetBSD Sound
> Drivers in Haskell".
>
> http://metasepi.org/papers.html
>
> It explains Ajhc customized jhc GC, and sometime useful to develop jhc.
>
> Thank's,
> --
> Kiwamu Okabe at METASEPI DESIGN
> _______________________________________________
> Haskell-Cafe mailing list
> Haskell-Cafe at haskell.org
> http://www.haskell.org/mailman/listinfo/haskell-cafe



-- 
John Meacham - http://notanumber.net/


More information about the Haskell-Cafe mailing list