dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and to


From: Klaus Treichel
Subject: [dotgnu-pnet-commits] [SCM] DotGNU Portable.NET engine, compilers and tools (pnet) branch, master, updated. a2eb1ba0e8aa3b258dcf48e580f4b7e9f7fdc225
Date: Sat, 30 Jan 2010 10:29:05 +0000

This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "DotGNU Portable.NET engine, compilers and tools (pnet)".

The branch, master has been updated
       via  a2eb1ba0e8aa3b258dcf48e580f4b7e9f7fdc225 (commit)
      from  c3ac178896b2603e34654237bc0bfdb9b7b4c9e3 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://git.savannah.gnu.org/cgit/pnet.git/commit/?id=a2eb1ba0e8aa3b258dcf48e580f4b7e9f7fdc225

commit a2eb1ba0e8aa3b258dcf48e580f4b7e9f7fdc225
Author: Klaus Treichel <address@hidden>
Date:   Sat Jan 30 11:28:37 2010 +0100

    Add a condition variable based interruptible lock implementation for
    pthread based systems.
    Change _ILMonitorCreate so that the returned monitor is already owned by
    the calling thread.

diff --git a/ChangeLog b/ChangeLog
index df81bf5..5045765 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,49 @@
+2010-01-30  Klaus Treichel  <address@hidden>
+
+       * support/monitor.c (_ILMonitorInit): Initialize a monitor so that it's
+       initially owned by the calling thread.
+       (ILMonitorDestroy): Adjust the call to _ILMonitorDestroy to the new
+       macro definitions.
+       (_ILMonitorPoolAllocMonitor): Install the new monitor (now owned by the
+       current thread) at the given monitor location now.
+       (ILMonitorTimedTryEnter): Handle the case when there is no monitor
+       attached to the given location completely in _ILMonitorPoolAllocMonitor
+       now.
+       
+       * support/no_defs.h (_ILMonitorCreate, _ILMonitorDestroy): Change macros
+       so that the return value is an additional argument.
+
+       * support/pt_defs.h (_ILMonitorCreate, _ILMonitorDestroy): Change macros
+       so that the return value is an additional argument.
+       Add checks if semaphore or condition variable based locks should be 
used.
+       Add definitions for condition variable based interruptible locks.
+
+       * support/pt_defs.c: (SemWaitInterruptible, SemTimedWaitInterruptible,
+       SemWaitUninterruptible): Rename to LockWaitInterruptible,
+       LockTimedWaitInterruptible and LockWaitUninterruptible.
+       (LockSignal, LockSignalCount, LockTrywait): Add functions for semaphore
+       based interruptible locks.
+       (LockSignal, LockSignalCount, LockTrywait, LockWaitInterruptible,
+       LockTimedWaitInterruptible, LockWaitUninterruptible): Add 
implementations
+       for condition variable based interruptible locks.
+       (_ILThreadInterrupt): Add thread interrupt for condition variable based
+       interruptible locks.
+       (_ILMonitorExit): Call LockSignal now.
+       (_ILMonitorTimedTryEnter): Call LockTryWait now if timeout is 0.
+       Pass a timespec now to LockTimedWaitInterruptible instead of the number
+       of milliseconds.
+       (_ILMonitorPulse): Call LockSignal now.
+       (_ILMonitorPulseAll): Call LockSignalCount now.
+
+       * support/w32_defs.h (_ILCondMutexCreateOwned): Add macro.
+       (_ILMonitorCreate, _ILMonitorDestroy): Change macros so that the return
+       value is an additional argument.
+       (_ILMonitorCreate): Change so that the monitor is initially owned by the
+       calling thread.
+
+       * tests/test_thread.c: Adjust the primitive monitor tests to the changed
+       semantics of a new created monitor.
+
 2010-01-10  Klaus Treichel  <address@hidden>
 
        * support/pt_defs.h: Disable longjmp out of signal handler for NetBSD.
diff --git a/support/monitor.c b/support/monitor.c
index c53d188..e6595c1 100755
--- a/support/monitor.c
+++ b/support/monitor.c
@@ -1,7 +1,7 @@
 /*
  * monitor.c - Syncronization Monitor routines.
  *
- * Copyright (C) 2009  Southern Storm Software, Pty Ltd.
+ * Copyright (C) 2009, 2010  Southern Storm Software, Pty Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -64,22 +64,27 @@ struct _tagILMonitorPool
  */
 static _ILMonitorPool _MonitorPool;
 
-static void ILMonitorInit(ILMonitor *monitor)
+static int ILMonitorInit(ILMonitor *monitor, ILThread *thread)
 {
+       int result;
+
        monitor->next = 0;
-       monitor->owner = 0;
-       monitor->enterCount = 0;
-       monitor->users = 0;
-       _ILMonitorCreate(&(monitor->monitor));
+       monitor->owner = thread;
+       monitor->enterCount = 1;
+       monitor->users = 1;
+       _ILMonitorCreate(&(monitor->monitor), result);
+       return result;
 }
 
 static void ILMonitorDestroy(ILMonitor *monitor)
 {
+       int result;
+
        monitor->next = 0;
        monitor->owner = 0;
        monitor->enterCount = 0;
        monitor->users = 0;
-       _ILMonitorDestroy(&(monitor->monitor));
+       _ILMonitorDestroy(&(monitor->monitor), result);
 }
 
 static void DestroyMonitorList(ILMonitor *monitor)
@@ -151,33 +156,64 @@ static void _ILMonitorPoolDestroy(void)
 
 /*
  * Get a new monitor from the monitor pool.
+ * The thread parameter *MUST* be the current thread. 
+ * The monitor is owned by the current if the function returns success.
  * This function must be called with the monitorpool lock held.
  */
-static ILMonitor *_ILMonitorPoolAllocMonitor(void)
+static int _ILMonitorPoolAllocMonitor(ILThread *thread, void **monitorLocation)
 {
        ILMonitor *monitor;
+       int result;
 
        if(_MonitorPool.freeList)
        {
                /* We have a monitor on the freelist so reuse this one */
                monitor = _MonitorPool.freeList;
                _MonitorPool.freeList = monitor->next;
-               /* And add the monitor to the used list */
-               monitor->next = _MonitorPool.usedList;
-               _MonitorPool.usedList = monitor;
+               if((result = _ILMonitorTryEnter(&(monitor->monitor))) == 
IL_THREAD_OK)
+               {
+                       /* Initialize the monitor state */
+                       monitor->owner = thread;
+                       monitor->enterCount = 1;
+                       monitor->users = 1;
+                       /* Add the monitor to the used list */
+                       monitor->next = _MonitorPool.usedList;
+                       _MonitorPool.usedList = monitor;
+                       /* Store the monitor at the monitor location given */
+                       ILInterlockedStoreP(monitorLocation, monitor);
+               }
+               else
+               {
+                       /* Move this monitor back to the freelist */
+                       monitor->next = _MonitorPool.freeList;
+                       _MonitorPool.freeList = monitor;
+               }
+               return result;
        }
        else
        {
                monitor = ILMemPoolAllocItem(&(_MonitorPool.pool));
                if(monitor)
                {
-                       ILMonitorInit(monitor);
-                       /* And add the monitor to the used list */
-                       monitor->next = _MonitorPool.usedList;
-                       _MonitorPool.usedList = monitor;
+                       if((result = ILMonitorInit(monitor, thread)) == 
IL_THREAD_OK)
+                       {
+                               /* Add the monitor to the used list */
+                               monitor->next = _MonitorPool.usedList;
+                               _MonitorPool.usedList = monitor;
+                               /* Store the monitor at the monitor location 
given */
+                               ILInterlockedStoreP(monitorLocation, monitor);
+                       }
+                       else
+                       {
+                               /* Move this monitor to the freelist */
+                               monitor->next = _MonitorPool.freeList;
+                               _MonitorPool.freeList = monitor;
+                       }
+                       return result;
                }
+               return IL_THREAD_ERR_OUTOFMEMORY;
        }
-       return monitor;
+       return IL_THREAD_ERR_UNKNOWN;
 }
 
 /*
@@ -298,41 +334,10 @@ int ILMonitorTimedTryEnter(void **monitorLocation, 
ILUInt32 ms)
                if(monitor == 0)
                {
                        /* We have to allocate a new monitor */
