Home

Delay after Delay

In Delay after Delay, Travis Griggs thinks that “Delay is a fun class to explore”.

That might be, until you hit a side of it that is less fun.

Kolibri relies heavily on processes and delays - and on terminating them, which is most probably the main cause of our problems. Andreas Raab pointed out that terminating a process that is in a Delay that is busy being scheduled has a risk of being terminated inside the #add: method of SortedCollection - especially with a lot of Delays being active, chances are that #add: has to do some shuffling around and thus becomes slow enough to stand a serious risk of being interrupted. For the time being, we’ve decided to patch it by protecting the add in a block that’s evaluated with #valueUnpreemtively.

Ever since I found a deadlock with two Semaphores last year (after a long debugging session), I’ve been unhappy about this system that ticks with lots of processes, delays, semaphores. Not only does it become brittle, but every time you have a delay somewhere you automatically get a unit testing headache.

Kolibri is out the door, so it’s a bit late now to re-work the internals. However, I’m still wondering about alternative programming models - Linda, E, etcetera - and whether we shouldn’t try harder in Smalltalk to make these the default, instead of the error-prone manual labour we’re currently supposed to do.

No, I don’t have a solution. It’s just a thought I wanted to share, maybe it’ll provoke some responses.


Stumble it!  Post to del.icio.us 

3 Responses to “Delay after Delay”

  1. Reinout Heeck Says:

    All I can say is ‘me too’.
    I complain often about how unbelievably primitive programming (even in Smalltalk) is nowadays, multithreading is just one aspect of that primitiveness.

    Like you I am very much interested to see multithreading addressed ‘properly’ in Smalltalk. Erlang is high on my radar for providing a usable model to carry Smalltalk multithreading into this century.

  2. Stephen Pair Says:

    Me three…here at work, we’ve implemented a concurrency system along the lines of that described in the ControlWorks paper. It certainly makes concurrent processing and exception semantics much, much cleaner. The following is a simple example that runs an application and waits on a termination signal…the expression terminates when either child process completes and an exception in either child process will propagate into the parent process. It’s an example of a “disjunctive” joint (you can also do conjunctive joints and any combination of the two). In combination with “dynamic bindings” (see SqueakMap or Store repository), we can also mimic Unix style piping (except that our pipes move objects, not just bytes). We’re slowly moving to a system where our apps all launch from a single process and only branch out to multiple processes using the control structures.

    | app term |
    app := [self runApplication].
    term := [self waitForSigTerm].
    (app | term) value.

    I also share the dis-satisfaction with Delay, especially how it impacts unit testing…we’re trying hard to better factor the use of real time in our application to eliminate the need for any real time delays while running our tests.

  3. Joerg Says:

    I’m going to be very “me to” and also stick up my hand. Smalltalk has all these great abstractions except when it comes back to dealing with concurrency. There are two approaches I’ve thought about playing with:

    1) Using channels as is done in “limbo”
    http://www.byte.com/art/9710/sec4/art5.htm and http://www.vitanuova.com/inferno/papers/descent.html.
    These are along the lines of Hore’s CSP’s. Interestingly the asyncronous event architecture choosen for Tweak seems very close to the notion of channels. Also if I read Stephens comment correctly so do some elements of the ControlWorks infrastructure. Some of the ATT papers indicate libo channels were intented to be a kind of abstraction of pipes.

    2) Add adding Transactional Memory. See for example:
    http://www.cambridge.intel-research.net/~rennals/faststm.html
    In this case there is no need to worry about deadlock or priority inversion. So building threadsafe data structures becomes much simpler.

    The first seems very Smaltalkish and certainly channels could be added and made available as a coummunications primative. But to enforce them as the only interprocess communications mechanism is a much bigger problem. There would be quite a shift in how the image is structured and functions. Objects in the image would be partitioned between threads and to communicate with an object in another thread means not invoking a method but sending something over a channel. I’m not even sure if this could be done in Smalltalk given how self-referential the image is.

    Transaction memory on the other had is just a better tool to manage multiple threads in the same memory space. There would be no need to change any of the Smalltalk semantices. I think all that would be needed is a inOneTransactionDo: aBlock method. Implementation wise I think both a write and read barrier is needed.

Leave a Reply

(note: comments may be moderated so don't always appear right away)


Copyright (C)2000-2005 Cees de Groot -- All rights reserved.