[racket] sync on OS semaphore on Unix

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Tue Feb 7 18:11:53 EST 2012

At Tue, 7 Feb 2012 23:07:15 +0100, Berthold Baeuml wrote:
> On 07.02.2012, at 00:35, Matthew Flatt wrote:
> 
> > While calling most scheme_...() function is out, can the real-time
> > thread call scheme_signal_received(), which amounts to a write() on an
> > native OS pipe?
> 
> Unfortunately not. 

Ok.

> But, a while ago you had conservation with John Clement about the 
> mzrt_sema_post call (which seem internally be realized using condition 
> variables and, hence, be OK on QNX). Might this call be a way to wake up the 
> racket main thread instead of scheme_signal_received()?

No. The mzrt_sema_post() function could be used to notify an OS thread
that is waiting on a semaphore, but it won't work the other way around.
The problem is that the main Racket thread cannot (as far as I know)
wait on both a semaphore and a set of file descriptors.

> > If not, I think we'll need a new OS thread at some level to convert a
> > semaphore wait to a call to scheme_signal_received(). The main Racket
> > thread on a Unix platform sleeps via epoll(), poll(), or select(), all
> > of which need file-descriptor activity to wake up (I think).
> 
> If mzrt_sema_post is no alternative, I will have to add one additional OS 
> thread, which is waked up by, e.g., a condition variable and then polls all OS 
> semaphores for all communications of the C threads with the racket main thread. 
> This way, only one OS thread is enough (and not one for each semaphore as I 
> thought yesterday).

Yes, that sounds like the right idea.

The one new thread will have to wake up the Racket thread using
scheme_signal_received(). Then, the polling of semaphores could happen
on the Racket side.


For an example of how to turn a poll into a synchronizable event, see

 "collects/mred/private/wx/common/queue.rkt"

around line 70. The key ingredients are

 1. Allocate a new type tag at the C level via scheme_make_type().

 2. Use scheme_add_evt() to register the tag as a synchronizable event,
    supplying a polling callback function. (You won't need a wakeup
    function.) Be sure to use `#:atomic? #t' in the type for the
    polling callback.


Posted on the users mailing list.