-                       monitor = _ILMonitorPoolAllocMonitor();
-                       if(!monitor)
-                       {
-                               /* Unlock the monitor system */
-                               _ILCriticalSectionLeave(&(_MonitorPool.lock));
-                               return IL_THREAD_ERR_OUTOFMEMORY;
-                       }
-
-                       /* Set me as monitor user */
-                       monitor->users = 1;
-
-                       /*
-                        * We can acquire the monitor in the lock here because 
we are
-                        * sure that it's not owned by someone else.
-                        */
-                       result = _ILMonitorTryEnter(&(monitor->monitor));
-
-                       if(result == IL_THREAD_OK)
-                       {
-                               /* Set me as owner of the monitor */
-                               monitor->owner = thread;
-                               /* And initialize my enter count to 1 */
-                               monitor->enterCount = 1;
-
-                               /* Store the monitor at the location given */
-                               ILInterlockedStoreP(monitorLocation, monitor);
-                       }
-                       else
-                       {
-                               _ILMonitorPoolMoveToFreeList(&_MonitorPool, 
monitor);
-                               result = IL_THREAD_ERR_UNKNOWN;
-                       }
+                       result = _ILMonitorPoolAllocMonitor(thread, 
monitorLocation);
                        /* Unlock the monitor system */
                        _ILCriticalSectionLeave(&(_MonitorPool.lock));
-                       
+
                        return result;
                }
                if(monitor->owner == 0)
diff --git a/support/no_defs.h b/support/no_defs.h
index 6cc5755..686d1b6 100755
--- a/support/no_defs.h
+++ b/support/no_defs.h
@@ -1,7 +1,7 @@
 /*
  * no_defs.h - Thread definitions for systems without thread support.
  *
- * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
+ * Copyright (C) 2002, 2009, 2010  Southern Storm Software, Pty Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -134,8 +134,8 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms);
 /*
  * Primitive monitor operations.
  */
-#define        _ILMonitorCreate(mon)                           IL_THREAD_OK
-#define        _ILMonitorDestroy(mon)                          IL_THREAD_OK
+#define        _ILMonitorCreate(mon, result)           do { (result) = 
IL_THREAD_OK; } while(0)
+#define        _ILMonitorDestroy(mon, result)          do { (result) = 
IL_THREAD_OK; } while(0)
 #define        _ILMonitorPulse(mon)                            IL_THREAD_OK
 #define        _ILMonitorPulseAll(mon)                         IL_THREAD_OK
 #define        _ILMonitorTimedTryEnter(mon, ms)        IL_THREAD_OK
diff --git a/support/pt_defs.c b/support/pt_defs.c
index 6123a13..ce2d4fc 100755
--- a/support/pt_defs.c
+++ b/support/pt_defs.c
@@ -1,7 +1,7 @@
 /*
  * pt_defs.c - Thread definitions for using pthreads.
  *
- * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
+ * Copyright (C) 2002, 2009, 2010  Southern Storm Software, Pty Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -57,12 +57,6 @@ extern       "C" {
  */
 
 /*
- * Special flag in the private threadstate to indicate that the interrupt
- * should be noticed but no interrupt should occure.
- */
-#define IL_TS_UNINTERRUPTIBLE 0x1000
-
-/*
  * This macro checks if an interrupt orrured after enabling the
  * IL_SIG_INTERRUPT signal and sets __result in this case without
  * entering the code that has to be executed.
@@ -74,6 +68,12 @@ extern       "C" {
  * flag too.
  */
 #ifdef _IL_PT_INTERRUPT_JMP
+/*
+ * Special flag in the private threadstate to indicate that the interrupt
+ * should be noticed in the signal handler but the longjmp should not be taken.
+ */
+#define IL_TS_UNINTERRUPTIBLE 0x1000
+
 #define IL_START_INTERRUPTIBLE(__result) \
                { \
                        ILThread *__myThread; \
@@ -182,10 +182,10 @@ extern    "C" {
                        __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv)); \
                        if((__threadState & IL_TS_INTERRUPTED) != 0) \
                        { \
+                               __threadState &= ~IL_TS_INTERRUPTED; \
+                               
ILInterlockedStoreU2(&(__myThread->state.split.priv), __threadState); \
                                __result = IL_THREAD_ERR_INTERRUPT; \
                        } \
-                       __threadState &= ~(IL_TS_UNINTERRUPTIBLE | 
IL_TS_INTERRUPTED); \
-                       ILInterlockedStoreU2(&(__myThread->state.split.priv), 
__threadState); \
                }
 
 #endif /* !_IL_PT_INTERRUPT_JMP */
@@ -395,17 +395,49 @@ int sem_timedwait(sem_t *sem,
 }
 #endif /* !HAVE_SEM_TIMEDWAIT */
 
