[Vm-dev] Re: Cog on Linux

Eliot Miranda eliot.miranda at gmail.com
Fri Jul 23 03:16:32 UTC 2010


Hi All,

    for those of you trying to get Cog working on linux I should say
something about the state of the linux port and what to watch out for as you
try and get the system up and running.

The Cog VMs depend on a heartbeat to periodically interrupt execution and
cause the system to poll for input.  The default implementation is a
high-priority thread that loops sleeping for a short time and then
interrupting the VM (by setting the VM's stackLimit to a value that will
cause the next frame-building send to check for stack overflow, which as a
side effect also checks for input).  The default heartbeat frequency is
either 500Hz (unix) or 1KHz (win32).  The heartbeat also updates the
system's clock on each beat, since accessing the clock can be quite
expensive and so updating at regular intervals actually provides a cheaper
clock with acceptable resolution.

The threaded heartbeat implementation depends on having multiple thread
priorities.  If the heartbeat thread runs at the same priority as the VM
thread then if the VM thread becomes compute intensive the heartbeat will be
starved of cycles.  The VM won't see input and the clock won't update.

The current state of posix threads on RedHat-derived linux distros is that
multiple thread priorities are only available to processes running with
superuser privileges, and so not practically available to the VM.  Hence the
unix heartbeat (platforms/unix/vm/sqUnixHeartbeat.c) provides a fallback
selected by defining ITIMER_HEARTBEAT=1 at compile time.  This avoids the
use of a thread and falls back to the ITIMER_REAL interval timer
(setitimer(2)).  This isn't ideal; we would like to use the heartbeat to run
other periodic high-priority activities, but with some fiddling it works.

At Teleplace we have some quite sophisticated media processing code that is
run for the heartbeat thread, except that on linux there isn't one.  So on
linux there is a second thread dedicated to these activities (see
platforms/Cross/vm/sqTicker.c for the facilities that allow one to install
periodic high-priority function calls) and a combination of forcing the VM
thread to block and sending SIGUSR2 to the "high-priority" thread (to break
it out of a blocking sleep) simulates a high-priority thread preempting the
VM thread, at least if you cross you fingers and its Wednesday.

But for linux users out there I need to emphasize that these shenanigans are
only necessary if the thread system doesn't support multiple priorities for
user-level processes.  If the thread system /does/ 't support multiple
priorities then the correct solution is to compile without
defining ITIMER_HEARTBEAT=1.  I think you'll find that if you compile
without ITIMER_HEARTBEAT the VM will complain if the thread system doesn't
allow it to set the heartbeat thread's priority above the VM thread's
priority.  So those of you on LinuxThreads where SIGUSR1 & SIGUSR2 are used
internally need to see whether the system does support multiple priorities
for user processes and if so a) abandon the ITIMER_HEARTBEAT, b) choose a
different signal to SIGUSR1 for provoking a printAllStacks report, and c)
report back what system you're on and if possible how to distinguish that
pthreads variant from the pthread.h header.

If on the other hand the system doesn't support multiple thread priorities
and still uses SIGUSR1 & SIGUSR2 internally (nice user-centric choice ;) )
then you need retain ITIMER_HEARTBEAT=1 and to find alternative signal
numbers for the prodding of the "high-priority" thread and the
printAllStacks report.

HTH
Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20100722/cbfb64b6/attachment.htm


More information about the Vm-dev mailing list