[fpc-devel] Multithreading wait for

Mattias Gaertner nc-gaertnma at netcologne.de
Wed Dec 3 20:06:00 CET 2008


On Wed, 03 Dec 2008 19:41:12 +0100
Vinzent Höfler <JeLlyFish.software at gmx.net> wrote:

> Mattias Gärtner wrote:
> 
> > The situation:
> > There are m threads working in parallel on n chunks of work (n>=m).
> > The n chunks are indexed 0..n-1.
> > Sometimes one thread needs the result of some of the lower indexed
> > chunks. For example the chunk number 5 needs chunks 0..2.
> > So I have a function WaitForIndex(LowerIndex: integer) which should
> > wait until all chunks with less or equal to LowerIndex have
> > finished.
> > 
> > My current approach is this:
> > EnterCriticalSection (try..finally)
> > Check if all lower chunks have finished, if yes then exit
> > LeaveCriticalSection
> > RTLeventWaitFor(AnEventOfTheCurrentThread);
> 
> Why don't you do it the other way around?
> 
> wait_loop:
> 
> RTLEventWaitFor (SomeChunkHasFinishedEvent);
> // EnterCriticalSection;
> State of chunks changed ->
>    so check if all lower parts are ready, if yes then exit
> // LeaveCriticalSection;
> 
> goto wait_loop;
> 
> This way, the loop only gets awakened once something changed, you
> check the state (in an atomic way, if at all necessary) and go back.
> In case another event occured between the RTLEventWaitFor and 
> EnterCriticalSection it will go through a second time immediately.

If I understand RTLEventWaitFor correct, then it waits until another
thread calls RTLeventSetEvent.
So I must check *before* calling RTLEventWaitFor, that some other thread
is running, must I not?

It's a pool of threads.
 
> > The problem is the gap between LeaveCriticalSection and
> > RTLeventWaitFor. During this time the other threads may finish. So
> > there is no one left to wake up the waiting thread.
> 
> So your asking the wrong question. You don't want an efficient wait 
> loop, you want a wait loop free from race conditions.

:)
I know how to do a race condition free loop inefficiently using a spin
lock. My question is, if it can be done race condition free and
efficiently, to allow switching thousands of times a second without busy waiting.

 
> > Moving the RTLeventWaitFor into the CritialSection creates a
> > deadlock. I can use the timeout of RTLeventWaitFor and check in
> > intervals, but criticalsections and low response times don't fit
> > together.
> 
> Well, depending on what your checks do, you may not even need the 
> critical section if you reverse the logic. Either all checked threads 
> are finished or they aren't. If the state changed during the check,
> the check code will be invoked immediately, because the event will
> already be signalled again.

The critical section is needed, because after a thread finished some
work it starts some other work.

Mattias



More information about the fpc-devel mailing list