Updated: 11/5/2005; 6:09:38 PM.
Chris Double's Radio Weblog

Friday, July 29, 2005

I've been working on a concurrency library for Factor, based on Erlang and Termite style concurrency. So far I've got light-weight processes implemented using Factor threads (which are in turn implemented using continuations). Each thread has a channel for sending and receiving messages.

I've been able to create over 100,000 processes, each sending messages around quite efficiently. Each process takes about 900 bytes of memory. Once I've tidied up the code a bit and decided on decent names for things I'll put the code in the 'contrib' directory of Factor CVS.

Most of the examples from the Termite papers work fine, including sending continuations to processes to 'update' the process with new code and linking processes so errors are propogated.

Everything works inside a single Factor instance at the moment but the next step I will be working on is getting things working in a distributed manner so processes can send messages to processes running in other Factor images.

Using the current 'in-flux' syntax, here's an example of a simple rpc server:
: rpc-server ( -- server )
  #! Process RPC requests where the message data
  #! is a list. The first item of the list is the function
  #! to execute. The remainder of the list are the arguments
  #! to that function.
      [ message? [ [ car add = ]     [ cdr 0 [ + ] reduce ] !result ] ]
      [ message? [ [ car product = ] [ cdr 1 [ * ] reduce ] !result ] ]
    ] recv
  ] spawn-server ;
The '!result' word takes a message and two quotations from the stack. It checks what the message is for (add or product) and then runs the second quotation on the message. The result of that is sent back to the calling process. Calling this server is as simple as:
  [ add 1 2 3 ] rpc-server !? 
    => 6
  [ product 2 4 ] rpc-server !?
    => 8
'!' is send, '?' receive and '!?' sends and waits for the result. As per the termite paper. I'll probably need to change these in the final result for Factor though as '!' is usually the comment character and '?' is used for other purposes too.

I'm leaning towards using Factor tuples as messages and just using the predicate dispatch mechanism inside the server message loop. The current 'recv' word sort of does this already and it seems to make sense to use what is already built into Factor instead. Doing pattern matching and deconstructing lists doesn't seem to make a lot of sense when you don't have variables to assign them to.

On top of this framework I've added 'futures', which work similar to Alice and Io futures. This looks like:
  [ 42 fib ] future
  ...some other stuff...
  ?future .
'future' runs a quotation inside a process and returns a 'future' on the stack. '?future' will return the value of that quotation if it has completed running, or it will block the current process until it is complete and then return the value.

Lazy evaluation works as well but I think it is less useful in Factor:
  [ 42 fib ] lazy 
  ...some stuff...
  ?lazy .
This spawns a process and returns a lazy future. When that lazy future is evaluated using '?lazy' then it will run it and return the result. But I don't see any advantage over just using a normal quotation for this purpose at the moment.

I hope to have some code released in the next week or so. And I'll post some benchmarking and examples here when done.

1:59:38 PM      

© Copyright 2005 Chris Double.
July 2005
Sun Mon Tue Wed Thu Fri Sat
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
Jun   Aug

Click here to visit the Radio UserLand website.

Listed on BlogShares

Click to see the XML version of this web page.

Click here to send an email to the editor of this weblog.