+#ifdef _IL_PT_LOCK_SEM
+static int LockSignal(_ILLock *lock)
+{
+       return (sem_post(&(lock)->_sem) == 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN);
+}
+
+static int LockSignalCount(_ILLock *lock, int count)
+{
+       while(count > 0)
+       {
+               sem_post(&(lock)->_sem);
+               --count;
+       }
+       return IL_THREAD_OK;
+}
+
+static int LockTryWait(_ILLock *lock)
+{
+       int result;
+
+       result = sem_trywait(&(lock->_sem));
+       if(result == -1)
+       {
+               if(errno == EAGAIN)
+               {
+                       return IL_THREAD_BUSY;
+               }
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       return IL_THREAD_OK;
+}
+
 /*
  * Interruptible wait on a semaphore.
  */
-static int SemWaitInterruptible(sem_t *sem)
+static int LockWaitInterruptible(_ILLock *lock)
 {
        int result;
 
        IL_START_INTERRUPTIBLE(result)
        do
        {
-               result = sem_wait(sem);
+               result = sem_wait(&(lock->_sem));
                if(result == 0)
                {
                        break;
@@ -433,24 +465,14 @@ static int SemWaitInterruptible(sem_t *sem)
 /*
  * Interruptible timed wait on a semaphore.
  */
-static int SemTimedWaitInterruptible(sem_t *sem, ILUInt32 ms)
+static int LockTimedWaitInterruptible(_ILLock *lock, const struct timespec *ts)
 {
-       struct timeval tv;
-       struct timespec ts;
        int result;
 
-       gettimeofday(&tv, 0);
-       ts.tv_sec = tv.tv_sec + (long)(ms / 1000);
-       ts.tv_nsec = (tv.tv_usec + (long)((ms % 1000) * 1000)) * 1000L;
-       if(ts.tv_nsec >= 1000000000L)
-       {
-               ++(ts.tv_sec);
-               ts.tv_nsec -= 1000000000L;
-       }
        IL_START_INTERRUPTIBLE(result)
        do
        {
-               result = sem_timedwait(sem, &ts);
+               result = sem_timedwait(&(lock->_sem), ts);
                if(result == 0)
                {
                        break;
@@ -480,14 +502,14 @@ static int SemTimedWaitInterruptible(sem_t *sem, ILUInt32 
ms)
        return result;
 }
 
-static int SemWaitUninterruptible(sem_t *sem)
+static int LockWaitUninterruptible(_ILLock *lock)
 {
        int result = IL_THREAD_OK;
 
        IL_START_UNINTERRUPTIBLE()
        do
        {
-               if(sem_wait(sem) == 0)
+               if(sem_wait(&(lock->_sem)) == 0)
                {
                        break;
                }
@@ -505,6 +527,408 @@ static int SemWaitUninterruptible(sem_t *sem)
        IL_END_UNINTERRUPTIBLE(result)
        return result;
 }
+#elif defined(_IL_PT_LOCK_COND)
+static int LockSignal(_ILLock *lock)
+{
+       _ILCondMutexLock(&(lock->_mutex));
+       lock->_value += 1;
+       if(lock->_value <= 0)
+       {
+               /* We have to release a waiter */
+               if(lock->_interrupted)
+               {
+                       /*
+                        * See if there is a thread woken up by an interrupt of 
an other
+                        * thread waiting on this lock
+                        */
+                       ILThread *thread;
+
+                       thread = lock->_waiters;
+                       while(thread)
+                       {
+                               ILUInt16 threadState;
+
+                               threadState = 
ILInterlockedLoadU2(&(thread->state.split.priv));
+                               if((threadState & IL_TS_NOTINTERRUPTED) != 0)
+                               {
+                                       /*
+                                        * Clear the not interrupted flag so 
that the thread
+                                        * will not continue waiting
+                                        */
+                                       threadState &= ~IL_TS_NOTINTERRUPTED;
+                                       
ILInterlockedStoreU2(&(thread->state.split.priv), threadState);
+                                       break;
+                               }
+                               thread = thread->nextWaiter;
+                       }
+                       if(!thread)
+                       {
+                               /*
+                                * There was no thread waiting with the 
IL_TS_NOTINTERRUPTED
+                                * flag set so clear the interropted flag of 
the lock.
+                                */
+                               lock->_interrupted = 0;
+                               /* And signal a thread to wake up */
+                               _ILCondVarSignal(&(lock->_cond));
+                       }
+               }
+               else
+               {
+                       _ILCondVarSignal(&(lock->_cond));
+               }
+       }
+       _ILCondMutexUnlock(&(lock->_mutex));
+
+       return IL_THREAD_OK;
+}
+
+static int LockSignalCount(_ILLock *lock, int count)
+{
+       _ILCondMutexLock(&(lock->_mutex));
+       lock->_value += count;
+       if(lock->_value > 0)
+       {
+               count -= lock->_value;
+       }
+       if(lock->_interrupted)
+       {
+               /*
+                * Process the threads woken up by interrupting an other thread
+                * and not being able to process the not interrupted first.
+                */
+               ILThread *thread;
+
+               thread = lock->_waiters;
+               while(thread && (count > 0))
+               {
+                       ILUInt16 threadState;
+
+                       threadState = 
ILInterlockedLoadU2(&(thread->state.split.priv));
+                       if((threadState & IL_TS_NOTINTERRUPTED) != 0)
+                       {
+                               /*
+                                * Clear the not interrupted flag so that the 
thread
+                                * will not continue waiting
+                                */
+                               threadState &= ~IL_TS_NOTINTERRUPTED;
+                               
ILInterlockedStoreU2(&(thread->state.split.priv), threadState);
+                               /* and decrement the number of waiters that 
should be awakened */
+                               --count;
+                               if(count <= 0)
+                               {
+                                       break;
+                               }
+                       }
+                       thread = thread->nextWaiter;
+               }
+               if(!thread)
+               {
+                       /*
+                        * There are no more threads waiting with the 
IL_TS_NOTINTERRUPTED
+                        * flag set so clear the interropted flag of the lock.
+                        */
+                       lock->_interrupted = 0;
+               }
+       }
+       if(lock->_value == 0)
+       {
+               /* Release all waiters */
+               _ILCondVarSignalAll(&(lock->_cond));
+       }
+       else
+       {
+               /* Release the number of waiters */
+               while(count > 0)
+               {
+                       _ILCondVarSignal(&(lock->_cond));
+                       --count;
+               }
+       }
+       _ILCondMutexUnlock(&(lock->_mutex));
+
+       return IL_THREAD_OK;
+}
+
+static int LockTryWait(_ILLock *lock)
+{
+       int result;
+
+       _ILCondMutexLock(&(lock->_mutex));
+       if(lock->_value > 0)
+       {
+               lock->_value -= 1;
+               result = IL_THREAD_OK;
+       }
+       else
+       {
+               result = IL_THREAD_BUSY;
+       }
+       _ILCondMutexUnlock(&(lock->_mutex));
+
+       return result;
+}
+
+/*
+ * Interruptible wait on a lock.
+ */
+static int LockWaitInterruptible(_ILLock *lock)
+{
+       int result = IL_THREAD_OK;
+
+       IL_START_INTERRUPTIBLE(result)
+       _ILCondMutexLock(&(lock->_mutex));
+       lock->_value -= 1;
+       if(lock->_value < 0)
+       {
+               /*
+                * Record this lock in the ILThread structure and add the 
thread to
+                * the waiters on this lock.
+                */
+               __myThread->lockWaitingOn = lock;
+               __myThread->nextWaiter = lock->_waiters;
+               lock->_waiters = __myThread;
+               do
+               {
+                       result = pthread_cond_wait(&(lock->_cond), 
&(lock->_mutex));
+                       if(result == 0)
+                       {
+                               /* Check if we are interrupted */
+                               __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv));
+                               if((__threadState & IL_TS_INTERRUPTED) != 0)
+                               {
+                                       /* Leave the wait loop  */
+                                       break;
+                               }
+                               else if((__threadState & IL_TS_NOTINTERRUPTED) 
!= 0)
+                               {
+                                       /* Clear the not interrupted flag */
+                                       __threadState &= ~IL_TS_NOTINTERRUPTED;
+                                       
ILInterlockedStoreU2(&(__myThread->state.split.priv), __threadState);
+                                       /* And continue waiting */
+                                       continue;
+                               }
+                               result = IL_THREAD_OK;
+                               break;
+                       }
+                       else
+                       {
+                               /* Remove me from the number of waiters */
+                               lock->_value += 1;
+                               result = IL_THREAD_ERR_UNKNOWN;
+                               break;
+                       }
+               } while(1);
+               /*
+                * Clear the  lock in the ILThread structure and remove the 
thread from
+                * the waiters on this lock.
+                */
+               __myThread->lockWaitingOn = 0;
+               if(lock->_waiters == __myThread)
+               {
+                       lock->_waiters = __myThread->nextWaiter;
+                       __myThread->nextWaiter = 0;
+               }
+               else
+               {
+                       ILThread *nextThread;
+                       
+                       nextThread = lock->_waiters;
+                       while(nextThread)
+                       {
+                               if(nextThread->nextWaiter == __myThread)
+                               {
+                                       nextThread->nextWaiter = 
__myThread->nextWaiter;
+                                       __myThread->nextWaiter = 0;
+                                       break;
+                               }
+                               nextThread = nextThread->nextWaiter;
+                       }
+               }
+       }
+       _ILCondMutexUnlock(&(lock->_mutex));
+       IL_END_INTERRUPTIBLE(result)
+       return result;
+}
+
+/*
+ * Interruptible timed wait on a lock.
+ */
+static int LockTimedWaitInterruptible(_ILLock *lock, const struct timespec *ts)
+{
+       int result = IL_THREAD_OK;
+
+       IL_START_INTERRUPTIBLE(result)
+       _ILCondMutexLock(&(lock->_mutex));
+       lock->_value -= 1;
+       if(lock->_value < 0)
+       {
+               /*
+                * Record this lock in the ILThread structure and add the 
thread to
+                * the waiters on this lock.
+                */
+               __myThread->lockWaitingOn = lock;
+               __myThread->nextWaiter = lock->_waiters;
+               lock->_waiters = __myThread;
+               do
+               {
+                       result = pthread_cond_timedwait(&(lock->_cond), 
&(lock->_mutex), ts);
+                       if(result == 0)
+                       {
+                               /* Check if we are interrupted */
+                               __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv));
+                               if((__threadState & IL_TS_INTERRUPTED) != 0)
+                               {
+                                       /* Leave the wait loop  */
+                                       break;
+                               }
+                               else if((__threadState & IL_TS_NOTINTERRUPTED) 
!= 0)
+                               {
+                                       /* Clear the not interrupted flag */
+                                       __threadState &= ~IL_TS_NOTINTERRUPTED;
+                                       
ILInterlockedStoreU2(&(__myThread->state.split.priv), __threadState);
+                                       /* And continue waiting */
+                                       continue;
+                               }
+                               result = IL_THREAD_OK;
+                               break;
+                       }
+                       else if(result == ETIMEDOUT)
+                       {
+                               /* Clear the not interrupted flag if present */
+                               __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv));
+                               if((__threadState & IL_TS_NOTINTERRUPTED) != 0)
+                               {
+                                       __threadState &= ~IL_TS_NOTINTERRUPTED;
+                                       
ILInterlockedStoreU2(&(__myThread->state.split.priv), __threadState);
+                               }
+                               lock->_value += 1;
+                               result = IL_THREAD_BUSY;
+                               break;
+                       }
+                       else
+                       {
+                               lock->_value += 1;
+                               result = IL_THREAD_ERR_UNKNOWN;
+                               break;
+                       }
+               } while(1);
+               /*
+                * Clear the  lock in the ILThread structure and remove the 
thread from
+                * the waiters on this lock.
+                */
+               __myThread->lockWaitingOn = 0;
+               if(lock->_waiters == __myThread)
+               {
+                       lock->_waiters = __myThread->nextWaiter;
+                       __myThread->nextWaiter = 0;
+               }
+               else
+               {
+                       ILThread *nextThread;
+                       
+                       nextThread = lock->_waiters;
+                       while(nextThread)
+                       {
+                               if(nextThread->nextWaiter == __myThread)
+                               {
+                                       nextThread->nextWaiter = 
__myThread->nextWaiter;
+                                       __myThread->nextWaiter = 0;
+                                       break;
+                               }
+                               nextThread = nextThread->nextWaiter;
+                       }
+               }
+       }
+       _ILCondMutexUnlock(&(lock->_mutex));
+       IL_END_INTERRUPTIBLE(result)
+       return result;
+}
+
+static int LockWaitUninterruptible(_ILLock *lock)
+{
+       int result = IL_THREAD_OK;
+
+       IL_START_UNINTERRUPTIBLE()
+       _ILCondMutexLock(&(lock->_mutex));
+       lock->_value -= 1;
+       if(lock->_value < 0)
+       {
+               /*
+                * Record this lock in the ILThread structure and add the 
thread to
+                * the waiters on this lock.
+                */
+               __myThread->lockWaitingOn = lock;
+               __myThread->nextWaiter = lock->_waiters;
+               lock->_waiters = __myThread;
+               do
+               {
+                       if(pthread_cond_wait(&(lock->_cond), &(lock->_mutex)) 
== 0)
+                       {
+                               /* Check if we are interrupted */
+                               __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv));
+                               if((__threadState & IL_TS_INTERRUPTED) != 0)
+                               {
+                                       /* Clear the interrupted flag */
+                                       __threadState &= ~IL_TS_INTERRUPTED;
+                                       
ILInterlockedStoreU2(&(__myThread->state.split.priv), __threadState);
+                                       /* Readd me to the number of waiters. */
+                                       lock->_value -= 1;
+                                       /* Set the result to interrupted */
+                                       result = IL_THREAD_ERR_INTERRUPT;
+                                       /* and continue waiting */
+                                       continue;
+                               }
+                               else if((__threadState & IL_TS_NOTINTERRUPTED) 
!= 0)
+                               {
+                                       /* Clear the not interrupted flag */
+                                       __threadState &= ~IL_TS_NOTINTERRUPTED;
+                                       
ILInterlockedStoreU2(&(__myThread->state.split.priv), __threadState);
+                                       /* And continue waiting */
+                                       continue;
+                               }
+                               result = IL_THREAD_OK;
+                               break;
+                       }
+                       else
+                       {
+                               /* An unexpected error occured so bail out */
+                               lock->_value += 1;
+                               result = IL_THREAD_ERR_UNKNOWN;
+                               break;
+                       }
+               } while(1);
+               /*
+                * Clear the  lock in the ILThread structure and remove the 
thread from
+                * the waiters on this lock.
+                */
+               __myThread->lockWaitingOn = 0;
+               if(lock->_waiters == __myThread)
+               {
+                       lock->_waiters = __myThread->nextWaiter;
+                       __myThread->nextWaiter = 0;
+               }
+               else
+               {
+                       ILThread *nextThread;
+                       
+                       nextThread = lock->_waiters;
+                       while(nextThread)
+                       {
+                               if(nextThread->nextWaiter == __myThread)
+                               {
+                                       nextThread->nextWaiter = 
__myThread->nextWaiter;
+                                       __myThread->nextWaiter = 0;
+                                       break;
+                               }
+                               nextThread = nextThread->nextWaiter;
+                       }
+               }
+       }
+       _ILCondMutexUnlock(&(lock->_mutex));
+       IL_END_UNINTERRUPTIBLE(result)
+       return result;
+}
+#endif /* _IL_PT_LOCK_COND */
 
 /*
  * This function is only used for initializing an ILThread
@@ -666,10 +1090,98 @@ void _ILThreadInterrupt(ILThread *thread)
 {
        if(thread)
        {
+#ifdef _IL_PT_LOCK_COND
+               _ILLock *lock;
+               ILUInt16 threadState;
+
+               threadState = ILInterlockedLoadU2(&(thread->state.split.priv));
+               lock = (_ILLock *)ILInterlockedLoadP((void 
**)&(thread->lockWaitingOn));
+#endif /* _IL_PT_LOCK_COND */
                /*
                 * Send the interrupt request to the thread.
                 */
                pthread_kill(thread->handle, IL_SIG_INTERRUPT);
