Hello All -

I have an update on timed mutex waits for mingw support for std::thread.

On Tue, Oct 12, 2010 at 10:50 PM, K. Frank <[email protected]> wrote:
> ...
> I have put together a first cut at mingw support for std::thread.
> ...
> One notable missing feature is timed waits on mutexes (because these are not
> supported by the windows critical sections that I am using as the underlying
> native mutex).
> ...

I've put together a trial implementation for timed waits on mutexes, i.e.,
for __gthread_mutex_timedlock, to support std::mutex.try_lock_for.  I'd like
to get a sanity check on the approach I've taken.

Quick summary of the issue:  The overall goal is to provide a native windows
implementation of std::thread for mingw, using, in particular, native windows
condition variables.  Windows condition variables only work with critical
sections (and slim reader/writer locks).  Therefore we have to use windows
critical sections for our implementation of mutexes.

However, windows critical sections do not offer a native timed wait (although
they do offer TryEnterCriticalSection), so we have to implement timed waits
ourselves.  That's the basic issue I am asking about.

One approach would be to use a polling scheme with TryEnterCriticalSection.
But polling is not really satisfactory (and is, in general, somewhat evil).

We need to use some sort of object for which windows supports timed waits.

The only reasonably simple scheme I can think of is to spawn a child thread
that waits -- potentially indefinitely -- on the critical section, and use
WaitForSingleObject to wait on the child thread with a timeout (which
windows does support).

Roughly speaking:

   wait_function(...) {
      EnterCriticalSection(...);
      LeaveCriticalSection(...);
   }

   __gthread_mutex_timedlock(...) {
      while (timeout_not_expired) {
         if (TryEnterCriticalSection(...))  return 0;
         child_thread = _beginthreadex (..., wait_function, ...);
         result = WaitForSingleObject (child_thread, remaining_time_to_timeout);
         CloseHandle (child_thread);
         if (result == WAIT_TIMEOUT)  return ETIMEDOUT;
         // else critical section has been released,
         // BUT another thread may have acquired it.
         // that's why TryEnterCriticalSection is wrapped in a while loop.
      }
      return ETIMEDOUT;
   }

If the critical section is free, this implementation is about as cheap as
it can be.  But if it is locked, we have the cost of creating a child thread,
and when the critical section is released we have to context-switch first to
the child thread, and then to the thread that called __gthread_mutex_timedlock.

(Windows condition variables do support timed waits, but I couldn't figure
out a way to implement a timed mutex using condition variables that didn't
include some sort of queue of waiting threads, basically building a mutex
implementation from scratch.)

This implementation seems to work properly with a basic test program, but
I haven't tested it extensively.

So, does this approach for implementing timed mutexes look sound?  Can you
think of better ways of doing it?  Simpler and/or more efficient?

Thanks for any thoughts on the timed mutex issue.


K. Frank

------------------------------------------------------------------------------
Download new Adobe(R) Flash(R) Builder(TM) 4
The new Adobe(R) Flex(R) 4 and Flash(R) Builder(TM) 4 (formerly 
Flex(R) Builder(TM)) enable the development of rich applications that run
across multiple browsers and platforms. Download your free trials today!
http://p.sf.net/sfu/adobe-dev2dev
_______________________________________________
Mingw-w64-public mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/mingw-w64-public

Reply via email to