[racket] sync on OS semaphore on Unix
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.