Re: [Haskell-cafe] Rewrite NetBSD kernel driver using Ajhc Haskell compiler

Hi Johnny,
On Wed, Feb 19, 2014 at 11:57 PM, Johnny Billquist
Maybe someone with more insight could explain to an idiot like me how Haskell garbage collection is handled when running in the kernel?
First, s_alloc() is Ajhc Haskell compiler's allocator, and gc_perform_gc() is GC runner. https://github.com/ajhc/ajhc/blob/6c053b940812689fe22d2dbe2b7ad835dab8a3c7/r... https://github.com/ajhc/ajhc/blob/6c053b940812689fe22d2dbe2b7ad835dab8a3c7/r... The s_alloc() try to find free area. But if not, it runs GC. https://github.com/ajhc/ajhc/blob/6c053b940812689fe22d2dbe2b7ad835dab8a3c7/r... By the way, where from s_alloc() get a memory chunk? Now using kern_malloc(9). https://github.com/metasepi/netbsd-arafura-s1/blob/arafura-s1/metasepi/sys/h... Regards, -- Kiwamu Okabe

Hi Johnny, I had forgotten important point.
On Wed, Feb 19, 2014 at 11:57 PM, Johnny Billquist
wrote: Maybe someone with more insight could explain to an idiot like me how Haskell garbage collection is handled when running in the kernel?
Running a simple logic in the kernel, it doesn't call GC. http://www.slideshare.net/master_q/20140117-11th-wocs2/19 Ajhc Haskell compiler creates program binary that has "context local heap". A lot of binaries have only one global heap. If C language code calls Haskell code, Ajhc runtime create new arena for GC. Sometime Haskell code runs allocator (s_alloc()), then the runtime allocates Heap area. Haskell context gets the end of life, the arena and heap are recovered by the runtime. In the kernel, the recover is called before the GC. But I think my custom kernel is ready to call GC in interrupt handler. Thank's, -- Kiwamu Okabe

On Wed, Feb 19, 2014 at 9:30 AM, Kiwamu Okabe
Hi Johnny, I had forgotten important point.
On Wed, Feb 19, 2014 at 11:57 PM, Johnny Billquist
wrote: Maybe someone with more insight could explain to an idiot like me how Haskell garbage collection is handled when running in the kernel?
Running a simple logic in the kernel, it doesn't call GC.
Having looked over the source, I couldn't get much of a feel for it -
it mostly seemed to be FFI & type declarations. Which does make sense
since the goal is to provide strong type checking in the kernel. Maybe
I'm looking in the wrong place in that rather large repository?
My question is how much does coding to meet the requirements for a
device driver - not doing GC being one of them - warp the resulting
Haskell code? Is it still pretty much idiomatic Haskell, or would it
be easier for a Haskell programmer to figure out the C it replaced?
Most of the time I've seen people try and get a modern language to
meet such requirements (me included), you might as well have stuck
with C as far as code improvement goes.
One of the advantages C has in the kernel - the BSD kernels, anyway,
reading Linux kernel makes me queasy - is that it isn't that different
from C in userland. And the kernel groups have been working on
reducing over the differences.
Thanks,

Hi Mike,
On Thu, Feb 20, 2014 at 8:34 AM, Mike Meyer
Running a simple logic in the kernel, it doesn't call GC.
Having looked over the source, I couldn't get much of a feel for it - it mostly seemed to be FFI & type declarations. Which does make sense since the goal is to provide strong type checking in the kernel. Maybe I'm looking in the wrong place in that rather large repository?
You are right. It's just "exercise". I would like to prove that can write code with functional language in interrupt context.
My question is how much does coding to meet the requirements for a device driver - not doing GC being one of them - warp the resulting Haskell code? Is it still pretty much idiomatic Haskell, or would it be easier for a Haskell programmer to figure out the C it replaced? Most of the time I've seen people try and get a modern language to meet such requirements (me included), you might as well have stuck with C as far as code improvement goes.
This exercise has logic code at following. https://github.com/metasepi/netbsd-arafura-s1/blob/arafura-s1/metasepi/sys/h... https://github.com/metasepi/netbsd-arafura-s1/blob/arafura-s1/metasepi/sys/h... https://github.com/metasepi/netbsd-arafura-s1/blob/arafura-s1/metasepi/sys/h... I re-write these from NetBSD's implementation, for a month. But now can get more speed with our new tool, convert C language API definition into Haskell API definition semi-automatically. https://github.com/ajhc/struct2hs Following is usage of the tool. $ struct2hs $HOME/src/netbsd-arafura-s1/obj/tooldir/bin/i486--netbsdelf-gcc "-Di386 -I$HOME/src/netbsd-arafura-s1/sys/arch/i386/compile/obj/GENERIC_HS ... sys/dev/pci/hdaudio/hdaudio.c | tail -15 newtype {-# CTYPE "struct pdevinit" #-} Pdevinit = Pdevinit () foreign import primitive "const.sizeof(struct pdevinit)" sizeOf_Pdevinit :: Int foreign import primitive "const.offsetof(struct pdevinit, pdev_attach)" offsetOf_Pdevinit_pdev_attach :: Int p_Pdevinit_pdev_attach :: Ptr Pdevinit -> IO (Ptr (Ptr (FunPtr (Int -> IO ())))) p_Pdevinit_pdev_attach p = return $ plusPtr p $ offsetOf_Pdevinit_pdev_attach foreign import ccall "dynamic" call_Pdevinit_pdev_attach :: FunPtr (Int -> IO ()) -> Int -> IO () foreign import primitive "const.offsetof(struct pdevinit, pdev_count)" offsetOf_Pdevinit_pdev_count :: Int p_Pdevinit_pdev_count :: Ptr Pdevinit -> IO (Ptr Int) p_Pdevinit_pdev_count p = return $ plusPtr p $ offsetOf_Pdevinit_pdev_count
One of the advantages C has in the kernel - the BSD kernels, anyway, reading Linux kernel makes me queasy - is that it isn't that different from C in userland. And the kernel groups have been working on reducing over the differences.
I hope so... But, I think Ajhc is not good for real kernel products, after this hard challenge. ATS language is much betther than Ajhc. Hongwei, as ATS author, says following. I perfectly agree his opinion. http://metasepi.org/posts/2013-12-24-jats-ug.html#%E4%B8%80%E9%80%9A%E3%81%A... Regards, -- Kiwamu Okabe
participants (2)
-
Kiwamu Okabe
-
Mike Meyer