Conditional variables in threads

I am looking into getting some support for conditional variables in the
threads of SDL (pending approval from the powers that be, of course).

Basically, one or more threads can wait on a condition (SDL_CondWait())
and another thread can wake one (SDL_CondSignalOne()) or all
(SDL_CondSignalAll()) waiting threads.

This is easy enough to implement in POSIX threads because it’s already
there. For other UNIX systems I think it would be fairly easy to use the
same type of portable code that the mutex stuff does.

BeOS and Win32 are other beasts and I have no experience in their API.
Maybe there is already support or maybe something similar?

Anyway, I wanted to make sure that:

1)  people would find it useful, and
2)  someone else wasn't working on the same contribution.

The project I am working on might have use for it (hence I strive to get
it into SDL) but thought I would make the idea public in case there were
major thoughts from the group one way or another.

Paul Braman
@Paul_Braman

Paul Braman wrote:

[snip]

Anyway, I wanted to make sure that:

    1)  people would find it useful, and

I think conditional variables would be very usefull. SDL does have a
Mutex mechism, but conditional variables are far more efficient, because
the waiting thread uses no cpu time.

[snip]

The project I am working on might have use for it (hence I strive to get
it into SDL) but thought I would make the idea public in case there were
major thoughts from the group one way or another.

cool, If they don’t make it into SDL proper, I’m sure that many people
would be happy to have access to the feature as a 3rd party library.

			-fjr

I think conditional variables would be very usefull. SDL does have a
Mutex mechism, but conditional variables are far more efficient, because
the waiting thread uses no cpu time.
Implementing conditional variables on to of Mutexes uses the same amount
of cpu to wait (none) as does using just mutexes (AFAIK). Or am I
confused, why would waiting for a mutex trigger waste the CPU?

Stuart

Stuart Anderson wrote:

I think conditional variables would be very usefull. SDL does have a
Mutex mechism, but conditional variables are far more efficient, because
the waiting thread uses no cpu time.
Implementing conditional variables on to of Mutexes uses the same amount
of cpu to wait (none) as does using just mutexes (AFAIK). Or am I
confused, why would waiting for a mutex trigger waste the CPU?

While I haven’t looked into the code, I know SDL Mutexes are implemented
with binary semaphores (the docs says so) Traditionally binary
semaphores
are used to produce what is called a spin-lock. the psudeo-code goes
something
like this:


while (locked == 1) {;}
locked = 1;

critical section

locked = 0;

As I understand the method Paul was describing he wants to do something
like


if (locked == 1) sleepUntilWoken(thread);

criticalsection

wakeNextThread();

This would free up a lot of CPU time. So if SDL Mutexes are
spin-locks then this
method will free cpu time that would otherwise be wasted. Of course
this is dependent upon
how much of your code is inside critical sections. If your code spends
very little time inside them spin-locks are probably fine.

There is a third way to do this, similar to a spin-lock:

while (locked == 1) { switchToNextThread(); }
locked = 1;

critical section

locked = 0;

This would be much more efficient than a standard spin-lock, but not
quite as efficient as a second method (because of the overhead of
calling runNextThread() over and over)

				-fjr

hi`

“Frank J. Ramsay” wrote:

While I haven’t looked into the code, I know SDL Mutexes are implemented
with binary semaphores (the docs says so) Traditionally binary
semaphores
are used to produce what is called a spin-lock. the psudeo-code goes
something
like this:

SDL uses libpthread and pthread_mutex (at least on Linux) from what I
read from the source.

From pthread_mutex_init manpage

   A  mutex  has  two possible states: unlocked (not owned by
   any thread), and locked (owned by one thread). A mutex can
   never  be owned by two different threads simultaneously. A
   thread attempting to lock a mutex that is  already  locked
   by  another  thread  is  suspended until the owning thread
   unlocks the mutex first.

So I guess this means it is not wasting CPU time. Anyone knowing for
sure?–
Daniel Vogel

666 @ http://grafzahl.de

So I guess this means it is not wasting CPU time. Anyone knowing for
sure?

Okay, let me first start off with an explaination of the difference
between mutexes and condition variables.

A mutex can be locked by any thread and only unlocked by the thread that
locked it. In other words, if thread A locks a mutex and thread B tries
to lock the mutex, thread B will wait until thread A unlocks it.

A condition variable can be thought of as a mutex that is always locked.
When threads A and B come along and wait on the condition, they are
waiting for some other thread to unlock the condition variable. Thread C
comes along and unlocks it (once, in this example) so either thread A or
thread B can get the lock. As soon as, say, thread A is restarted the
condition is immediately relocked until something else (either thread A or
thread C) unlocks it again so thread B can run.

Now, in both paradigms the thread that is “waiting” consumes little/no CPU
time. Using POSIX threads this is the very definition. (On Linux, the
thread uses sigsuspend() until something wakens it.) Using a semaphore
the thread just waits until the operation succeeds. In Win32, the
WaitForSingleObject() function is called with an INFINITE timeout.

Ergo, threads waiting on both mutexes and condition variables consume
little/no CPU time while waiting. SDL does not use spinlocks as far as I
can see for non-POSIX threads handling. The semaphore code to lock a
mutex reads…

tryagain:
        if ( semop(mutex->id, op_lock, 2) < 0 ) {
                if ( errno == EINTR ) {
                        goto tryagain;
                }
                ...
        }

which only “spins” if the semop() function is interrupted by a signal.

I hope this answers everyone’s questions. :slight_smile:

Paul Braman
@Paul_BramanOn Sat, 13 Nov 1999, Daniel Vogel wrote: