Csound Csound-dev Csound-tekno Search About

[CSOUND-DEV:5592] RE: FLTK threading rules and Csound4

Date2004-12-27 14:49
From"gogins@pipeline.com"
Subject[CSOUND-DEV:5592] RE: FLTK threading rules and Csound4
This is interesting, because my experience with CsoundVST is different.

CsoundVST is uses FLTK. CsoundVST runs Csound in a spawned thread, and FLTK
from the main thread. FLTK is compiled for multi-threading.

Both threads call Fl::lock();Fl::wait(0);Fl::unlock(); with no problem. I
never call Fl::awake() (this is the first I've heard of it). 

CsoundVST will run performances with FLTK widgets in real time with no
problems that I have seen. I don't do this often, but I do it every time I
run a major rebuild -- on Windows. 

I also periodically rebuild CsoundVST on Linux and make sure it runs, but I
don't think I've tried a realtime performance with FLTK widgets on Linux. I
will try that next I time I test on Linux.

Original Message:
-----------------
From:  ramsdell@mitre.org (John D. Ramsdell)
Date: 27 Dec 2004 01:37:40 -0500
To: csound-dev@eartha.mills.edu
Subject: [CSOUND-DEV:5591] FLTK threading rules and Csound4


I decided to make it so that flCsound can be compiled in a mode in
which GUI events are handled in one thread, and the Csound engine
renders in another.  Before designing the code changes, I spend a fair
amount of time reading both the FLTK manual and key parts of its
source code.  What I learned about FLTK 1.1.6 makes me wonder about
other uses of FLTK in Csound4.

The FLTK manual makes promises about the library's behavior to those
who follow some rules.  The rules for a single threaded application
are simple.  For example, to ensure the GUI is responsive, one must
make sure Fl::wait or Fl::check in called often enough so that events
are handled in a timely fashion.

The rules for a multi-threaded applications are more complex, although
FLTK is much simpler than wxWidgets.  The first thing one must do is
ensure the FLTK was compiled with multi-threading support enabled
(--enable-threads).  Before any threads are spawned, the main thread
must call Fl::lock to initialize threading support in FLTK.  A spawned
thread must call Fl::lock before it updates widgets and data, and
finish by calling Fl::unlock.  The main thread is the only one allowed
to call Fl::wait or Fl::check.  When Fl::wait is waiting for input or
timeouts, spawned threads are given access to FLTK.  Finally, a
spawned thread can prod the main thread into processing events by
calling Fl::awake.

Given this background, it turns out that it is fairly straightforward
to make it so that flCsound can be compiled in a mode in which GUI
events are handled in one thread, and the Csound engine renders in
another.  The program appears to work well in this mode until one
renders a piece with an orchestra containing some of the FL* opcodes.
These opcodes need access to FLTK, but the code that makes the access
is not surrounded by a Fl::lock/Fl::unlock pair.  Furthermore, FLrun
invokes Fl::wait via Fl::run in a thread other than flCsound's main
thread.  Needless to say, bad things happen.

It turns out that flCsound compiled in single threaded mode, does
handle pieces that contain FL* opcodes, or so it seems.  The FLTK
authors clearly say one should not rely on this outcome.

John


--------------------------------------------------------------------
mail2web - Check your email from the web at
http://mail2web.com/ .

Date2004-12-27 15:21
Fromramsdell@mitre.org (John D. Ramsdell)
Subject[CSOUND-DEV:5593] RE: FLTK threading rules and Csound4
"gogins@pipeline.com"  writes:

> This is interesting, because my experience with CsoundVST is different.
> 
> CsoundVST is uses FLTK. CsoundVST runs Csound in a spawned thread, and FLTK
> from the main thread. FLTK is compiled for multi-threading.
> 
> Both threads call Fl::lock();Fl::wait(0);Fl::unlock(); with no problem. I
> never call Fl::awake() (this is the first I've heard of it). 

I'm was confident that CsoundVST correctly used FLTK and followed its
rules for multi-threaded applications.  The focus of my comments is
what's csound/widgets.cpp.  It's a fluke if the FLTK opcodes defined
in this file correctly worked with CsoundVST, because one can plainly
see they do not follow the rules for multi-threaded applications.  

A key point I would like to emphasize, is that just because the
opcodes seem to work, that does not mean the implementation is
correct.  Very soon, nearly all machines that will be used to run
Csound will contain more than one processor.  On these machines,
unprotected shared state will be accessed and modified by multiple
threads in very unpredictable ways, ways not available on uniprocessor
machines.

To read more about why the age of the uniprocessor is dead, see Gibbs,
W. Wayt, "A Split at the Core", Scientific American, Volume 291,
Number 5, Pages 96-100.

Also note that I updated Csound4's configure.ac file so that it probes
the FLTK library to see if it was compiled with thread support
enabled.  When it is, it defines HAVE_FL__LOCK.  The configuration
system for Csound5 should make an equivalent check.  The file
flcsound/src/main.cpp contains the code that generates a version of
flCsound that is either single or multi-threaded, based on
HAVE_FL__LOCK.

To fix the threading problem, I suspect csound/widgets.cpp will have
to changed so that the code in it employs the same tricks used by
flCsound's main routine, that is, the code will have to be
conditionalized on HAVE_FL__LOCK.

John