green_threads

Stefan Seifert nine at detonation.org
Tue Oct 11 18:29:56 UTC 2011


Dear parrot developers,

during the past two months I've been working on bringing the gsoc_threads 
branch up to date and into a usable shape. Now I got to the point were serious 
talk about merging and future development is due. fulltest passes, as does 
Rakudo's spectests. On git at github.com:niner/parrot.git I have a green_threads 
branch containing my work.

So what are "green threads"? Green threads or tasks are lightweight threads. 
They exist only within the interpreter and do not use operating system 
facilities like threads or processes. Instead, the interpreter itself contains 
a scheduler which manages running tasks and switches between them.

Where are we now? Parrot_pf_execute_bytecode_program got changed to instead of 
calling the main sub directly, starting up the scheduler and running the main 
sub as the first task. The scheduler preemptively switches tasks every 20ms. 
Tasks can be started directly or as result of an expired alarm or a fireing 
timer. Attached is a little test program demonstrating task switching.

There are some restrictions to the current implementation:
* Blocking I/O and native calls block the whole interpreter, so no task
  switches occur
* Preemptive task switching only works if the current task is in the top most
  runloop. Otherwise the task switch is skipped and hopefully the task
  returned to runloop 1 for the next task switch
* Voluntary task switching (calling sleep or pass) suffers the same
  restriction. Even worse, trying it anyway will currently end up in a corrupt
  stack. A workaround will be to block the whole interpreter for sleep and
  probably ignore a pass.

In short: runloops are a real hassle. But tasks can still be useful. One could 
use them for handling signals for example.

Possible ways forward from here:
An immediate improvement will be to stop preemption if only one task is 
active. Or the other way around: start the scheduler's timer only when a 
second task gets added to the list. This way, tasks will have zero overhead in 
the common case.

The restriction of blocking I/O could be circumvented by using asynchronous 
I/O instead and and suspending the task in the meanwhile. This would be a nice 
performance improvement for I/O bound programs.

Obviously real threads could fix this as well. They seem inevitable in the long 
run anyway. But of course, those are a huge amount of work.

Any change that removes nested runloops will be very much welcomed :)

In any case, I think it's time to start some serious communications with 
Rakudo folks about these features and where to go from now. Most of all we 
need feedback.

Stefan
-------------- next part --------------
#!./parrot

.sub main :main
    .local pmc task, a, b
    task = get_global 'task'
    a = new ['String']
    a = "a"
    b = new ['String']
    b = "b"
    $P0 = new ['Task']
    setattribute $P0, 'code', task
    setattribute $P0, 'data', a
    $P1 = new ['Task']
    setattribute $P1, 'code', task
    setattribute $P1, 'data', b
    schedule $P0
    schedule $P1
.end

.sub task
    .param pmc name
    .local int i
start:
    print name
    i = 0
loop:
    inc i
    if i >= 100000 goto start
    goto loop
.end
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: This is a digitally signed message part.
URL: <http://lists.parrot.org/pipermail/parrot-dev/attachments/20111011/abcf14cf/attachment.asc>


More information about the parrot-dev mailing list