+#ifdef _IL_PT_LOCK_COND
+               if(lock != 0)
+               {
+                       /* Acquire the lock */
+                       _ILCondMutexLock(&(lock->_mutex));
+                       /* Recheck if the thread is still waiting on the same 
lock */
+                       if(lock == (_ILLock *)ILInterlockedLoadP((void 
**)&(thread->lockWaitingOn)))
+                       {
+                               /*
+                                * First check if the thread to be interrupted 
should be awakened
+                                * because of an other interrupt processing.
+                                */
+                               if((threadState & IL_TS_INTERRUPTED) == 0)
+                               {
+                                       /* Remove the thread from the number od 
waiters */
+                                       lock->_value += 1;
+
+                                       threadState |= IL_TS_INTERRUPTED;
+                                       if((threadState & IL_TS_NOTINTERRUPTED) 
!= 0)
+                                       {
+                                               threadState &= 
~IL_TS_NOTINTERRUPTED;
+                                               
ILInterlockedStoreU2(&(thread->state.split.priv), threadState);
+                                       }
+                                       else
+                                       {
+                                               /*
+                                                * Mark all other threads 
waiting on the lock as not
+                                                * interrupted so that they 
will continue waiting at
+                                                * their next wakeup.
+                                                */
+                                               ILThread *otherThread;
+                                               ILInt32 value;
+                                               int otherWaiter = 0;
+
+                                               /*
+                                                * Set the interrupted flag 
here so that we don't depend
+                                                * on the signal processing 
timing to set the flag.
+                                                */
+                                               
ILInterlockedStoreU2(&(thread->state.split.priv), threadState);
+
+                                               /*
+                                                * Process at most 
(-lock->_value) waiters.
+                                                */
+                                               value = lock->_value;
+                                               otherThread = lock->_waiters;
+                                               while(otherThread && (value < 
0))
+                                               {
+                                                       if(otherThread != 
thread)
+                                                       {
+                                                               threadState = 
ILInterlockedLoadU2(&(otherThread->state.split.priv));
+                                                               if((threadState 
& IL_TS_INTERRUPTED) == 0)
+                                                               {
+                                                                       
threadState |= IL_TS_NOTINTERRUPTED;
+                                                                       
ILInterlockedStoreU2(&(otherThread->state.split.priv), threadState);
+                                                                       /*
+                                                                        * Set 
the flag that there is an other thread waiting
+                                                                        * on 
the lock
+                                                                        */
+                                                                       
otherWaiter = 1;
+                                                               }
+                                                               ++value;
+                                                       }
+                                                       otherThread = 
otherThread->nextWaiter;
+                                               }
+                                               if(otherWaiter)
+                                               {
+                                                       /*
+                                                        * Mark the lock that 
there is interrupt processing on
+                                                        * the way
+                                                        */
+                                                       lock->_interrupted = 1;
+                                               }
+                                               /* Wake up all threads waiting 
on the lock */
+                                               
_ILCondVarSignalAll(&(lock->_cond));
+                                       }
+                               }
+                       }
+                       /* Release the lock */
+                       _ILCondMutexUnlock(&(lock->_mutex));
+               }
+#endif /* _IL_PT_LOCK_COND */
        }
 }
 
@@ -707,7 +1219,7 @@ int _ILThreadSleep(ILUInt32 ms)
 #ifndef _IL_PT_INTERRUPT_JMP
                                        /* Check and clear the interrupted flag 
*/
                                        __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv));
-                                       if((__threadState | IL_TS_INTERRUPTED) 
!= 0)
+                                       if((__threadState & IL_TS_INTERRUPTED) 
!= 0)
                                        {
                                                result = 
IL_THREAD_ERR_INTERRUPT;
                                                break;
@@ -1033,32 +1545,33 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms)
 
 int _ILMonitorExit(_ILMonitor *mon)
 {
-       int result;
-
-       if((result = sem_post(&(mon->_enterSem))) == 0)
-       {
-               return IL_THREAD_OK;
-       }
-       return IL_THREAD_ERR_UNKNOWN;
+       return LockSignal(&(mon->_enterLock));
 }
 
 int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms)
 {
        if(ms == 0)
        {
-               if(sem_trywait(&(mon->_enterSem)) == 0)
-               {
-                       return IL_THREAD_OK;
-               }
-               return errno == EAGAIN ? IL_THREAD_BUSY : IL_THREAD_ERR_UNKNOWN;
+               return LockTryWait(&(mon->_enterLock));
        }
        else if(ms == IL_MAX_UINT32)
        {
-               return SemWaitInterruptible(&(mon->_enterSem));
+               return LockWaitInterruptible(&(mon->_enterLock));
        }
        else if(ms <= IL_MAX_INT32)
        {
-               return SemTimedWaitInterruptible(&(mon->_enterSem), ms);
+               struct timeval tv;
+               struct timespec ts;
+
+               gettimeofday(&tv, 0);
+               ts.tv_sec = tv.tv_sec + (long)(ms / 1000);
+               ts.tv_nsec = (tv.tv_usec + (long)((ms % 1000) * 1000)) * 1000L;
+               if(ts.tv_nsec >= 1000000000L)
+               {
+                       ++(ts.tv_sec);
+                       ts.tv_nsec -= 1000000000L;
+               }
+               return LockTimedWaitInterruptible(&(mon->_enterLock), &ts);
        }
        else
        {
@@ -1078,9 +1591,10 @@ int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
                 * In this case we don't have to enter the waiting queue but 
simply
                 * release and reenter the ready state.
                 */
-               if((result = sem_post(&(mon->_enterSem))) != 0)
+               result = LockSignal(&(mon->_enterLock));
+               if(result != IL_THREAD_OK)
                {
-                       return IL_THREAD_ERR_UNKNOWN;
+                       return result;
                }
        }
        else if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
@@ -1093,7 +1607,8 @@ int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
                /*
                 * Release the ownership of the monitor.
                 */
-               if(sem_post(&(mon->_enterSem)) != 0)
+               result = LockSignal(&(mon->_enterLock));
+               if(result != IL_THREAD_OK)
                {
                        /*
                         * Leave the wait queue and return with error
@@ -1104,7 +1619,7 @@ int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
 
                if(ms == IL_MAX_UINT32)
                {
-                       result = SemWaitInterruptible(&(mon->_waitSem));
+                       result = LockWaitInterruptible(&(mon->_waitLock));
                        if(result)
                        {
                                /*
@@ -1116,7 +1631,18 @@ int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
                }
                else
                {
-                       result = SemTimedWaitInterruptible(&(mon->_waitSem), 
ms);
+                       struct timeval tv;
+                       struct timespec ts;
+
+                       gettimeofday(&tv, 0);
+                       ts.tv_sec = tv.tv_sec + (long)(ms / 1000);
+                       ts.tv_nsec = (tv.tv_usec + (long)((ms % 1000) * 1000)) 
* 1000L;
+                       if(ts.tv_nsec >= 1000000000L)
+                       {
+                               ++(ts.tv_sec);
+                               ts.tv_nsec -= 1000000000L;
+                       }
+                       result = LockTimedWaitInterruptible(&(mon->_waitLock), 
&ts);
                        if(result)
                        {
                                /*
@@ -1135,7 +1661,7 @@ int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
        /*
         * Now we have to regain the ownership of the monitor
         */
-       enterResult = SemWaitUninterruptible(&(mon->_enterSem));
+       enterResult = LockWaitUninterruptible(&(mon->_enterLock));
        if(result == IL_THREAD_OK)
        {
                result = enterResult;
@@ -1145,17 +1671,21 @@ int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
 
 int _ILMonitorPulse(_ILMonitor *mon)
 {
+       int result;
+
+       result = IL_THREAD_OK;
        if(mon)
        {
                ILInt32 waitValue;
-               
+
+               result = IL_THREAD_OK;
                waitValue = ILInterlockedLoadI4(&(mon->_waitValue));
                if(waitValue < 0)
                {
                        waitValue = 
ILInterlockedIncrementI4_Acquire(&(mon->_waitValue));
                        if(waitValue <= 0)
                        {
-                               sem_post(&(mon->_waitSem));
+                               result = LockSignal(&(mon->_waitLock));
                        }
                        else
                        {
@@ -1163,7 +1693,7 @@ int _ILMonitorPulse(_ILMonitor *mon)
                        }
                }
        }
-       return IL_THREAD_OK;
+       return result;
 }
 
 int _ILMonitorPulseAll(_ILMonitor *mon)
@@ -1180,11 +1710,7 @@ int _ILMonitorPulseAll(_ILMonitor *mon)
                        if(waitValue < 0)
                        {
                                /* Release the waiters */
-                               while(waitValue < 0)
-                               {
-                                       sem_post(&(mon->_waitSem));
-                                       ++waitValue;
-                               }
+                               LockSignalCount(&(mon->_waitLock), -waitValue);
                        }
                        else if(waitValue > 0)
                        {
diff --git a/support/pt_defs.h b/support/pt_defs.h
index 7d8592f..c50071b 100755
--- a/support/pt_defs.h
+++ b/support/pt_defs.h
@@ -1,7 +1,7 @@
 /*
  * pt_defs.h - Thread definitions for using pthreads.
  *
- * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
+ * Copyright (C) 2002, 2009, 2010  Southern Storm Software, Pty Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,6 +41,20 @@ extern       "C" {
 #endif
 
 /*
+ * This is a real thread package.
+ */
+#define        _ILThreadIsReal         1
+
+/*
+ * Define IL_USE_COND_LOCK if condition variable based locks should be used.
+ * They are used by default if sem_timedwait is not available.
+ * This has to be done if the semaphore implementation on the OS doesn't
+ * return with errno set to EINTR if the waiting thread was interrupted by
+ * a signal (like on various BSD implementations).
+ */
+/* #define IL_USE_COND_LOCK 1 */
+
+/*
  * Determine the minimum and maximum real-time signal numbers.
  */
 #if !defined(__SIGRTMIN) && defined(SIGRTMIN)
@@ -108,6 +122,21 @@ extern     "C" {
 #endif
 
 /*
+ * Get or set the thread object that is associated with "self".
+ */
+#if defined(USE_COMPILER_TLS)
+extern _THREAD_ ILThread *_myThread;
+#define        _ILThreadGetSelf()                      (_myThread)
+#define        _ILThreadSetSelf(object)        (_myThread = (object))
+#else
+extern pthread_key_t _ILThreadObjectKey;
+#define        _ILThreadGetSelf()      \
+                       ((ILThread *)(pthread_getspecific(_ILThreadObjectKey)))
+#define        _ILThreadSetSelf(object)        \
+                       (pthread_setspecific(_ILThreadObjectKey, (object)))
+#endif
+
+/*
  * Types that are needed elsewhere.
  */
 typedef pthread_mutex_t                _ILCriticalSection;
@@ -150,13 +179,62 @@ typedef pthread_mutex_t           _ILRWLock;
 #endif
 
 /*
- * pthread specific extensions for an ILThread
+ * Check which type of lock to use on this architecture
  */
+#if !defined(IL_USE_COND_LOCK) && defined(HAVE_SEM_TIMEDWAIT) && 
defined(_IL_PT_INTERRUPT_JMP)
+#define _IL_PT_LOCK_SEM 1
+#else
 #ifdef _IL_PT_INTERRUPT_JMP
+#undef _IL_PT_INTERRUPT_JMP
+#endif
+#define _IL_PT_LOCK_COND 1
+/*
+ * An additional flag in the private thread state part to indicate that the
+ * thread was woken up because of an interruption of an other thread waiting
+ * on the same lock.
+ * NOTE: We extend the modifiability of the private thread state part by
+ * foreign threads here if the following conditions are met:
+ * 1. The thread whose private thread state shall be modified must be waiting
+ *    on a lock. (-> the member lockWaitingOn is != 0).
+ * 2. The thread wanting to modify the private state of the other thread
+ *    *MUST* hold the lockWaitingOn lock.
+ */
+#define IL_TS_NOTINTERRUPTED   0x0800
+#endif
+
+/*
+ * Define the type of lock to use.
+ */
+#if defined(_IL_PT_LOCK_SEM)
+typedef struct
+{
+       _ILSemaphore            _sem;
+} _ILLock;
+#elif defined(_IL_PT_LOCK_COND)
+typedef struct
+{
+       _ILCondVar                      _cond;
+       _ILCondMutex            _mutex;
+       ILThread                   *_waiters;
+       ILInt32                         _value;
+       ILInt32                         _interrupted;
+} _ILLock;
+#else
+#error "No lock type defined for this architecture"
+#endif
+
+/*
+ * pthread specific extensions for an ILThread
+ */
+#if defined(_IL_PT_INTERRUPT_JMP)
 #define _IL_THREAD_EXT \
        sigjmp_buf                      interruptJmpBuf;
-
+#elif defined(_IL_PT_LOCK_COND)
+#define _IL_THREAD_EXT \
+       _ILLock                    *lockWaitingOn; \
+       ILThread                   *nextWaiter;
 #endif
+
 /*
  * Semaphore which allows to release multiple or all waiters.
  * The semantic for posix and windows semaphores is the same and the
@@ -179,16 +257,11 @@ typedef struct
 typedef struct
 {
        ILInt32                 _waitValue;
-       _ILSemaphore    _waitSem;
-       _ILSemaphore    _enterSem;
+       _ILLock                 _waitLock;
+       _ILLock                 _enterLock;
 } _ILMonitor;
 
 /*
- * This is a real thread package.
- */
-#define        _ILThreadIsReal         1
-
-/*
  * Determine if a thread corresponds to "self".
  */
 #define        _ILThreadIsSelf(thread) \
@@ -348,6 +421,8 @@ int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 
count);
                        (pthread_cond_destroy((cond)))
 #define        _ILCondVarSignal(cond)          \
                        (pthread_cond_signal((cond)))
+#define        _ILCondVarSignalAll(cond)               \
+                       (pthread_cond_broadcast((cond)))
 int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex *mutex, ILUInt32 ms);
 
 /*
@@ -370,29 +445,77 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms);
 #define _ILCountSemaphoreWait(sem)     _ILCountSemaphoreTimedWait((sem), 
IL_MAX_UINT32)
 #define _ILCountSemaphoreTryWait(sem)  _ILCountSemaphoreTimedWait((sem), 0)
 
+#if defined(_IL_PT_LOCK_SEM)
+#define _ILLockCreate(lock, result) \
+       do { \
+               (result) = (sem_init(&((lock)->_sem), 0, 0) == 0 ? IL_THREAD_OK 
: IL_THREAD_ERR_UNKNOWN); \
+       } while(0)
+#define _ILLockDestroy(lock, result) \
+       do { \
+               (result) = (sem_destroy(&((lock)->_sem)) == 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN); \
+       } while(0)
+#elif defined(_IL_PT_LOCK_COND)
+#define _ILLockCreate(lock, result) \
+       do { \
+               (lock)->_waiters = 0; \
+               (lock)->_value = 0; \
+               (lock)->_interrupted = 0; \
+               if(!_ILCondMutexCreate(&((lock)->_mutex))) \
+               { \
+                       if(!_ILCondVarCreate((&((lock)->_cond)))) \
+                       { \
+                               (result) = IL_THREAD_OK; \
+                       } \
+                       else \
+                       { \
+                               (result) = IL_THREAD_ERR_UNKNOWN; \
+                       } \
+               } \
+               else \
+               { \
+                       (result) = IL_THREAD_ERR_UNKNOWN; \
+               } \
+       } while(0)
+#define _ILLockDestroy(lock, result) \
+       do { \
+               if(!_ILCondMutexDestroy(&((lock)->_mutex))) \
+               { \
+                       if(!_ILCondVarDestroy((&((lock)->_cond)))) \
+                       { \
+                               (result) = IL_THREAD_OK; \
+                       } \
+                       else \
+                       { \
+                               (result) = IL_THREAD_ERR_UNKNOWN; \
+                       } \
+               } \
+               else \
+               { \
+                       (result) = IL_THREAD_ERR_UNKNOWN; \
+               } \
+       } while(0)
+#endif /* _IL_PT_LOCK_COND) */
+
 /*
  * Primitive monitor operations.
  */
-#define        _ILMonitorCreate(mon)   \
-               ({ \
-                       int __result; \
+#define        _ILMonitorCreate(mon, result) \
+               do { \
                        (mon)->_waitValue = 0; \
-                       __result = sem_init(&((mon)->_waitSem), 0, 0); \
-                       if(!__result) \
+                       _ILLockCreate(&((mon)->_waitLock), (result)); \
+                       if(!(result)) \
                        { \
-                               __result = sem_init(&((mon)->_enterSem), 0, 1); 
\
+                               _ILLockCreate(&((mon)->_enterLock), (result)); \
                        } \
-                       __result == 0 ? IL_THREAD_OK : IL_THREAD_ERR_UNKNOWN; \
-               })
-#define        _ILMonitorDestroy(mon)  \
-               ({ \
-                       int __result = _ILSemaphoreDestroy(&((mon)->_waitSem)); 
\
-                       if(!__result) \
+               } while(0)
+#define        _ILMonitorDestroy(mon, result) \
+               do { \
+                       _ILLockDestroy(&((mon)->_waitLock),(result)); \
+                       if(!(result)) \
                        { \
-                               __result = 
_ILSemaphoreDestroy(&((mon)->_enterSem)); \
+                               _ILLockDestroy(&((mon)->_enterLock), (result)); 
\
                        } \
-                       __result == 0 ? IL_THREAD_OK : IL_THREAD_ERR_UNKNOWN; \
-               })
+               } while(0)
 int _ILMonitorPulse(_ILMonitor *mon);
 int _ILMonitorPulseAll(_ILMonitor *mon);
 int    _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms);
@@ -403,21 +526,6 @@ int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms);
 #define _ILMonitorWait(mon) _ILMonitorTimedWait((mon), IL_MAX_UINT32)
 
 /*
- * Get or set the thread object that is associated with "self".
- */
-#if defined(USE_COMPILER_TLS)
-extern _THREAD_ ILThread *_myThread;
-#define        _ILThreadGetSelf()                      (_myThread)
-#define        _ILThreadSetSelf(object)        (_myThread = (object))
-#else
-extern pthread_key_t _ILThreadObjectKey;
-#define        _ILThreadGetSelf()      \
-                       ((ILThread *)(pthread_getspecific(_ILThreadObjectKey)))
-#define        _ILThreadSetSelf(object)        \
-                       (pthread_setspecific(_ILThreadObjectKey, (object)))
-#endif
-
-/*
  * Call a function "once".
  */
 #define        _ILCallOnce(func)       \
diff --git a/support/w32_defs.h b/support/w32_defs.h
index 11e89e7..05faaea 100755
--- a/support/w32_defs.h
+++ b/support/w32_defs.h
@@ -1,7 +1,7 @@
 /*
  * w32_defs.h - Thread definitions for using Win32 threads.
  *
- * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
+ * Copyright (C) 2002, 2009, 2010  Southern Storm Software, Pty Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -195,6 +195,11 @@ int _ILThreadSleep(ILUInt32 ms);
                                *(mutex) = CreateMutex(NULL, FALSE, NULL); \
                                *(mutex) != 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN; \
                        })
+#define        _ILCondMutexCreateOwned(mutex)  \
+                       ({ \
+                               *(mutex) = CreateMutex(NULL, TRUE, NULL); \
+                               *(mutex) != 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN; \
+                       })
 #define        _ILCondMutexDestroy(mutex)      _ILWaitHandleClose(*(mutex))
 #define        _ILCondMutexLockUnsafe(mutex)   _ILWaitHandleWait(*(mutex))
 #define        _ILCondMutexTryLockUnsafe(mutex)        
_ILWaitHandleTimedWait(*(mutex), 0)
@@ -280,29 +285,29 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms);
 /*
  * Primitive monitor operations.
  */
-#define        _ILMonitorCreate(mon)   \
-               ({ \
-                       int _result = 0; \
+#define        _ILMonitorCreate(mon, result)   \
+               do { \
                        (mon)->_waitValue = 0; \
-                       if((_result = _ILCondMutexCreate(&((mon)->_mutex))) == 
IL_THREAD_OK) \
+                       if(((result) = 
_ILCondMutexCreateOwned(&((mon)->_mutex))) == IL_THREAD_OK) \
                        { \
-                               _result = _ILSemaphoreCreate(&((mon)->_sem)); \
+                               (result) = _ILSemaphoreCreate(&((mon)->_sem)); \
                        } \
-                       _result == IL_THREAD_OK ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN; \
-               })
-#define        _ILMonitorDestroy(mon)  \
-               ({ \
-                       int _result = IL_THREAD_OK; \
-                       if(_ILSemaphoreDestroy(&((mon)->_sem)) != IL_THREAD_OK) 
\
+                       if((result) != IL_THREAD_OK) \
                        { \
-                               _result = IL_THREAD_ERR_UNKNOWN; \
+                               (result) = IL_THREAD_ERR_UNKNOWN; \
                        } \
-                       if(_ILCondMutexDestroy(&((mon)->_mutex)) != 
IL_THREAD_OK) \
+               } while(0)
+#define        _ILMonitorDestroy(mon, result)  \
+               do { \
+                       if(((result) = _ILSemaphoreDestroy(&((mon)->_sem))) == 
IL_THREAD_OK) \
                        { \
-                               _result = IL_THREAD_ERR_UNKNOWN; \
+                               (result) = 
_ILCondMutexDestroy(&((mon)->_mutex)); \
                        } \
-                       _result; \
-               })
+                       if((result) != IL_THREAD_OK) \
+                       { \
+                               (result) = IL_THREAD_ERR_UNKNOWN; \
+                       } \
+               } while(0)
 
 /*
  * Release one waiter from the waiting queue.
diff --git a/tests/test_thread.c b/tests/test_thread.c
index d6dc02a..9f0a479 100755
--- a/tests/test_thread.c
+++ b/tests/test_thread.c
@@ -1,7 +1,7 @@
 /*
  * test_thread.c - Test the thread routines in "support".
  *
- * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
+ * Copyright (C) 2002, 2009, 2010  Southern Storm Software, Pty Ltd.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -1775,43 +1775,45 @@ static void wait_monitor_suspend(void *arg)
 }
 
 /*
- * Test monitor creation.
+ * Test monitor create primitive.
  */
 static void primitive_monitor_create(void *arg)
 {
        /* We are using the primitive versions for now. */
        _ILMonitor mon;
-       if(_ILMonitorCreate(&mon))
+       int result;
+       
+       _ILMonitorCreate(&mon, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
-       _ILMonitorDestroy(&mon);
+       if(_ILMonitorExit(&mon))
+       {
+               ILUnitFailed("could not exit a monitor");
+       }
+       _ILMonitorDestroy(&mon, result);
 }
 
 /*
- * Test monitor enter.
+ * Test monitor enter primitive.
  */
 static void primitive_monitor_enter(void *arg)
 {
        int result = 0;
-
-       /* We are using the primitive versions for now. */
        _ILMonitor mon;
-       if(_ILMonitorCreate(&mon))
+
+       _ILMonitorCreate(&mon, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
-       if((result = _ILMonitorEnter(&mon)))
-       {
-               _ILMonitorDestroy(&mon);
-               ILUnitFailed("could not enter a monitor");
-       }
        if((result = _ILMonitorExit(&mon)))
        {
-               _ILMonitorDestroy(&mon);
+               _ILMonitorDestroy(&mon, result);
                ILUnitFailed("could not exit a monitor");
        }
-       _ILMonitorDestroy(&mon);
+       _ILMonitorDestroy(&mon, result);
 }
 
 static volatile int _result;
@@ -1833,7 +1835,8 @@ static void primitive_monitor_exit_unowned(void *arg)
        int result = 0;
        ILThread *thread;
 
-       if(_ILMonitorCreate(&_mon1))
+       _ILMonitorCreate(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
@@ -1842,16 +1845,10 @@ static void primitive_monitor_exit_unowned(void *arg)
        thread = ILThreadCreate(_primitive_monitor_exit_unowned, &_mon1);
        if(!thread)
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitOutOfMemory();
        }
 
-       if((result = _ILMonitorEnter(&_mon1)))
-       {
-               _ILMonitorDestroy(&_mon1);
-               ILUnitFailed("could not enter a monitor");
-       }
-
        /* Set the result to an invalid value. */
        _result = -1;
 
@@ -1867,7 +1864,7 @@ static void primitive_monitor_exit_unowned(void *arg)
        if(_result != IL_THREAD_ERR_SYNCLOCK)
        {
                _ILMonitorExit(&_mon1);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitFailMessage("exiting an unowned monitor returned the 
wrong result");
                ILUnitFailMessage("the Wrong result is %i", _result);
                if(_result == IL_THREAD_OK)
@@ -1879,10 +1876,10 @@ static void primitive_monitor_exit_unowned(void *arg)
 
        if((result = _ILMonitorExit(&_mon1)))
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitFailed("could not exit a monitor");
        }
-       _ILMonitorDestroy(&_mon1);
+       _ILMonitorDestroy(&_mon1, result);
 }
 #endif /* !IL_USE_PTHREADS */
 
@@ -1914,23 +1911,18 @@ static void primitive_monitor_enter1(void *arg)
        int result2 = 0;
 
        /* We are using the primitive versions for now. */
-       if(_ILMonitorCreate(&_mon1))
+       _ILMonitorCreate(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
 
-       if((result = _ILMonitorEnter(&_mon1)))
-       {
-               _ILMonitorDestroy(&_mon1);
-               ILUnitFailed("could not enter a monitor");
-       }
-
        /* Create the thread */
        thread = ILThreadCreate(_primitive_monitor_enter_locked, &_mon1);
        if(!thread)
        {
                _ILMonitorExit(&_mon1);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitOutOfMemory();
        }
 
@@ -1947,7 +1939,7 @@ static void primitive_monitor_enter1(void *arg)
 
        if((result = _ILMonitorExit(&_mon1)))
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILThreadDestroy(thread);
                ILUnitFailed("could not exit a monitor");
        }
@@ -1963,11 +1955,12 @@ static void primitive_monitor_enter1(void *arg)
 
        if(result1 != 1 || result2 != 2)
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitFailed("lock on monitor enter doesn't work");
        }
 
-       if((result = _ILMonitorDestroy(&_mon1)))
+       _ILMonitorDestroy(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not destroy a monitor");
        }
@@ -2010,23 +2003,18 @@ static void primitive_monitor_tryenter1(void *arg)
        int result1 = 0;
 
        /* We are using the primitive versions for now. */
-       if(_ILMonitorCreate(&_mon1))
+       _ILMonitorCreate(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
 
-       if((result = _ILMonitorEnter(&_mon1)))
-       {
-               _ILMonitorDestroy(&_mon1);
-               ILUnitFailed("could not enter a monitor");
-       }
-
        /* Create the thread */
        thread = ILThreadCreate(_primitive_monitor_tryenter_locked, &_mon1);
        if(!thread)
        {
                _ILMonitorExit(&_mon1);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitOutOfMemory();
        }
 
@@ -2043,7 +2031,7 @@ static void primitive_monitor_tryenter1(void *arg)
 
        if((result = _ILMonitorExit(&_mon1)))
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILThreadDestroy(thread);
                ILUnitFailed("could not exit a monitor");
        }
@@ -2053,12 +2041,13 @@ static void primitive_monitor_tryenter1(void *arg)
 
        if(result1 != 1)
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("tryenter on a locked monitor doesn't work");
        }
 
-       if((result = _ILMonitorDestroy(&_mon1)))
+       _ILMonitorDestroy(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not destroy a monitor");
        }
@@ -2071,7 +2060,8 @@ static void primitive_monitor_tryenter2(void *arg)
        int result1 = 0;
 
        /* We are using the primitive versions for now. */
-       if(_ILMonitorCreate(&_mon1))
+       _ILMonitorCreate(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
@@ -2081,10 +2071,17 @@ static void primitive_monitor_tryenter2(void *arg)
        if(!thread)
        {
                _ILMonitorExit(&_mon1);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitOutOfMemory();
        }
 
+       if((result = _ILMonitorExit(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1, result);
+               ILThreadDestroy(thread);
+               ILUnitFailed("could not exit a monitor");
+       }
+
        _result = -1;
 
        /* Start the thread, which should immediately try to enter the monitor. 
*/
@@ -2100,12 +2097,13 @@ static void primitive_monitor_tryenter2(void *arg)
 
        if(result1 != 0)
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("tryenter on a unlocked monitor doesn't work");
        }
 
-       if((result = _ILMonitorDestroy(&_mon1)))
+       _ILMonitorDestroy(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not destroy a monitor");
        }
@@ -2148,23 +2146,18 @@ static void primitive_monitor_timed_tryenter1(void *arg)
        int result1 = 0;
 
        /* We are using the primitive versions for now. */
-       if(_ILMonitorCreate(&_mon1))
+       _ILMonitorCreate(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
 
-       if((result = _ILMonitorEnter(&_mon1)))
-       {
-               _ILMonitorDestroy(&_mon1);
-               ILUnitFailed("could not enter a monitor");
-       }
-
        /* Create the thread */
        thread = ILThreadCreate(_primitive_monitor_timed_tryenter, &_mon1);
        if(!thread)
        {
                _ILMonitorExit(&_mon1);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitOutOfMemory();
        }
 
@@ -2183,19 +2176,20 @@ static void primitive_monitor_timed_tryenter1(void *arg)
 
        if((result = _ILMonitorExit(&_mon1)))
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILThreadDestroy(thread);
                ILUnitFailed("could not exit a monitor");
        }
 
        if(result1 != 1)
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("timed tryenter on a locked monitor with timeout 
doesn't work");
        }
 
-       if((result = _ILMonitorDestroy(&_mon1)))
+       _ILMonitorDestroy(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not destroy a monitor");
        }
@@ -2243,23 +2237,18 @@ static void primitive_monitor_wait1(void *arg)
        int result2 = 0;
 
        /* We are using the primitive versions for now. */
-       if(_ILMonitorCreate(&_mon1))
+       _ILMonitorCreate(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
 
-       if(_ILMonitorEnter(&_mon1))
-       {
-               _ILMonitorDestroy(&_mon1);
-               ILUnitFailed("could not enter a monitor");
-       }
-
        /* Create the thread */
        thread = ILThreadCreate(_primitive_monitor_wait1, &_mon1);
        if(!thread)
        {
                _ILMonitorExit(&_mon1);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitOutOfMemory();
        }
 
@@ -2278,7 +2267,7 @@ static void primitive_monitor_wait1(void *arg)
        {
                /* Clean up the thread object. */
                ILThreadDestroy(thread);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitFailed("wait on a monitor doesn't work");
        }
 
@@ -2293,18 +2282,19 @@ static void primitive_monitor_wait1(void *arg)
 
        if(result1 != 0)
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("tryenter on a locked monitor doesn't work");
        }
 
        if((result = _ILMonitorExit(&_mon1)))
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitFailed("could not exit a monitor");
        }
 
-       if((result = _ILMonitorDestroy(&_mon1)))
+       _ILMonitorDestroy(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not destroy a monitor");
        }
@@ -2379,23 +2369,18 @@ static void primitive_monitor_timed_wait1(void *arg)
        int result2 = 0;
 
        /* We are using the primitive versions for now. */
-       if(_ILMonitorCreate(&_mon1))
+       _ILMonitorCreate(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not create a monitor");
        }
 
-       if(_ILMonitorEnter(&_mon1))
-       {
-               _ILMonitorDestroy(&_mon1);
-               ILUnitFailed("could not enter a monitor");
-       }
-
        /* Create the thread */
        thread = ILThreadCreate(_primitive_monitor_timed_wait1, &_mon1);
        if(!thread)
        {
                _ILMonitorExit(&_mon1);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitOutOfMemory();
        }
 
@@ -2415,7 +2400,7 @@ static void primitive_monitor_timed_wait1(void *arg)
        {
                /* Clean up the thread object. */
                ILThreadDestroy(thread);
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result1);
                printf("Wrong result is %i\n", result);
                ILUnitFailed("timed wait on a monitor doesn't work");
        }
