[fpc-devel] Multithreading wait for

Vinzent Höfler JeLlyFish.software at gmx.net
Wed Dec 3 19:41:12 CET 2008


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.

> 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.

> 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.


Vinzent.



More information about the fpc-devel mailing list