@@ -2431,18 +2416,19 @@ static void primitive_monitor_timed_wait1(void *arg)
 
        if(result1 != 0 || result2 != 3)
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("tryenter on a locked monitor doesn't work");
        }
 
        if((result = _ILMonitorExit(&_mon1)))
        {
-               _ILMonitorDestroy(&_mon1);
+               _ILMonitorDestroy(&_mon1, result);
                ILUnitFailed("could not exit a monitor");
        }
 
-       if((result = _ILMonitorDestroy(&_mon1)))
+       _ILMonitorDestroy(&_mon1, result);
+       if(result)
        {
                ILUnitFailed("could not destroy a monitor");
        }

-----------------------------------------------------------------------

Summary of changes:
 ChangeLog           |   46 ++++
 support/monitor.c   |  103 +++++----
 support/no_defs.h   |    6 +-
 support/pt_defs.c   |  634 ++++++++++++++++++++++++++++++++++++++++++++++-----
 support/pt_defs.h   |  188 ++++++++++++----
 support/w32_defs.h  |   39 ++--
 tests/test_thread.c |  160 ++++++-------
 7 files changed, 926 insertions(+), 250 deletions(-)


hooks/post-receive
-- 
DotGNU Portable.NET engine, compilers and tools (pnet)




reply via email to

[Prev in Thread] Current Thread [Next in Thread]