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. f7416a42ef725fc90f38d742a227a52334a3ec4a
Date: Wed, 30 Dec 2009 13:09:46 +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  f7416a42ef725fc90f38d742a227a52334a3ec4a (commit)
      from  371e013c41bd33968e856a27f1963343eb886dfc (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=f7416a42ef725fc90f38d742a227a52334a3ec4a

commit f7416a42ef725fc90f38d742a227a52334a3ec4a
Author: Klaus Treichel <address@hidden>
Date:   Wed Dec 30 14:09:17 2009 +0100

    Add support for interruptible waits on the monitor.
    Add critical sections support (is identical with ILMutex by now).
    Enable the new monitor in the engine.
    Lots of optimizations.

diff --git a/ChangeLog b/ChangeLog
index a576d82..8b77bd2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,68 @@
+2009-12-30  Klaus Treichel  <address@hidden>
+
+       * configure.in: Add checks for the nanosleep and clock_nanosleep
+       functions.
+
+       * engine/engine.h: Add prototype for the _ILExecThreadHandleError
+       function.
+
+       * engine/lib_monitor.c: Use the new monitor implementation now.
+
+       * engine/lib_thread.c (_IL_Thread_InternalSleep): Use the new function
+       _ILExecThreadHandleError instead of _ILExecThreadHandleWaitResult for
+       handling errors.
+
+       * engine/thread.c (_ILExecThreadHandleError): Add new function.
+
+       * support/monitor.c: Rework the monitor implementation.
+
+       * support/no_defs.h, support/pt_defs.h, support/w32_defs.h: Add
+       definitions for the new _ILCriticalSection type.
+       (_ILThreadInterrupt, _ILThreadSleep): Add prototypes
+       (_ILMonitorTimedWait, _ILMonitorWait): Change prototypes
+
+       * support/pt_defs.h: Change the monitor to using two semaphores instead
+       of a condition variable and a mutex to be able to interrupt the waits 
via
+       calls to _ILThreadInterrupt.
+
+       * support/no_defs.c (_ILThreadInterrupt, _ILThreadSleep): Added
+
+       * support/pt_defs.c: Add support for interrupting waits.
+       (_ILThreadInterrupt, _ILThreadSleep): Added
+       Rework the primitive monitor with using semaphores.
+
+       * support/w32_defs.c: Add support for using compiler tls for the current
+       thread.
+       (_ILThreadInterrupt, _ILThreadSleep): Added
+       (_ILWaitHandleWaitInterruptible): Added to do an allertible wait on a
+        handle.
+       Rework the primitive monitor implementation.
+
+       * support/thr_defs.h: Replace _ILMutexes by _ILCriticalSections.
+       Split the threadstate in a private and public part.
+       Add the macros for critical sections.
+       (_ILThreadEnterWaitState, _ILThreadLeaveWaitState): Add prototypes.
+       Rework the ILMonitor definition.
+
+       * support/thread.c: Replace _ILMutexes by _ILCriticalSections.
+       Control destruction of the ILThread structure by a reference count.
+       (_ILThreadEnterWaitState, _ILThreadLeaveWaitState): Add
+       (ILThreadSpleep): Change to use the native _ILThreadSleep
+       implementations.
+       (ILThreadDestroy): Destroying a thread doesn't abort the thread to
+       destroy anymore.
+
+       * support/wait.c (_ILEnterWait, _ILLeaveWait): Redo
+
+       * support/wait_event.c, support/wait_mutex.c, support/wait_mutex.h:
+       Adjust to use critilal sections instead of mutexes and the splited
+       thread state.
+
+       * tests/test_thread.c: Adjust monitor tests to the new monitor
+       implementation.
+       Add tests for interrupting and aborting a thread while entering or
+       waiting on a monitor.
+
 2009-12-23  Klaus Treichel  <address@hidden>
 
        * engine/verify_except.c (OutputExceptiopnTable): Fix some whitespace
diff --git a/configure.in b/configure.in
index c784622..5572b81 100644
--- a/configure.in
+++ b/configure.in
@@ -660,8 +660,9 @@ AC_CHECK_FUNCS(get_current_dir_name dlopen strerror fcntl 
ftruncate)
 AC_CHECK_FUNCS(acos asin atan atan2 ceil cos cosh exp floor remainder)
 AC_CHECK_FUNCS(log log10 pow rint sin sinh sqrt tan tanh round trunc)
 AC_CHECK_FUNCS(wctomb wcrtomb mbtowc mbrtowc nl_langinfo setlocale)
-AC_CHECK_FUNCS(clock_gettime)
-AC_CHECK_FUNCS(usleep gethostbyname gethostbyaddr isatty getpwuid geteuid)
+AC_CHECK_FUNCS(clock_gettime clock_nanosleep)
+AC_CHECK_FUNCS(usleep nanosleep)
+AC_CHECK_FUNCS(gethostbyname gethostbyaddr isatty getpwuid geteuid)
 AC_CHECK_FUNCS(opendir readdir readdir_r closedir chdir access)
 AC_CHECK_FUNCS(cygwin_conv_to_win32_path snprintf rename utime)
 AC_CHECK_FUNCS(mkdir ioctl setsockopt getsockopt uname mkstemp mktemp)
diff --git a/engine/engine.h b/engine/engine.h
index 088bae8..8322cf7 100644
--- a/engine/engine.h
+++ b/engine/engine.h
@@ -1209,6 +1209,11 @@ int _ILExecThreadSelfAborting(ILExecThread *thread);
 int _ILExecThreadHandleWaitResult(ILExecThread *thread, int result);
 
 /*
+ * Throw the exception for the thread error code.
+ */
+void _ILExecThreadHandleError(ILExecThread *thread, int error);
+
+/*
  * Gets the state of the thread.
  */
 ILInt32 _ILExecThreadGetState(ILExecThread *thread, ILThread* supportThread);
diff --git a/engine/lib_monitor.c b/engine/lib_monitor.c
index c8b23ea..7c8aa0d 100644
--- a/engine/lib_monitor.c
+++ b/engine/lib_monitor.c
@@ -107,47 +107,6 @@ extern     "C" {
  */
 
 /*
- * Spins until the object is unmarked and the current thread can mark it.
- */
-static IL_INLINE ILLockWord _ILObjectLockWord_WaitAndMark(ILExecThread 
*thread, ILObject *obj)
-{
-       ILLockWord lockword;
-
-       for (;;)
-       {
-               lockword = GetObjectLockWord(thread, obj);
-
-               if ((CompareAndExchangeObjectLockWord(thread, obj, 
IL_LW_MARK(lockword),
-                       IL_LW_UNMARK(lockword)) == IL_LW_UNMARK(lockword)))
-               {
-                       return IL_LW_MARK(lockword);
-               }
-
-               ILThreadYield();
-       }
-}
-
-/*
- * Sets an object's lockword to 0.
- */
-#define _ILObjectLockWord_Unmark(thread, obj) \
-       SetObjectLockWord(thread, obj, IL_LW_UNMARK(GetObjectLockWord(thread, 
obj)));
-
-/*
- * Adds a monitor to the end of the thread's free monitor list.
- * If the free list grows too large, the monitor is abandoned
- * and left for the garbage collector.
- */
-#define _ILExecMonitorAppendToFreeList(thread, monitor) \
-       if (thread->freeMonitorCount < 32) \
-       {       \
-               monitor->waiters = 0; \
-               monitor->next = thread->freeMonitor;    \
-               thread->freeMonitor = monitor;  \
-               thread->freeMonitorCount++;     \
-       }
-
-/*
  * public static void Enter(Object obj);
  */
 void _IL_Monitor_Enter(ILExecThread *thread, ILObject *obj)
@@ -165,15 +124,12 @@ void _IL_Monitor_Enter(ILExecThread *thread, ILObject 
*obj)
 ILBool _IL_Monitor_InternalTryEnter(ILExecThread *thread,
                                                                        
ILObject *obj, ILInt32 timeout)
 {
-       int result;     
-       ILLockWord lockword;
-       ILExecMonitor *monitor, *next;
+       int result;
        
        /* Make sure the object isn't null */
-       if (obj == 0)
+       if(obj == 0)
        {
                ILExecThreadThrowArgNull(thread, "obj");
-
                return 0;
        }
 
@@ -181,131 +137,18 @@ ILBool _IL_Monitor_InternalTryEnter(ILExecThread *thread,
        if (timeout < -1)
        {
                ILExecThreadThrowArgRange(thread, "timeout", (const char *)0);
-
                return 0;
        }
 
-retry:
+       result = ILMonitorTimedTryEnter((void **)GetObjectLockWordPtr(thread, 
obj),
+                                                                       
timeout);
 
-       /* Get the lockword lock word */                
-       lockword = GetObjectLockWord(thread, obj);
-
-       if (lockword == 0)
+       if((result != IL_THREAD_OK) && (result != IL_THREAD_BUSY))
        {
-               /* There is no monitor installed for this object */
-
-               monitor = thread->freeMonitor;
-
-               if (monitor == NULL)
-               {
-                       monitor = _ILExecMonitorCreate();
-               }
-
-               next = monitor->next;
-
-               /* Try to install the new monitor. */
-               if (CompareAndExchangeObjectLockWord
-                       (
-                               thread,
-                               obj,
-                               IL_LW_MARK(monitor),
-                               lockword
-                       ) == lockword)
-               {
-                       result = ILWaitMutexFastEnter(thread->supportThread, 
monitor->waitMutex);
-
-                       if (result != 0)
-                       {
-                               /* Dissociate the monitor from the object */
-                               
-                               SetObjectLockWord(thread, obj, 0);
-
-                               /* If the monitor is new, add it to the free 
list */
-                               if (monitor != thread->freeMonitor)
-                               {
-                                       _ILExecMonitorAppendToFreeList(thread, 
monitor);
-                               }
-
-                               _ILExecThreadHandleWaitResult(thread, result);
-
-                               return 0;
-                       }
-
-                       /* If the monitor is from the free list, remove it from 
the free list */
-                       if (monitor == thread->freeMonitor)
-                       {
-                               thread->freeMonitorCount--;
-                               thread->freeMonitor = next;
-                       }
-
-                       /* Finally allow other threads to enter the monitor */
-                       _ILObjectLockWord_Unmark(thread, obj);
-
-                       return 1;
-               }
-               else
-               {
-                       /* Another thread managed to install a monitor first */
-
-                       /* If the monitor is new, add it to the free list */
-                       if (monitor != thread->freeMonitor)
-                       {
-                               _ILExecMonitorAppendToFreeList(thread, monitor);
-                       }
-
-                       goto retry;
-               }
+               _ILExecThreadHandleError(thread, result);
        }
-
-       /* Lock the object's lockword */
-       lockword = _ILObjectLockWord_WaitAndMark(thread, obj);
-
-       monitor = IL_LW_UNMARK(lockword);
-
-       /* We assume that _ILObjectLockWord_WaitAndMark flushed the CPU's cache
-          so that we can see the monitor */
-
-       if (monitor == 0)
-       {
-               /* Some other thread owned the monitor but has released it
-                  since we last called GetObjectLockWord */
-
-               _ILObjectLockWord_Unmark(thread, obj);
-
-               goto retry;
-       }
-
-       /* Incrementing waiters prevents other threads from disassociating 
-          the monitor with the object or using FastLeave */
-
-       monitor->waiters++;
-       
-       _ILObjectLockWord_Unmark(thread, obj);
-       
-       /* Here we try entering the monitor.  If we know that we own the
-          monitor then we can call ILWaitMutexFastEnter. */
        
-       if (ILWaitMutexThreadOwns(thread->supportThread, monitor->waitMutex))
-       {
-               result = ILWaitMutexFastEnter(thread->supportThread, 
monitor->waitMutex);
-       }
-       else
-       {               
-               result = ILWaitMonitorTryEnter(monitor->waitMutex, timeout);
-       }
-
-       _ILObjectLockWord_WaitAndMark(thread, obj);
-       --monitor->waiters;
-       _ILObjectLockWord_Unmark(thread, obj);
-
-       /* Failed or timed out somehow */
-       if (result != 0)
-       {
-               /* Handle ThreadAbort etc */            
-               _ILExecThreadHandleWaitResult(thread, result);
-       }
-
-       return result == 0;
+       return (result == IL_THREAD_OK);
 }
 
 /*
@@ -314,8 +157,6 @@ retry:
 void _IL_Monitor_Exit(ILExecThread *thread, ILObject *obj)
 {
        int result;
-       ILLockWord lockword;
-       ILExecMonitor *monitor;
 
        /* Make sure obj isn't null */
        if(obj == 0)
@@ -325,72 +166,11 @@ void _IL_Monitor_Exit(ILExecThread *thread, ILObject *obj)
                return;
        }
 
-       /* Make sure noone is allowed to change the object's monitor */
-       lockword = _ILObjectLockWord_WaitAndMark(thread, obj);
-
-       /* We assume that _ILObjectLockWord_WaitAndMark flushed the CPU's cache
-          so that we can see the monitor */
-       monitor = IL_LW_UNMARK(lockword);
+       result = ILMonitorExit((void **)GetObjectLockWordPtr(thread, obj));
 
-       /* Make sure the monitor is valid */
-       if (monitor == 0 || (monitor != 0 
-               && !ILWaitMutexThreadOwns(thread->supportThread, 
monitor->waitMutex)))
+       if(result != IL_THREAD_OK)
        {
-               /* Hmm.  Can't call Monitor.Exit before Monitor.Enter */
-
-               _ILObjectLockWord_Unmark(thread, obj);
-
-               ILExecThreadThrowSystem
-               (
-                       thread,
-                       "System.Threading.SynchronizationLockException",        
-                       "Exception_ThreadNeedsLock"
-               );
-
-               return;
-       }
-
-       /*
-        * If there are no waiters then we have exclusive access to the 
monitor.  This
-        * allows us to do a "FastRelease" and possibly return the monitor to 
the freelist.
-        */
-       if (monitor->waiters == 0)
-       {
-               result = ILWaitMutexFastRelease(thread->supportThread, 
monitor->waitMutex);
-               
-               if (result == IL_WAITMUTEX_RELEASE_STILL_OWNS)
-               {
-                       _ILObjectLockWord_Unmark(thread, obj);
-               }
-               else
-               {
-                       /* Monitor no longer owned.  Return it to the free list 
to
-                          make the next call to Monitor.Enter on this object 
fast */
-                       _ILExecMonitorAppendToFreeList(thread, monitor);
-
-                       SetObjectLockWord(thread, obj, 0);
-               }
-               
-               return;         
-       }
-       
-       _ILObjectLockWord_Unmark(thread, obj);
-
-       /*
-        * Another thread is waiting so try leaving the old fashioned way.
-        */
-       result = ILWaitMonitorLeave(monitor->waitMutex);
-
-       if (result < 0)
-       {
-               /* We *should* own the monitor.  This must be a bug in the 
engine. */
-               
-               ILExecThreadThrowSystem
-               (
-                       thread,                                 
-                       "System.ExecutionEngineException",
-                       "Exception_UnexpectedEngineState"
-               );
+               _ILExecThreadHandleError(thread, result);
        }
 }
 
@@ -401,92 +181,22 @@ ILBool _IL_Monitor_InternalWait(ILExecThread *thread,
                                                                ILObject *obj, 
ILInt32 timeout)
 {
        int result;
-       ILLockWord lockword;
-       ILExecMonitor *monitor;
 
        /* Make sure obj isn't null */
        if (obj == 0)
-       {               
+       {
                ILExecThreadThrowArgNull(thread, "obj");
-
                return 0;
        }
 
-       lockword = _ILObjectLockWord_WaitAndMark(thread, obj);
-       
-       monitor = IL_LW_UNMARK(lockword);
+       result = ILMonitorTimedWait((void **)GetObjectLockWordPtr(thread, obj), 
timeout);
 
-       if (monitor == 0 || (monitor != 0 
-               && !ILWaitMutexThreadOwns(thread->supportThread, 
monitor->waitMutex)))
+       if((result != IL_THREAD_OK) && (result != IL_THREAD_BUSY))
        {
-               _ILObjectLockWord_Unmark(thread, obj);
-
-               /* Object needs to own monitor */
-
-               ILExecThreadThrowSystem
-               (
-                       thread,
-                       "System.Threading.SynchronizationLockException",
-                       "Exception_ThreadNeedsLock"
-               );
-
-               return 0;
+               _ILExecThreadHandleError(thread, result);
        }
 
-       ++monitor->waiters;
-       
-       _ILObjectLockWord_Unmark(thread, obj);
-
-       /* If we get here then we know that no other thread can dissociate
-          the monitor from the object because we own the monitor! */
-
-       result = ILWaitMonitorWait(monitor->waitMutex, timeout);
-
-       _ILObjectLockWord_WaitAndMark(thread, obj);     
-       --monitor->waiters;     
-       _ILObjectLockWord_Unmark(thread, obj);
-
-       switch (result)
-       {
-       case 0:
-
-               /* We *should* own the monitor.  This must be a bug in the 
engine. */
-
-               ILExecThreadThrowSystem
-               (
-                       thread,
-                       "System.ExecutionEngineException",
-                       "Exception_UnexpectedEngineState"
-               );
-
-               return 0;
-
-       case IL_WAIT_FAILED:
-       case 1:
-
-               /* Success or wait failed */
-
-               /* Returning 1 because the lock is always regained */
-
-               return 1;
-
-       case IL_WAIT_TIMEOUT:
-
-               /* Return 0 to indicate that the thread competed and reacquired 
-                  the lock after it was woken and that it was woken because it 
-                  timed out waiting for a pulse rather than because it 
received 
-                  a pulse. */
-
-               return 0;
-
-       default:
-
-               /* Handle ThreadAbort etc */
-
-               _ILExecThreadHandleWaitResult(thread, result);
-
-               return 1;
-       }
+       return (result == IL_THREAD_OK);
 }
 
 /*
@@ -495,68 +205,18 @@ ILBool _IL_Monitor_InternalWait(ILExecThread *thread,
 void _IL_Monitor_Pulse(ILExecThread *thread, ILObject *obj)
 {
        int result;
-       ILExecMonitor * monitor;
 
        if(obj == 0)
        {
                ILExecThreadThrowArgNull(thread, "obj");
-
                return;
        }
 
-       _ILObjectLockWord_WaitAndMark(thread, obj);
-
-       monitor = GetObjectMonitor(thread, obj);
-
-       if (monitor == 0 || (monitor != 0 
-               && !ILWaitMutexThreadOwns(thread->supportThread, 
monitor->waitMutex)))
+       result = ILMonitorPulse((void **)GetObjectLockWordPtr(thread, obj));
+       
+       if(result != IL_THREAD_OK)
        {
-               /* Object needs to own monitor */
-
-               _ILObjectLockWord_Unmark(thread, obj);
-
-               ILExecThreadThrowSystem
-               (
-                       thread,
-                       "System.Threading.SynchronizationLockException",
-                       "Exception_ThreadNeedsLock"
-               );
-
-               return;
-       }
-
-       _ILObjectLockWord_Unmark(thread, obj);
-
-       result = ILWaitMonitorPulse(monitor->waitMutex);
-
-       switch (result)
-       {
-       case 0:
-
-               /* We *should* own the monitor.  This must be a bug in the 
engine. */
-
-               ILExecThreadThrowSystem
-               (
-                       thread,
-                       "System.ExecutionEngineException",
-                       "Exception_UnexpectedEngineState"
-               );
-
-               return;
-
-       case 1:
-
-               /* Successfully pulsed */
-
-               return;
-
-       default:
-
-               /* Handle ThreadAbort etc */
-
-               _ILExecThreadHandleWaitResult(thread, result);
-
-               return;
+               _ILExecThreadHandleError(thread, result);
        }
 }
 
@@ -565,69 +225,19 @@ void _IL_Monitor_Pulse(ILExecThread *thread, ILObject 
*obj)
  */
 void _IL_Monitor_PulseAll(ILExecThread *thread, ILObject *obj)
 {
-       int result;     
-       ILExecMonitor * monitor;
+       int result;
 
        if(obj == 0)
        {
                ILExecThreadThrowArgNull(thread, "obj");
-
                return;
        }
 
-       _ILObjectLockWord_WaitAndMark(thread, obj);
+       result = ILMonitorPulseAll((void **)GetObjectLockWordPtr(thread, obj));
 
-       monitor = GetObjectMonitor(thread, obj);
-
-       if (monitor == 0 || (monitor != 0 
-               && !ILWaitMutexThreadOwns(thread->supportThread, 
monitor->waitMutex)))
+       if(result != IL_THREAD_OK)
        {
-               /* Object needs to own monitor */
-
-               _ILObjectLockWord_Unmark(thread, obj);
-
-               ILExecThreadThrowSystem
-               (
-                       thread,
-                       "System.Threading.SynchronizationLockException",
-                       "Exception_ThreadNeedsLock"
-               );
-
-               return;
-       }
-
-       _ILObjectLockWord_Unmark(thread, obj);
-
-       result = ILWaitMonitorPulseAll(monitor->waitMutex);
-
-       switch (result)
-       { 
-       case 0:
-
-               /* We *should* own the monitor.  This must be a bug in the 
engine. */
-
-               ILExecThreadThrowSystem
-               (
-                       thread,
-                       "System.ExecutionEngineException",
-                       "Exception_UnexpectedEngineState"
-               );
-
-               return;
-
-       case 1:
-
-               /* Successfully pulsed */
-
-               return;
-
-       default:
-
-               /* Handle ThreadAbort etc */
-
-               _ILExecThreadHandleWaitResult(thread, result);
-
-               return;
+               _ILExecThreadHandleError(thread, result);
        }
 }
 
diff --git a/engine/lib_thread.c b/engine/lib_thread.c
index 0105b4d..dca1517 100644
--- a/engine/lib_thread.c
+++ b/engine/lib_thread.c
@@ -263,7 +263,7 @@ void _IL_Thread_FinalizeThread(ILExecThread *thread, 
ILObject *_this)
        {
                clrThread->privateData = 0;
 
-               ILThreadDestroy(supportThread);         
+               ILThreadDestroy(supportThread);
        }
 }
 
@@ -314,7 +314,7 @@ void _IL_Thread_SpinWait(ILExecThread *_thread, ILInt32 
iterations)
         */
 
        if(iterations > 0)
-       {               
+       {
                /*
                 * Can't use ILThreadSleep because it will catch interrupts
                 * and we don't want it to do that.
@@ -427,13 +427,16 @@ void _IL_Thread_ResetAbort(ILExecThread *thread)
  */
 void _IL_Thread_InternalSleep(ILExecThread *thread, ILInt32 timeout)
 {
+       int result;
+       
        if (timeout < -1)
        {
                ILExecThreadThrowSystem(thread,
                        "System.ArgumentOutOfRangeException", (const char *)0);
        }
        
-       _ILExecThreadHandleWaitResult(thread, ILThreadSleep((ILUInt32)timeout));
+       result = ILThreadSleep((ILUInt32)timeout);
+       _ILExecThreadHandleError(thread, result);
 }
 
 /*
diff --git a/engine/thread.c b/engine/thread.c
index 6dd7c6b..1dccca9 100644
--- a/engine/thread.c
+++ b/engine/thread.c
@@ -22,6 +22,7 @@
 
 #include "engine_private.h"
 #include "lib_defs.h"
+#include "thr_defs.h"
 #include "interrupt.h"
 #include "interlocked.h"
 
@@ -68,7 +69,7 @@ ILObject *ILExecThreadCurrentClrThread()
        
                /* Get the CLR thread class */
 
-               classInfo = ILExecThreadLookupClass(thread, 
"System.Threading.Thread");         
+               classInfo = ILExecThreadLookupClass(thread, 
"System.Threading.Thread");
 
                /* Allocate a new CLR thread object */
 
@@ -534,7 +535,7 @@ int _ILExecThreadHandleWaitResult(ILExecThread *thread, int 
result)
                break;
        case IL_WAIT_ABORTED:
                {
-                       _ILExecThreadSelfAborting(thread);                      
+                       _ILExecThreadSelfAborting(thread);
                }
                break;
        case IL_WAIT_FAILED:
@@ -552,6 +553,51 @@ int _ILExecThreadHandleWaitResult(ILExecThread *thread, 
int result)
 }
 
 /*
+ * Throw the exception for the thread error code.
+ */
+void _ILExecThreadHandleError(ILExecThread *thread, int error)
+{
+       switch(error)
+       {
+               case IL_THREAD_ERR_SYNCLOCK:
+               {
+                       ILExecThreadThrowSystem(thread,
+                                                                       
"System.Threading.SynchronizationLockException",
+                                                                       (const 
char *)0);
+               }
+               break;
+
+               case IL_THREAD_ERR_INTERRUPT:
+               {
+                       ILExecThreadThrowSystem(thread,
+                                                                       
"System.Threading.ThreadInterruptedException",
+                                                                       (const 
char *)0);
+               }
+               break;
+
+               case IL_THREAD_ERR_ABORTED:
+               {
+                       _ILExecThreadSelfAborting(thread);
+               }
+               break;
+
+               case IL_THREAD_ERR_OUTOFMEMORY:
+               {
+                       
+               }
+               break;
+               
+               case IL_THREAD_ERR_UNKNOWN:
+               {
+                       ILExecThreadThrowSystem(thread,
+                                                                       
"System.SystemException",
+                                                                       (const 
char *)0);
+               }
+               break;
+       }
+}
+
+/*
  * Join an ILExecProcess for normal execution.
  * The caller has to handle the thread safety and to make sure
  * that the process is not unloaded.
@@ -617,12 +663,12 @@ ILExecThread *_ILExecThreadCreate(ILExecProcess *process, 
int ignoreProcessState
        thread->freeMonitorCount = 0;
        thread->isFinalizerThread = 0;
        thread->method = 0;
-       thread->thrownException = 0;    
+       thread->thrownException = 0;
        thread->threadStaticSlots = 0;
        thread->threadStaticSlotsUsed = 0;
        thread->currentException = 0;
        thread->managedSafePointFlags = 0;
-       thread->runningManagedCode = 0; 
+       thread->runningManagedCode = 0;
        thread->threadAbortException = 0;
        thread->process = 0;
 
diff --git a/support/monitor.c b/support/monitor.c
old mode 100644
new mode 100755
index 96c2d4d..c53d188
--- a/support/monitor.c
+++ b/support/monitor.c
@@ -26,6 +26,9 @@
 #include <il_utils.h>
 #include "thr_defs.h"
 #include "interlocked.h"
+#ifdef IL_THREAD_DEBUG
+#include <stdio.h>
+#endif
 
 #ifdef __cplusplus
 extern "C" {
@@ -34,12 +37,33 @@ extern      "C" {
 struct _tagILMonitor
 {
        ILMonitor                  *next;               /* The next monitor in 
the list */
-       ILThread volatile  *owner;              /* The current owner of the 
monotor */
-       ILInt32                 enterCount;             /* The number of enters 
without corresponding leave by the owner */
+       ILThread * volatile     owner;          /* The current owner of the 
monotor */
+       ILInt32                         enterCount;     /* The number of enters 
without corresponding leave by the owner */
        ILUInt32                        users;          /* The number of 
threads using this monitor */
        _ILMonitor                      monitor;        /* The platform 
dependent monitor */
 };
 
+/*
+ * Pool used by the monitor.
+ */
+typedef struct _tagILMonitorPool _ILMonitorPool;
+struct _tagILMonitorPool
+{
+       _ILCriticalSection      lock;           /* critical section to 
synchronize the access to the pool */
+       ILMonitor                  *freeList;   /* List of unused monitors */
+       ILMonitor                  *usedList;   /* List of monitors in use */
+       ILMemPool                       pool;           /* Pool to allocate the 
monitors from */
+#ifdef IL_THREAD_DEBUG
+       ILUInt32                numReclaimed;   /* Number of reclaimed monitors 
*/
+       ILUInt32                numAbandoned;   /* Number of abandoned monitors 
*/
+#endif
+};
+
+/*
+ * The pool to hold all monitors used.
+ */
+static _ILMonitorPool _MonitorPool;
+
 static void ILMonitorInit(ILMonitor *monitor)
 {
        monitor->next = 0;
@@ -70,73 +94,138 @@ static void DestroyMonitorList(ILMonitor *monitor)
        }
 }
 
-void ILMonitorPoolInit(ILMonitorPool *pool)
+#ifdef IL_THREAD_DEBUG
+static int ListCount(ILMonitor *monitor)
 {
-       if(!pool)
+       int count;
+
+       count = 0;
+       while(monitor)
        {
-               return;
+               ++count;
+               monitor = monitor->next;
        }
-       ILMemPoolInitType(&(pool->pool), ILMonitor, 20);
-       pool->freeList = 0;
-       pool->usedList = 0;
-       _ILMutexCreate(&(pool->lock));
+       return count;
 }
 
-void ILMonitorPoolDestroy(ILMonitorPool *pool)
+void ILMonitorPrintStats()
 {
-       if(!pool)
-       {
-               return;
-       }
-       DestroyMonitorList(pool->freeList);
-       pool->freeList = 0;
+       fprintf(stderr, "Number of monitors in the used list: %i\n",
+                   ListCount(_MonitorPool.usedList));
+       fprintf(stderr, "Number of monitors in the free list: %i\n",
+                   ListCount(_MonitorPool.freeList));
+       fprintf(stderr, "Number of reclaimed monitors: %i\n",
+                                       _MonitorPool.numReclaimed);
+       fprintf(stderr, "Number of abandoned monitors: %i\n",
+                                       _MonitorPool.numAbandoned);
+}
+#endif
+
+static void _ILMonitorPoolInit(void)
+{
+       ILMemPoolInitType(&(_MonitorPool.pool), ILMonitor, 20);
+       _MonitorPool.freeList = 0;
+       _MonitorPool.usedList = 0;
+#ifdef IL_THREAD_DEBUG
+       _MonitorPool.numAbandoned = 0;
+#endif
+       _ILCriticalSectionCreate(&(_MonitorPool.lock));
+}
+
+static void _ILMonitorPoolDestroy(void)
+{
+#ifdef IL_THREAD_DEBUG
+       ILMonitorPrintStats();
+#endif
+       DestroyMonitorList(_MonitorPool.freeList);
+       _MonitorPool.freeList = 0;
        /*
-        * NOTE: If the usedList is not 0 we might be in very big trouble 
afterwards
-        * but we clean up the resources used by this list anyways.
+        * NOTE: If the usedList is not 0 we will be in very big trouble 
afterwards
+        * if references to monitors in the pool are used later.
         */
-       DestroyMonitorList(pool->usedList);
-       pool->usedList = 0;
-       _ILMutexDestroy(&(pool->lock));
-       ILMemPoolDestroy(&(pool->pool));
+       DestroyMonitorList(_MonitorPool.usedList);
+       _MonitorPool.usedList = 0;
+       _ILCriticalSectionDestroy(&(_MonitorPool.lock));
+       ILMemPoolDestroy(&(_MonitorPool.pool));
 }
 
 /*
  * Get a new monitor from the monitor pool.
  * This function must be called with the monitorpool lock held.
  */
-static ILMonitor *ILMonitorPoolAllocMonitor(ILMonitorPool *pool)
+static ILMonitor *_ILMonitorPoolAllocMonitor(void)
 {
        ILMonitor *monitor;
 
-       if(pool->freeList)
+       if(_MonitorPool.freeList)
        {
                /* We have a monitor on the freelist so reuse this one */
-               monitor = pool->freeList;
-               pool->freeList = monitor->next;
+               monitor = _MonitorPool.freeList;
+               _MonitorPool.freeList = monitor->next;
                /* And add the monitor to the used list */
-               monitor->next = pool->usedList;
-               pool->usedList = monitor;
+               monitor->next = _MonitorPool.usedList;
+               _MonitorPool.usedList = monitor;
        }
        else
        {
-               monitor = ILMemPoolAllocItem(&(pool->pool));
+               monitor = ILMemPoolAllocItem(&(_MonitorPool.pool));
                if(monitor)
                {
                        ILMonitorInit(monitor);
                        /* And add the monitor to the used list */
-                       monitor->next = pool->usedList;
-                       pool->usedList = monitor;
+                       monitor->next = _MonitorPool.usedList;
+                       _MonitorPool.usedList = monitor;
                }
        }
        return monitor;
 }
 
 /*
+ * Reclaim a monitor that's no longer needed.
+ * If the monitor is in the used list of the monitor pool it will be
+ * destroyed and moved to the memory pool freelist.
+ * This function must be called with the monitorpool lock held.
+ */
+static void _ILMonitorPoolReclaimMonitor(_ILMonitorPool *pool,
+                                                                               
 ILMonitor *monitor)
+{
+       if(pool->usedList == monitor)
+       {
+               pool->usedList = monitor->next;
+               ILMonitorDestroy(monitor);
+               ILMemPoolFree(&(pool->pool), monitor);
+#ifdef IL_THREAD_DEBUG
+               ++(pool->numReclaimed);
+#endif
+       }
+       else
+       {
+               ILMonitor *prevMonitor;
+
+               prevMonitor = pool->usedList;
+               while(prevMonitor)
+               {
+                       if(prevMonitor->next == monitor)
+                       {
+                               prevMonitor->next = monitor->next;
+                               ILMonitorDestroy(monitor);
+                               ILMemPoolFree(&(pool->pool), monitor);
+#ifdef IL_THREAD_DEBUG
+                               ++(pool->numReclaimed);
+#endif
+                               return;
+                       }
+                       prevMonitor = prevMonitor->next;
+               }
+       }
+}
+
+/*
  * Move a monitor from the used list to the free list of the monitor pool.
  * This function must be called with the monitorpool lock held.
  */
-static void ILMonitorPoolMoveToFreeList(ILMonitorPool *pool,
-                                                                               
ILMonitor *monitor)
+static void _ILMonitorPoolMoveToFreeList(_ILMonitorPool *pool,
+                                                                               
 ILMonitor *monitor)
 {
        if(pool->usedList == monitor)
        {
@@ -163,46 +252,30 @@ static void ILMonitorPoolMoveToFreeList(ILMonitorPool 
*pool,
        }
 }
 
-int ILMonitorTimedTryEnter(ILMonitorPool *pool, void **monitorLocation,
-                                                  ILUInt32 ms)
+void _ILMonitorSystemInit()
+{
+       _ILMonitorPoolInit();
+}
+
+void _ILMonitorSystemDeinit()
+{
+       _ILMonitorPoolDestroy();
+}
+
+int ILMonitorTimedTryEnter(void **monitorLocation, ILUInt32 ms)
 {
-       ILMonitor * volatile *monLoc;
        ILMonitor *monitor;
        ILThread *thread;
 
-       if(!pool || !monitorLocation)
+       if(!monitorLocation)
        {
                return IL_THREAD_ERR_UNKNOWN;
        }
-       /* Store the location in a volatile variable */
-       monLoc = (ILMonitor **)monitorLocation;
-
        /* Get my thread */
        thread = _ILThreadGetSelf();
 
-       _ILMutexLock(&(pool->lock));
-       if((monitor = *monLoc) == 0)
-       {
-               /* We have to allocate a new monitor */
-               monitor = ILMonitorPoolAllocMonitor(pool);
-               if(!monitor)
-               {
-                       _ILMutexUnlock(&(pool->lock));
-                       return IL_THREAD_ERR_UNKNOWN;
-               }
-               /* and store the monitor at the location given */
-               *monLoc = monitor;      
-               /* Add me to the monitor users */
-               ++(monitor->users);
-       }
-       else if(monitor->owner != thread)
-       {
-               /* Add me to the monitor users */
-               ++(monitor->users);
-       }
-       _ILMutexUnlock(&(pool->lock));
-
-       if(monitor->owner == thread)
+       monitor = (ILMonitor *)ILInterlockedLoadP(monitorLocation);
+       if((monitor != 0) && (monitor->owner == thread))
        {
                /*
                 * I'm already the owner of this monitor.
@@ -216,9 +289,125 @@ int ILMonitorTimedTryEnter(ILMonitorPool *pool, void 
**monitorLocation,
                 * We have to enter the monitor.
                 */
                int result;
+               int waitStateResult;
+
+               /* Lock the monitor system */
+               _ILCriticalSectionEnter(&(_MonitorPool.lock));
+               
+               monitor = (ILMonitor *)ILInterlockedLoadP(monitorLocation);
+               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;
+                       }
+                       /* Unlock the monitor system */
+                       _ILCriticalSectionLeave(&(_MonitorPool.lock));
+                       
+                       return result;
+               }
+               if(monitor->owner == 0)
+               {
+                       /* Add me to the monitor users */
+                       ++(monitor->users);
+
+                       /*
+                        * 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;
+                               
+                               /* Unlock the monitor system */
+                               _ILCriticalSectionLeave(&(_MonitorPool.lock));
+                       
+                               return result;
+                       }
+                       else if(result == IL_THREAD_BUSY)
+                       {
+                               if(ms == 0)
+                               {
+                                       /* Rmove me from the monitor users */
+                                       --(monitor->users);
+                                       
+                                       /* Unlock the monitor system */
+                                       
_ILCriticalSectionLeave(&(_MonitorPool.lock));
+                       
+                                       return result;
+                               }
+                       }
+                       /* Rmove me from the monitor users */
+                       --(monitor->users);
+               }
+               if(ms == 0)
+               {
+                       /*
+                        * We have to acquire the monitor lock without waiting.
+                        * This is not possible.
+                        */
 
+                       /* Unlock the monitor system */
+                       _ILCriticalSectionLeave(&(_MonitorPool.lock));
+
+                       return IL_THREAD_BUSY;
+               }
+               /*
+                * Enter the Wait/Sleep/Join state.
+                */
+               result = _ILThreadEnterWaitState(thread);
+               if(result != IL_THREAD_OK)
+               {
+                       /* Unlock the monitor pool */
+                       _ILCriticalSectionLeave(&(_MonitorPool.lock));
+
+                       return result;
+               }
+               /* Add me to the monitor users */
+               ++(monitor->users);
+
+               /* Unlock the monitor pool */
+               _ILCriticalSectionLeave(&(_MonitorPool.lock));
+
+               /* Try to acquire the monitor */
                result = _ILMonitorTimedTryEnter(&(monitor->monitor), ms);
-               if(result == IL_THREAD_OK)
+
+               waitStateResult = _ILThreadLeaveWaitState(thread, result);
+
+               if((result == IL_THREAD_OK) && (waitStateResult == 
IL_THREAD_OK))
                {
                        /*
                         * The owner should be 0 at this point.
@@ -228,34 +417,51 @@ int ILMonitorTimedTryEnter(ILMonitorPool *pool, void 
**monitorLocation,
                }
                else
                {
-                       /* We have to leave the monitor again */
-                       _ILMutexLock(&(pool->lock));
+                       /* Lock the monitor system again */
+                       _ILCriticalSectionEnter(&(_MonitorPool.lock));
 
-                       /* Remove me from the monitor users */
+                       /* Remove me from the user list */
                        --(monitor->users);
+
+                       /*
+                        * If we acquired the monitor successfully but got 
interrupted
+                        * we have to exit the monitor now.
+                        */
+                       if(result == IL_THREAD_OK)
+                       {
+                               _ILMonitorExit(&(monitor->monitor));
+                       }
+
                        if(monitor->users <= 0)
                        {
                                /* No other waiters on the monitor */
                                monitor->users = 0;
                                /* So move the monitor to the free list of the  
pool */
-                               ILMonitorPoolMoveToFreeList(pool, monitor);
+                               _ILMonitorPoolMoveToFreeList(&_MonitorPool, 
monitor);
                                /* And clear the monitor location */
-                               *monitorLocation = 0;
+                               ILInterlockedStoreP(monitorLocation, 0);
+                       }
+
+                       /* Unlock the monitor pool */
+                       _ILCriticalSectionLeave(&(_MonitorPool.lock));
+
+                       if(waitStateResult != IL_THREAD_OK)
+                       {
+                               result = waitStateResult;
                        }
-                       _ILMutexUnlock(&(pool->lock));
                }
                return result;
        }
        return IL_THREAD_OK;
 }
 
-int ILMonitorExit(ILMonitorPool *pool, void **monitorLocation)
+int ILMonitorExit(void **monitorLocation)
 {
        ILMonitor * volatile *monLoc;
        ILMonitor *monitor;
        ILThread *thread;
 
-       if(!pool || !monitorLocation)
+       if(!monitorLocation)
        {
                return IL_THREAD_ERR_UNKNOWN;
        }
@@ -275,7 +481,7 @@ int ILMonitorExit(ILMonitorPool *pool, void 
**monitorLocation)
        if(monitor->enterCount <= 0)
        {
                /* We really are leaving the monitor */
-               _ILMutexLock(&(pool->lock));
+               _ILCriticalSectionEnter(&(_MonitorPool.lock));
 
                /* Remove me from the monitor users */
                --(monitor->users);
@@ -287,12 +493,12 @@ int ILMonitorExit(ILMonitorPool *pool, void 
**monitorLocation)
                        /* No other waiters on the monitor */
                        monitor->users = 0;
                        /* So move the monitor to the free list of the  pool */
-                       ILMonitorPoolMoveToFreeList(pool, monitor);
+                       _ILMonitorPoolMoveToFreeList(&_MonitorPool, monitor);
                        /* And clear the monitor location */
                        *monitorLocation = 0;
                }
                _ILMonitorExit(&(monitor->monitor));
-               _ILMutexUnlock(&(pool->lock));
+               _ILCriticalSectionLeave(&(_MonitorPool.lock));
        }
        return IL_THREAD_OK;
 }
@@ -341,25 +547,12 @@ int ILMonitorPulseAll(void **monitorLocation)
        return IL_THREAD_OK;
 }
 
-/*
- * Predicate function for monitor wait.
- */
-static int MonitorPredicate(void *mon)
-{
-       ILMonitor *monitor;
-       ILThread *thread;
-
-       monitor = (ILMonitor *)mon;
-       thread = _ILThreadGetSelf();
-       ILInterlockedCompareAndExchangeP((void **)&(monitor->owner), thread, 0);
-       return (monitor->owner == thread);
-}
-
 int ILMonitorTimedWait(void **monitorLocation, ILUInt32 ms)
 {
        ILMonitor *monitor;
        ILThread *thread;
        int result;
+       int waitStateResult;
        ILUInt32 enterCount;
 
        if(!monitorLocation)
@@ -372,21 +565,70 @@ int ILMonitorTimedWait(void **monitorLocation, ILUInt32 
ms)
        {
                return IL_THREAD_ERR_SYNCLOCK;
        }
+
+       /*
+        * Enter the Wait/Sleep/Join state.
+        */
+       result = _ILThreadEnterWaitState(thread);
+       if(result != IL_THREAD_OK)
+       {
+               return result;
+       }
        /*
-        * Save the number of times this thread entered the monitor and reset
-        + the value in the monitor
+        * Save the number of times this thread entered the monitor, reset
+        + the value in the monitor and clear the owner.
         */
        enterCount = monitor->enterCount;
        monitor->enterCount = 0;
-       result = _ILMonitorTimedWait(&(monitor->monitor), ms, MonitorPredicate, 
monitor);
-       if(result == IL_THREAD_OK || result == IL_THREAD_BUSY)
+       monitor->owner = 0;
+       result = _ILMonitorTimedWait(&(monitor->monitor), ms);
+       monitor->enterCount = enterCount;
+       monitor->owner = thread;
+       
+       waitStateResult = _ILThreadLeaveWaitState(thread, result);
+       if(waitStateResult != IL_THREAD_OK)
        {
-               monitor->enterCount = enterCount;
-               monitor->owner = thread;
+               result = waitStateResult;
        }
        return result;
 }
 
+/*
+ * Reclaim a monitor that's no longer needed.
+ * This function is usually called if an object is destroyed where
+ * a monitor is attached,
+ */
+void ILMonitorReclaim(void **monitorLocation)
+{
+       ILMonitor * volatile *monLoc;
+       ILMonitor *monitor;
+
+       /*
+        * Validate the arguments.
+        */
+       if(!monitorLocation)
+       {
+               return;
+       }
+       monLoc = (ILMonitor **)monitorLocation;
+       if((monitor = *monLoc) == 0)
+       {
+               /* No Monitor attached to the location */
+               return;
+       }
+       /* clear the monitor location */
+       *monLoc = 0;
+
+       /* Lock the pool */
+       _ILCriticalSectionEnter(&(_MonitorPool.lock));
+
+       /* Abandon the monitor in the pool */
+       _ILMonitorPoolReclaimMonitor(&_MonitorPool, monitor);
+
+       /* Unlock the pool */
+       _ILCriticalSectionLeave(&(_MonitorPool.lock));
+}
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/support/no_defs.c b/support/no_defs.c
index d3ca605..60ae4b8 100644
--- a/support/no_defs.c
+++ b/support/no_defs.c
@@ -59,6 +59,51 @@ int _ILThreadGetPriority(ILThread *thread)
        return IL_TP_NORMAL;
 }
 
+void _ILThreadInterrupt(ILThread *thread)
+{
+       /* Nothing to on a system without threads */
+}
+
+int _ILThreadSleep(ILUInt32 ms)
+{
+#ifdef HAVE_USLEEP
+       if(ms == 0)
+       {
+               ILThreadYield();
+       }
+       else if(ms <= IL_MAX_INT32)
+       {
+               /* Sleep for the specified timeout */
+               while(ms >= 100000)
+               {
+                       usleep(100000000);
+                       ms -= 100000;
+               }
+               if(ms > 0)
+               {
+                       usleep(ms * 1000);
+               }
+       }
+       else if(ms == IL_MAX_UINT32)
+       {
+               /* Sleep forever */
+               for(;;)
+               {
+                       usleep(100000000);
+               }
+       }
+       else
+       {
+               /* Invalid timeout specified */
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+       return IL_THREAD_OK;
+#else
+       /* We don't know how to sleep on this platform, so report "interrupted" 
*/
+       return ILTHREAD_ERR_INTERRUPT;
+#endif
+}
+
 int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex *mutex, ILUInt32 ms)
 {
        /* On a system without threads, we wait for the timeout
@@ -87,23 +132,13 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms)
                        usleep(100000000);
                }
        }
-       return 0;
+       return IL_THREAD_OK;
 #else
        /* We don't know how to sleep on this platform, so report "interrupted" 
*/
-       return -1;
+       return ILTHREAD_ERR_INTERRUPT;
 #endif
 }
 
-int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
-                                               ILMonitorPredicate predicate, 
void *arg)
-{
-       if(!predicate(arg))
-       {
-               return IL_THREAD_ERR_UNKNOWN;
-       }
-       return IL_THREAD_OK;
-}
-
 #ifdef __cplusplus
 };
 #endif
diff --git a/support/no_defs.h b/support/no_defs.h
index 6882d30..6cc5755 100755
--- a/support/no_defs.h
+++ b/support/no_defs.h
@@ -28,6 +28,7 @@ extern        "C" {
 /*
  * Types that are needed elsewhere.
  */
+typedef int    _ILCriticalSection;
 typedef int    _ILMutex;
 typedef int    _ILCondMutex;
 typedef int    _ILCondVar;
@@ -67,6 +68,26 @@ typedef int _ILMonitor;
 #define        _ILThreadDestroy(thread)                do { ; } while (0)
 
 /*
+ * Interrupt a thread in the wait/sleep/join state or when it enters the
+ * wait/sleep/join state the next time.
+ */
+void _ILThreadInterrupt(ILThread *thread);
+
+/*
+ * Put the current thread to sleep for a number of milliseconds.
+ * The sleep may be interrupted by a call to _ILThreadInterrupt.
+ */
+int _ILThreadSleep(ILUInt32 ms);
+
+/*
+ * Primitive critival section operations.
+ */
+#define        _ILCriticalSectionCreate(critsect)                      do { 
*(critsect) = 0; } while (0)
+#define        _ILCriticalSectionDestroy(critsect)                     do { ; 
} while (0)
+#define        _ILCriticalSectionEnterUnsafe(critsect)         do { ; } while 
(0)
+#define        _ILCriticalSectionLeaveUnsafe(critsect)         do { ; } while 
(0)
+
+/*
  * Primitive mutex operations.
  */
 #define        _ILMutexCreate(mutex)                   do { *(mutex) = 0; } 
while (0)
@@ -121,10 +142,8 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms);
 #define _ILMonitorTryEnter(mon)                        IL_THREAD_OK
 #define _ILMonitorEnter(mon)                           IL_THREAD_OK
 #define        _ILMonitorExit(mon)                                     
IL_THREAD_OK
-int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
-                                               ILMonitorPredicate predicate, 
void *arg);
-#define _ILMonitorWait(mon, pred, arg) \
-                       _ILMonitorTimedWait((mon), IL_MAX_UINT32, (pred), (arg))
+#define _ILMonitorTimedWait(mon, ms)           IL_THREAD_OK
+#define _ILMonitorWait(mon)                                    IL_THREAD_OK
 
 /*
  * Get or set the thread object that is associated with "self".
diff --git a/support/pt_defs.c b/support/pt_defs.c
index 132be44..4f55054 100755
--- a/support/pt_defs.c
+++ b/support/pt_defs.c
@@ -18,7 +18,9 @@
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  */
 
+#include "il_thread.h"
 #include "thr_defs.h"
+#include "interlocked.h"
 #if TIME_WITH_SYS_TIME
        #include <sys/time.h>
     #include <time.h>
@@ -40,6 +42,153 @@
 extern "C" {
 #endif
 
+/*
+ * Choose the version to use for modifying the counter in a count semaphore
+ */
+#define _SemAdd(dest, value)           ILInterlockedAddI4_Acquire((dest), 
(value))
+#define _SemSub(dest, value)           ILInterlockedSubI4_Acquire((dest), 
(value))
+#define _SemIncrement(dest)                    
ILInterlockedIncrementI4_Acquire((dest))
+#define _SemDecrement(dest)                    
ILInterlockedDecrementI4_Acquire((dest))
+#define _SemExchange(dest, value)      ILInterlockedExchangeI4_Acquire((dest), 
(value))
+
+/*
+ * Macros to run code in the current thread with the signal 
+ * IL_SIG_INTERRUPT enabled.
+ */
+
+/*
+ * 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.
+ * NOTE: There is a possibility that the interrupt is missed if it happens
+ * after enabling the signal but before the function that should be
+ * interrupted is able to catch the signal.
+ * Maybe we have to change this so that the signel handler is left with a
+ * siglongjmp later. This would remove the need for the IL_TS_INTERRUPTED
+ * flag too.
+ */
+#ifdef _IL_PT_INTERRUPT_JMP
+#define IL_START_INTERRUPTIBLE(__result) \
+               { \
+                       ILThread *__myThread; \
+                       __myThread = _ILThreadSelf(); \
+                       if(sigsetjmp(__myThread->interruptJmpBuf, 1) != 0) \
+                       { \
+                               __result = IL_THREAD_ERR_INTERRUPT; \
+                       } \
+                       else \
+                       { \
+                               sigset_t __newset; \
+                               sigset_t __oldset; \
+                               sigemptyset(&__newset); \
+                               sigaddset(&__newset, IL_SIG_INTERRUPT); \
+                               pthread_sigmask(SIG_UNBLOCK, &__newset, 
&__oldset); \
+                               {
+
+#define IL_END_INTERRUPTIBLE(__result) \
+                               } \
+                               pthread_sigmask(SIG_SETMASK, &__oldset, 0); \
+                       } \
+               }
+
+/*
+ * This macro enables the IL_SIG_INTERRUPT signal and doesn't check if an
+ * interrupt occured.
+ */
+#define IL_START_UNINTERRUPTIBLE() \
+               { \
+                       ILThread *__myThread; \
+                       ILUInt16 __threadState; \
+                       sigset_t __newset; \
+                       sigset_t __oldset; \
+                       __myThread = _ILThreadSelf(); \
+                       __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv)); \
+                       __threadState |= IL_TS_UNINTERRUPTIBLE; \
+                       ILInterlockedStoreU2(&(__myThread->state.split.priv), 
__threadState); \
+                       sigemptyset(&__newset); \
+                       sigaddset(&__newset, IL_SIG_INTERRUPT); \
+                       pthread_sigmask(SIG_UNBLOCK, &__newset, &__oldset); \
+                       { 
+
+#define IL_END_UNINTERRUPTIBLE(__result) \
+                       } \
+                       pthread_sigmask(SIG_SETMASK, &__oldset, 0); \
+                       __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv)); \
+                       if((__threadState & IL_TS_INTERRUPTED) != 0) \
+                       { \
+                               __result = IL_THREAD_ERR_INTERRUPT; \
+                       } \
+                       __threadState &= ~(IL_TS_UNINTERRUPTIBLE | 
IL_TS_INTERRUPTED); \
+                       ILInterlockedStoreU2(&(__myThread->state.split.priv), 
__threadState); \
+               }
+
+#else /* !_IL_PT_INTERRUPT_JMP */
+
+#define IL_START_INTERRUPTIBLE(__result) \
+               { \
+                       sigset_t __newset; \
+                       sigset_t __oldset; \
+                       ILThread *__myThread; \
+                       ILUInt16 __threadState; \
+                       __myThread = _ILThreadSelf(); \
+                       sigemptyset(&__newset); \
+                       sigaddset(&__newset, IL_SIG_INTERRUPT); \
+                       pthread_sigmask(SIG_UNBLOCK, &__newset, &__oldset); \
+                       __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv)); \
+                       if((__threadState & IL_TS_INTERRUPTED) != 0) \
+                       { \
+                               __result = IL_THREAD_ERR_INTERRUPT; \
+                       }  \
+                       else \
+                       {
+
+#define IL_END_INTERRUPTIBLE(__result) \
+                       } \
+                       pthread_sigmask(SIG_SETMASK, &__oldset, 0); \
+                       __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; \
+                       } \
+               }
+
+/*
+ * This macro enables the IL_SIG_INTERRUPT signal and doesn't check if an
+ * interrupt occured.
+ */
+#define IL_START_UNINTERRUPTIBLE() \
+               { \
+                       sigset_t __newset; \
+                       sigset_t __oldset; \
+                       ILThread *__myThread; \
+                       ILUInt16 __threadState; \
+                       __myThread = _ILThreadSelf(); \
+                       sigemptyset(&__newset); \
+                       sigaddset(&__newset, IL_SIG_INTERRUPT); \
+                       pthread_sigmask(SIG_UNBLOCK, &__newset, &__oldset); \
+                       { 
+
+#define IL_END_UNINTERRUPTIBLE(__result) \
+                       } \
+                       pthread_sigmask(SIG_SETMASK, &__oldset, 0); \
+                       __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv)); \
+                       if((__threadState & IL_TS_INTERRUPTED) != 0) \
+                       { \
+                               __result = IL_THREAD_ERR_INTERRUPT; \
+                       } \
+                       __threadState &= ~(IL_TS_UNINTERRUPTIBLE | 
IL_TS_INTERRUPTED); \
+                       ILInterlockedStoreU2(&(__myThread->state.split.priv), 
__threadState); \
+               }
+
+#endif /* !_IL_PT_INTERRUPT_JMP */
 
 #if defined(USE_COMPILER_TLS)
 /*
@@ -95,6 +244,7 @@ void _ILThreadSuspendUntilResumed(ILThread *thread)
                sigsuspend(&mask);
        }
        while(!(thread->resumeRequested));
+
 }
 
 /*
@@ -125,6 +275,26 @@ static void ResumeSignal(int sig)
 }
 
 /*
+ * Signal handler for IL_SIG_INTERRUPT
+ */
+static void InterruptSignal(int sig)
+{
+       ILThread *thread = _ILThreadGetSelf();
+       ILUInt16 threadState;
+
+       threadState = ILInterlockedLoadU2(&(thread->state.split.priv));
+#ifdef _IL_PT_INTERRUPT_JMP
+       if((threadState & IL_TS_UNINTERRUPTIBLE) == 0)
+       {
+               siglongjmp(thread->interruptJmpBuf, IL_THREAD_ERR_INTERRUPT);
+       }
+#endif
+       /* Set the interrupted flag */
+       threadState |= IL_TS_INTERRUPTED;
+       ILInterlockedStoreU2(&(thread->state.split.priv), threadState);
+}
+
+/*
  * Signal handler for IL_SIG_ABORT.
  */
 static void AbortSignal(int sig)
@@ -134,6 +304,117 @@ static void AbortSignal(int sig)
 }
 
 /*
+ * Interruptible wait on a semaphore.
+ */
+static int SemWaitInterruptible(sem_t *sem)
+{
+       int result;
+
+       IL_START_INTERRUPTIBLE(result)
+       do
+       {
+               result = sem_wait(sem);
+               if(result == 0)
+               {
+                       break;
+               }
+               else if(errno == EINTR)
+               {
+#ifndef _IL_PT_INTERRUPT_JMP
+                       __threadState = 
ILInterlockedLoadU2(&(__myThread->state.split.priv));
+                       if((threadState & IL_TS_INTERRUPTED) != 0)
+                       {
+                               break;
+                       }
+#endif /* _IL_PT_INTERRUPT_JMP */
+               }
+               else
+               {
+                       result = IL_THREAD_ERR_UNKNOWN;
+                       break;
+               }
+       } while(1);
+       IL_END_INTERRUPTIBLE(result)
+       return result;
+}
+
+/*
+ * Interruptible timed wait on a semaphore.
+ */
+static int SemTimedWaitInterruptible(sem_t *sem, ILUInt32 ms)
+{
+       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);
+               if(result == 0)
+               {
+                       break;
+               }
+               else if(errno == ETIMEDOUT)
+               {
+                       result = IL_THREAD_BUSY;
+                       break;
+               }
+               else if(errno == EINTR)
+               {
+#ifndef _IL_PT_INTERRUPT_JMP
+                       __threadState = 
ILInterlockedLoadU2(&(thread->state.split.priv));
+                       if((threadState & IL_TS_INTERRUPTED) != 0)
+                       {
+                               break;
+                       }
+#endif /* _IL_PT_INTERRUPT_JMP */
+               }
+               else
+               {
+                       result = IL_THREAD_ERR_UNKNOWN;
+                       break;
+               }
+       } while(1);
+       IL_END_INTERRUPTIBLE(result)
+       return result;
+}
+
+static int SemWaitUninterruptible(sem_t *sem)
+{
+       int result = IL_THREAD_OK;
+
+       IL_START_UNINTERRUPTIBLE()
+       do
+       {
+               if(sem_wait(sem) == 0)
+               {
+                       break;
+               }
+               else if(errno == EINTR)
+               {
+                       /* Ignore this one */
+               }
+               else
+               {
+                       /* An unexpected error occured so bail out */
+                       result = IL_THREAD_ERR_UNKNOWN;
+                       break;
+               }
+       } while(1);
+       IL_END_UNINTERRUPTIBLE(result)
+       return result;
+}
+
+/*
  * This function is only used for initializing an ILThread
  * structure for threads not created by pnet.
  */
@@ -162,11 +443,20 @@ void _ILThreadInitSystem(ILThread *mainThread)
        sigdelset(&(action.sa_mask), SIGTERM);
        sigdelset(&(action.sa_mask), SIGABRT);
 
-       /* Abort signal - used to stop blocking IO,
-          SA_RESTART must not be set */
+       /*
+        * Abort signal - used to signal a thread abort.
+        * SA_RESTART must not be set.
+        */
        action.sa_handler = AbortSignal;
        sigaction(IL_SIG_ABORT, &action, (struct sigaction *)0);
 
+       /*
+        * Interrupt signal - used to interrupt a blocked thread.
+        * SA_RESTART must not be set.
+        */
+       action.sa_handler = InterruptSignal;
+       sigaction(IL_SIG_INTERRUPT, &action, (struct sigaction *)0);
+
        action.sa_flags = SA_RESTART;
        action.sa_handler = SuspendSignal;
        sigaction(IL_SIG_SUSPEND, &action, (struct sigaction *)0);
@@ -184,10 +474,14 @@ void _ILThreadInitSystem(ILThread *mainThread)
        pthread_mutexattr_settype(&_ILMutexAttr, PTHREAD_MUTEX_NORMAL);
 #endif
 
-       /* Block the IL_SIG_RESUME signal in the current thread.
-          It will be unblocked by "SuspendUntilResumed" */
+       /*
+        * Block the IL_SIG_RESUME and IL_SIG_INTERRUPT signals in the current
+        * thread. They will be unblocked by "SuspendUntilResumed" or if 
entering
+        * the wait/sleep/join state
+        */
        sigemptyset(&set);
        sigaddset(&set, IL_SIG_RESUME);
+       sigaddset(&set, IL_SIG_INTERRUPT);
        pthread_sigmask(SIG_BLOCK, &set, (sigset_t *)0);
 
        /* Unblock the IL_SIG_SUSPEND and IL_SIG_ABORT signals */
@@ -272,6 +566,95 @@ int _ILThreadCreateSystem(ILThread *thread)
        }
 }
 
+/*
+ * Interrupt a thread in the wait/sleep/join state or when it enters the
+ * wait/sleep/join state the next time.
+ */
+void _ILThreadInterrupt(ILThread *thread)
+{
+       if(thread)
+       {
+               /*
+                * Send the interrupt request to the thread.
+                */
+               pthread_kill(thread->handle, IL_SIG_INTERRUPT);
+       }
+}
+
+/*
+ * Put the current thread to sleep for a number of milliseconds.
+ * The sleep may be interrupted by a call to _ILThreadInterrupt.
+ */
+int _ILThreadSleep(ILUInt32 ms)
+{
+       if(ms == 0)
+       {
+               /*
+                * This is like yielding the thread.
+                */
+               _ILThreadYield();
+               return IL_THREAD_OK;
+       }
+       else if((ms <= IL_MAX_INT32) || (ms == IL_MAX_UINT32))
+       {
+               int result;
+#ifdef HAVE_NANOSLEEP
+               struct timespec ts;
+       
+               ts.tv_sec = (time_t)(ms / 1000);
+               ts.tv_nsec = (long int)(ms % 1000) * 1000000;
+
+               IL_START_INTERRUPTIBLE(result)
+               do
+               {
+                       if((result = nanosleep(&ts, &ts)) != 0)
+                       {
+                               /* Looks like we got interrupted */
+                               if(errno == EINTR)
+                               {
+#ifndef _IL_PT_INTERRUPT_JMP
+                                       /* Check and clear the interrupted flag 
*/
+                                       __threadState = 
ILInterlockedLoadU2(&(thread->state.split.priv));
+                                       if((__threadState | IL_TS_INTERRUPTED) 
!= 0)
+                                       {
+                                               result = 
IL_THREAD_ERR_INTERRUPT;
+                                               break;
+                                       }
+                                       else
+                                       {
+                                               continue;
+                                       }
+#endif /* !_IL_PT_INTERRUPT_JMP */
+                               }
+                               else
+                               {
+                                       result = IL_THREAD_ERR_UNKNOWN;
+                                       break;
+                               }
+                       }
+                       else if(ms == IL_MAX_UINT32)
+                       {
+                               /* Reinitialize the time to sleep */
+                               ts.tv_sec = (time_t)(ms / 1000);
+                               ts.tv_nsec = (long int)(ms % 1000) * 1000000;
+                       }
+                       else
+                       {
+                               break;
+                       }
+               } while (1);
+#else /* !HAVE_NANOSLEEP */
+#error "nanosleep is needed for implementing an interruptible sleep"
+#endif /* !HAVE_NANOSLEEP */
+               IL_END_INTERRUPTIBLE(result)
+               return result;
+       }
+       else
+       {
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
 int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex *mutex, ILUInt32 ms)
 {
        struct timeval tv;
@@ -315,25 +698,37 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms)
 int pthread_mutex_timedlock (pthread_mutex_t *mutex,
                            const struct timespec *abs_timeout)
 {
-       struct timeval tv;
-       struct timespec ts;
        int retcode;
+#ifdef HAVE_NANOSLEEP
+       struct timespec ts;
        
        /* To avoid a completely busy wait we sleep for 10 ms between two 
tries. */
        /* As a consequence the resolution is at most 10 ms instead of 1 ms. */
        ts.tv_sec = 0;
        ts.tv_nsec = 10000000;  /* 10ms */
+#endif /* HAVE_NANOSLEEP */
        
        while((retcode = pthread_mutex_trylock(mutex)) == EBUSY)
        {
+               struct timeval tv;
+
                gettimeofday(&tv, NULL);
                
-               if(tv.tv_sec >= abs_timeout->tv_sec &&
-                   (tv.tv_usec * 1000) >= abs_timeout->tv_nsec)
+               if((tv.tv_sec > abs_timeout->tv_sec) ||
+                  (tv.tv_sec == abs_timeout->tv_sec &&
+                   (tv.tv_usec * 1000) >= abs_timeout->tv_nsec))
                {
                        return ETIMEDOUT;
                }
+#ifdef HAVE_NANOSLEEP
                nanosleep(&ts, NULL);
+#else /* !HAVE_NANOSLEEP */
+#ifdef HAVE_USLEEP
+                       usleep(10000);  /* 10 ms */
+#else /* !HAVE_USLEEP */
+#error "neither nanosleep nor usleep are available on this system"
+#endif /* !HAVE_USLEEP */
+#endif /* !HAVE_NANOSLEEP */
        }
        return retcode;
 }
@@ -343,27 +738,46 @@ int pthread_mutex_timedlock (pthread_mutex_t *mutex,
 int sem_timedwait(sem_t *sem,
                                  const struct timespec *abs_timeout)
 {
-       struct timeval tv;
+#ifdef HAVE_NANOSLEEP
        struct timespec ts;
-       int retcode;
        
        /* To avoid a completely busy wait we sleep for 10 ms between two 
tries. */
        /* As a consequence the resolution is at most 10 ms instead of 1 ms. */
        ts.tv_sec = 0;
        ts.tv_nsec = 10000000;  /* 10ms */
-       
-       while((retcode = sem_trywait(sem)) == EAGAIN)
+#endif /* HAVE_NANOSLEEP */
+
+       while(sem_trywait(sem) == -1)
        {
-               gettimeofday(&tv, NULL);
+               if(errno == EAGAIN)
+               {
+                       struct timeval tv;
+
+                       gettimeofday(&tv, NULL);
                
-               if(tv.tv_sec >= abs_timeout->tv_sec &&
-                   (tv.tv_usec * 1000) >= abs_timeout->tv_nsec)
+                       if((tv.tv_sec > abs_timeout->tv_sec) ||
+                          (tv.tv_sec == abs_timeout->tv_sec &&
+                           (tv.tv_usec * 1000) >= abs_timeout->tv_nsec))
+                       {
+                               errno = ETIMEDOUT;
+                               return -1;
+                       }
+#ifdef HAVE_NANOSLEEP
+                       if(nanosleep(&ts, NULL) != 0)
+                       {
+                               /* Looks like we got interrupted */
+                               return -1;
+                       }
+#else /* !HAVE_NANOSLEEP */
+#error "nanosleep is needed for implementing an interruptible sleep"
+#endif /* !HAVE_NANOSLEEP */
+               }
+               else
                {
-                       return ETIMEDOUT;
+                       return -1;
                }
-               nanosleep(&ts, NULL);
        }
-       return retcode;
+       return 0;
 }
 #endif /* !HAVE_SEM_TIMEDWAIT */
 
@@ -454,15 +868,39 @@ int _ILSemaphoreTimedWait(_ILSemaphore *sem, ILUInt32 ms, 
ILInt32 interruptable)
                        do
                        {
                                result = sem_wait(sem);
-                       } while(!interruptable && (result == EINTR));
+                               if(result == 0)
+                               {
+                                       break;
+                               }
+                               else if(errno == EINTR)
+                               {
+                                       if(interruptable)
+                                       {
+                                               result = 
IL_THREAD_ERR_INTERRUPT;
+                                               break;
+                                       }
+                               }
+                               else
+                               {
+                                       result = IL_THREAD_ERR_UNKNOWN;
+                                       break;                                  
+                               }
+                       } while(1);
                }
                else if(ms == 0)
                {
                        /* This is the same as the call to _ILSemaphoreTryWait. 
*/
-                       do
+                       if((result = sem_trywait(sem)) != 0)
                        {
-                               result = sem_trywait(sem);
-                       } while(!interruptable && (result == EINTR));
+                               if(errno == EAGAIN)
+                               {
+                                       result = IL_THREAD_BUSY;
+                               }
+                               else
+                               {
+                                       result = IL_THREAD_ERR_UNKNOWN;
+                               }
+                       }
                }
                else
                {
@@ -523,24 +961,16 @@ int _ILCountSemaphoreSignalCount(_ILCountSemaphore *sem, 
ILUInt32 count)
        {
                ILUInt32 current;
 
-               /* Lock the count semaphore object. */
-               _ILMutexLock(&(sem->_lock));
+               _SemAdd(&(sem->_value), count);
 
                for(current = 0; current < count; current++)
                {
                        if(sem_post(&(sem->_sem)))
                        {
                                /* An error occured. */
-
-                               /* Unlock the count semaphore object. */
-                               _ILMutexUnlock(&(sem->_lock));
-
                                return IL_THREAD_ERR_UNKNOWN;
                        }
-                       --(sem->_waiting);
                }
-               /* Unlock the count semaphore object. */
-               _ILMutexUnlock(&(sem->_lock));
        }
        else
        {
@@ -556,30 +986,20 @@ int _ILCountSemaphoreSignalCount(_ILCountSemaphore *sem, 
ILUInt32 count)
 int _ILCountSemaphoreSignalAll(_ILCountSemaphore *sem)
 {
        int result = IL_THREAD_OK;
+       ILInt32 count;
+       ILInt32 current;
 
-       if(sem->_waiting > 0)
-       {
-               /* Lock the count semaphore object. */
-               _ILMutexLock(&(sem->_lock));
+       count = _SemExchange(&(sem->_value), 0);
 
-               /* We have to recheck because of possible race conditions. */
-               while(sem->_waiting > 0)
+       for(current = 0; current < count; ++current)
+       {
+               if(sem_post(&(sem->_sem)))
                {
-                       if(sem_post(&(sem->_sem)))
-                       {
-                               /* An error occured. */
-
-                               /* Unlock the count semaphore object. */
-                               _ILMutexUnlock(&(sem->_lock));
-
-                               return IL_THREAD_ERR_UNKNOWN;
-                       }
-                       --sem->_waiting;
+                       /* An error occured. */
+                       return IL_THREAD_ERR_UNKNOWN;
                }
-
-               /* Unlock the count semaphore object. */
-               _ILMutexUnlock(&(sem->_lock));
        }
+
        return result;
 }
 
@@ -592,28 +1012,16 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms)
        {
                int result = IL_THREAD_OK;
 
-               /* Lock the count semaphore object. */
-               _ILMutexLock(&(sem->_lock));
-
-               ++sem->_waiting;
-
-               /* Unlock the count semaphore object. */
-               _ILMutexUnlock(&(sem->_lock));
+               /* Increment the count semaphore's waiters. */          
+               _SemIncrement(&(sem->_value));
 
                if((result = _ILSemaphoreTimedWait(&(sem->_sem), ms, 0)) != 
IL_THREAD_OK)
                {
-                       /* We have to decrement the counter again because the 
call failed. */
-
-                       /* Lock the count semaphore object. */
-                       _ILMutexLock(&(sem->_lock));
-
-                       if(sem->_waiting > 0)
-                       {
-                               --sem->_waiting;
-                       }
-
-                       /* Unlock the count semaphore object. */
-                       _ILMutexUnlock(&(sem->_lock));
+                       /*
+                        * We have to decrement the counter again because the 
call failed.
+                        * NOTE: The waiters can become negative here.
+                        */
+                       _SemDecrement(&(sem->_value));
                }
                return result;
        }
@@ -627,58 +1035,30 @@ int _ILMonitorExit(_ILMonitor *mon)
 {
        int result;
 
-       if(!(result = _ILCondMutexUnlockUnsafe(&(mon->_mutex))))
+       if((result = sem_post(&(mon->_enterSem))) == 0)
        {
-               /* NOTE: fast mutexes return 0 even if the current thread 
doesn't */
-               /* own the mutex. */
                return IL_THREAD_OK;
        }
-       return result == EPERM ? IL_THREAD_ERR_SYNCLOCK : IL_THREAD_ERR_UNKNOWN;
+       return IL_THREAD_ERR_UNKNOWN;
 }
 
 int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms)
 {
-       if(ms == IL_MAX_UINT32)
+       if(ms == 0)
        {
-               if(!_ILCondMutexLockUnsafe(&(mon->_mutex)))
+               if(sem_trywait(&(mon->_enterSem)) == 0)
                {
                        return IL_THREAD_OK;
                }
-               return IL_THREAD_ERR_UNKNOWN;
+               return errno == EAGAIN ? IL_THREAD_BUSY : IL_THREAD_ERR_UNKNOWN;
        }
-       else if(ms == 0)
+       else if(ms == IL_MAX_UINT32)
        {
-               int result;
-
-               if(!(result = _ILCondMutexTryLockUnsafe(&(mon->_mutex))))
-               {
-                       return IL_THREAD_OK;
-               }
-               return result == EBUSY ? IL_THREAD_BUSY : IL_THREAD_ERR_UNKNOWN;
+               return SemWaitInterruptible(&(mon->_enterSem));
        }
        else if(ms <= IL_MAX_INT32)
        {
-               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;
-               }
-               if((result = pthread_mutex_timedlock(&(mon->_mutex), &ts)) != 0)
-               {
-                       if(result == ETIMEDOUT)
-                       {
-                               return IL_THREAD_BUSY;
-                       }
-                       return IL_THREAD_ERR_UNKNOWN;
-               }
-               return IL_THREAD_OK;
+               return SemTimedWaitInterruptible(&(mon->_enterSem), ms);
        }
        else
        {
@@ -687,104 +1067,133 @@ int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 
ms)
        }
 }
 
-int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
-                                               ILMonitorPredicate predicate, 
void *arg)
+int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
 {
-       int result = 0;
+       int result = IL_THREAD_OK;
+       int enterResult;
 
-       if(ms == IL_MAX_UINT32)
+       if(ms == 0)
        {
-               do
+               /*
+                * 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 = pthread_cond_wait(&(mon->_cond), 
&(mon->_mutex));
-                       switch(result)
-                       {
-                               case 0:
-                               {
-                                       if(predicate(arg))
-                                       {
-                                               return IL_THREAD_OK;
-                                       }
-                               }
-                               break;
-
-                               case EINVAL:
-                               {
-                                       return IL_THREAD_ERR_INVALID_TIMEOUT;
-                               }
-                               break;
-
-                               case EPERM:
-                               {
-                                       return IL_THREAD_ERR_SYNCLOCK;
-                               }
-                               break;
-                       }
                        return IL_THREAD_ERR_UNKNOWN;
-               } while(1);
+               }
        }
-       else if(ms == 0)
+       else if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
        {
                /*
-                * In this case we don't have to enter the waiting queue but 
simply
-                * release the mutex and reacquire it again
-                * that's (release and reenter the ready state).
+                * Enter the wait queue
                 */
-               if(!(result = _ILCondMutexUnlockUnsafe(&(mon->_mutex))))
+               ILInterlockedDecrementI4_Acquire(&(mon->_waitValue));
+               
+               /*
+                * Release the ownership of the monitor.
+                */
+               if(sem_post(&(mon->_enterSem)) != 0)
+               {
+                       /*
+                        * Leave the wait queue and return with error
+                        */
+                       ILInterlockedIncrementI4_Acquire(&(mon->_waitValue));
+                       return IL_THREAD_ERR_UNKNOWN;
+               }
+
+               if(ms == IL_MAX_UINT32)
                {
-                       result = _ILCondMutexLockUnsafe(&(mon->_mutex));
-                       if(!result)
+                       result = SemWaitInterruptible(&(mon->_waitSem));
+                       if(result)
                        {
                                /*
-                                * In this case the predicate should always 
return a
-                                * value != 0
+                                * We have not been pulsed so leave the wait 
queue now
                                 */
-                               if(predicate(arg))
-                               {
-                                       return IL_THREAD_OK;
-                               }
-                               return IL_THREAD_ERR_UNKNOWN;
+                               
ILInterlockedIncrementI4_Acquire(&(mon->_waitValue));
+                               
+                       }
+               }
+               else
+               {
+                       result = SemTimedWaitInterruptible(&(mon->_waitSem), 
ms);
+                       if(result)
+                       {
+                               /*
+                                * We have not been pulsed so leave the wait 
queue now
+                                */
+                               
ILInterlockedIncrementI4_Acquire(&(mon->_waitValue));
+                               
                        }
                }
-               return result;
        }
-       else if(ms <= IL_MAX_INT32)
+       else
        {
-               struct timeval tv;
-               struct timespec ts;
+               /* Invalid negative value for ms. */
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+       /*
+        * Now we have to regain the ownership of the monitor
+        */
+       enterResult = SemWaitUninterruptible(&(mon->_enterSem));
+       if(result == IL_THREAD_OK)
+       {
+               result = enterResult;
+       }
+       return 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)
+int _ILMonitorPulse(_ILMonitor *mon)
+{
+       if(mon)
+       {
+               ILInt32 waitValue;
+               
+               waitValue = ILInterlockedLoadI4(&(mon->_waitValue));
+               if(waitValue < 0)
                {
-                       ++(ts.tv_sec);
-                       ts.tv_nsec -= 1000000000L;
+                       waitValue = 
ILInterlockedIncrementI4_Acquire(&(mon->_waitValue));
+                       if(waitValue <= 0)
+                       {
+                               sem_post(&(mon->_waitSem));
+                       }
+                       else
+                       {
+                               
ILInterlockedDecrementI4_Acquire(&(mon->_waitValue));
+                       }
                }
+       }
+       return IL_THREAD_OK;
+}
 
-               /* Wait until we are signalled or the timeout expires */
-               do
+int _ILMonitorPulseAll(_ILMonitor *mon)
+{
+       if(mon)
+       {
+               ILInt32 waitValue;
+               
+               waitValue = ILInterlockedLoadI4(&(mon->_waitValue));
+               if(waitValue < 0)
                {
-                       result = pthread_cond_timedwait(&(mon->_cond),
-                                                                               
    &(mon->_mutex), &ts);
-                       if((result == 0) || (result == ETIMEDOUT))
+                       waitValue = 
ILInterlockedExchangeI4_Acquire(&(mon->_waitValue), 0);
+
+                       if(waitValue < 0)
                        {
-                               if(predicate(arg))
+                               /* Release the waiters */
+                               while(waitValue < 0)
                                {
-                                       return result == 0 ? IL_THREAD_OK : 
IL_THREAD_BUSY;
+                                       sem_post(&(mon->_waitSem));
+                                       ++waitValue;
                                }
                        }
-                       else
+                       else if(waitValue > 0)
                        {
-                               return IL_THREAD_ERR_UNKNOWN;
+                               /* Readjust the monitor's wait value */
+                               ILInterlockedAddI4_Acquire(&(mon->_waitValue), 
waitValue);
                        }
-               } while(1);
-       }
-       else
-       {
-               /* Invalid negative value for ms. */
-               return IL_THREAD_ERR_INVALID_TIMEOUT;
+               }
        }
+       return IL_THREAD_OK;
 }
 
 #ifdef __cplusplus
diff --git a/support/pt_defs.h b/support/pt_defs.h
index 11ca5e2..f7e25d0 100755
--- a/support/pt_defs.h
+++ b/support/pt_defs.h
@@ -24,6 +24,9 @@
 #include <errno.h>
 #include <semaphore.h>
 #include <signal.h>
+#ifdef HAVE_SETJMP_H
+#include <setjmp.h>
+#endif
 #ifdef HAVE_LIBGC
 #include <private/gc_priv.h>   /* For SIG_SUSPEND */
 #if defined(SIG_SUSPEND) && defined(GC_DARWIN_THREADS)
@@ -52,19 +55,26 @@ extern      "C" {
  * them of various conditions.  Finding a free signal is a bit
  * of a pain as most of the obvious candidates are already in
  * use by pthreads or libgc.  Unix needs more signals!
+ * NOTE: libgc is using either SIGUSR1 and SIGUSR2 or
+ * SIGRTMIN + 5 and SIGRTMIN + 6 for SIG_INTERRUPT or SIG_THR_RESTART.
+ * Linux NTPL is using the first two and LinuxThreads the first three
+ * real time signals.
  */
 #if defined(__sun)
 #define        IL_SIG_SUSPEND          (__SIGRTMIN+0)
 #define        IL_SIG_RESUME           (__SIGRTMIN+1)
 #define        IL_SIG_ABORT            (__SIGRTMIN+2)
+#define        IL_SIG_INTERRUPT        (__SIGRTMIN+3)
 #elif !defined(__SIGRTMIN) || (__SIGRTMAX - __SIGRTMIN < 14)
 #define        IL_SIG_SUSPEND          SIGALRM
 #define        IL_SIG_RESUME           SIGVTALRM
 #define        IL_SIG_ABORT            SIGFPE
+#define        IL_SIG_INTERRUPT        SIGUSR1
 #else
 #define        IL_SIG_SUSPEND          (__SIGRTMIN+10)
 #define        IL_SIG_RESUME           (__SIGRTMIN+11)
 #define        IL_SIG_ABORT            (__SIGRTMIN+12)
+#define        IL_SIG_INTERRUPT        (__SIGRTMIN+13)
 #endif
 
 /*
@@ -100,6 +110,7 @@ extern      "C" {
 /*
  * Types that are needed elsewhere.
  */
+typedef pthread_mutex_t                _ILCriticalSection;
 typedef pthread_mutex_t                _ILMutex;
 typedef pthread_mutex_t                _ILCondMutex;
 typedef pthread_cond_t         _ILCondVar;
@@ -113,19 +124,62 @@ typedef pthread_mutex_t           _ILRWLock;
 #endif
 
 /*
+ * sigsetjmp and siglongjmp are not recognized by configure in all cases
+ * because they might be implemented by a macro (like on Linux)
+ * So we check for macros here if HAVE_SIGSETJMP or HAVE_SIGLONGJMP are
+ * not defined.
+ */
+#ifndef HAVE_SIGSETJMP
+#if defined(sigsetjmp) || defined(HAVE___SIGSETJMP)
+#define HAVE_SIGSETJMP 1
+#endif
+#endif
+
+#ifndef HAVE_SIGLONGJMP
+#ifdef siglongjmp
+#define HAVE_SIGLONGJMP 1
+#endif
+#endif
+
+/*
+ * Check if we can implement thread interrupts using sigsetjmp and siglongjmp
+ */
+#if defined(HAVE_SIGSETJMP) && defined(HAVE_SIGLONGJMP)
+#define _IL_PT_INTERRUPT_JMP
+#endif
+
+/*
+ * pthread specific extensions for an ILThread
+ */
+#ifdef _IL_PT_INTERRUPT_JMP
+#define _IL_THREAD_EXT \
+       sigjmp_buf                      interruptJmpBuf;
+
+#endif
+/*
  * Semaphore which allows to release multiple or all waiters.
+ * The semantic for posix and windows semaphores is the same and the
+ * implementation follows this semantics.
+ * This means:
+ * The value is decremented each time a thread tries to wait on the
+ * semaphore. If the count is positive at the time the thread calls
+ * one of the wait functions the thread is not blocked.
+ * The value is incremented by one or the number given if the one of the
+ * Signal functions is called.
+ * This means that if the member _value is negative the absolute value of
+ * _value indicates the number of blocked threads.
  */
 typedef struct
 {
-       _ILMutex                        _lock;
        _ILSemaphore            _sem;
-       ILInt32 volatile        _waiting;
+       ILInt32 volatile        _value;
 } _ILCountSemaphore;
 
 typedef struct
 {
-       _ILCondMutex    _mutex;
-       _ILCondVar              _cond;
+       ILInt32                 _waitValue;
+       _ILSemaphore    _waitSem;
+       _ILSemaphore    _enterSem;
 } _ILMonitor;
 
 /*
@@ -181,10 +235,41 @@ void _ILThreadSuspendUntilResumed(ILThread *thread);
 #define        _ILThreadDestroy(thread)        do { ; } while (0)
 
 /*
+ * Interrupt a thread in the wait/sleep/join state or when it enters the
+ * wait/sleep/join state the next time.
+ */
+void _ILThreadInterrupt(ILThread *thread);
+
+/*
+ * Put the current thread to sleep for a number of milliseconds.
+ * The sleep may be interrupted by a call to _ILThreadInterrupt.
+ */
+int _ILThreadSleep(ILUInt32 ms);
+
+/*
+ * The default mutex attribute for critical sections and mutexes.
+ * The attribute defaults to a fast mutex that doesn't do error checking
+ * and doesn't allow recursive locking.
+ */
+extern pthread_mutexattr_t _ILMutexAttr;
+
+/*
+ * Primitive critical section operations.
+ * NOTE: The "EnterUnsafe" and "LeaveUnsafe" operations are not "suspend-safe"
+ */
+#define _ILCriticalSectionCreate(critsect)     \
+                       (pthread_mutex_init((critsect), &_ILMutexAttr))
+#define _ILCriticalSectionDestroy(critsect)    \
+                       (pthread_mutex_destroy((critsect)))
+#define _ILCriticalSectionEnterUnsafe(critsect)        \
+                       (pthread_mutex_lock((critsect)))
+#define _ILCriticalSectionLeaveUnsafe(critsect)        \
+                       (pthread_mutex_unlock((critsect)))
+
+/*
  * Primitive mutex operations.  Note: the "Lock" and "Unlock"
  * operations are not "suspend-safe".
  */
-extern pthread_mutexattr_t _ILMutexAttr;
 #define        _ILMutexCreate(mutex)   \
                        (pthread_mutex_init((mutex), &_ILMutexAttr))
 #define        _ILMutexDestroy(mutex)  \
@@ -289,34 +374,32 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms);
  */
 #define        _ILMonitorCreate(mon)   \
                ({ \
-                       int __result = _ILCondMutexCreate(&((mon)->_mutex)); \
+                       int __result; \
+                       (mon)->_waitValue = 0; \
+                       __result = sem_init(&((mon)->_waitSem), 0, 0); \
                        if(!__result) \
                        { \
-                               __result = _ILCondVarCreate(&((mon)->_cond)); \
+                               __result = sem_init(&((mon)->_enterSem), 0, 1); 
\
                        } \
                        __result == 0 ? IL_THREAD_OK : IL_THREAD_ERR_UNKNOWN; \
                })
 #define        _ILMonitorDestroy(mon)  \
                ({ \
-                       int __result = _ILCondVarDestroy(&((mon)->_cond)); \
+                       int __result = _ILSemaphoreDestroy(&((mon)->_waitSem)); 
\
                        if(!__result) \
                        { \
-                               __result = 
_ILCondMutexDestroy(&((mon)->_mutex)); \
+                               __result = 
_ILSemaphoreDestroy(&((mon)->_enterSem)); \
                        } \
                        __result == 0 ? IL_THREAD_OK : IL_THREAD_ERR_UNKNOWN; \
                })
-#define        _ILMonitorPulse(mon)    \
-                       _ILCondVarSignal(&((mon)->_cond))
-#define        _ILMonitorPulseAll(mon) \
-                       (pthread_cond_broadcast(&((mon)->_cond)))
+int _ILMonitorPulse(_ILMonitor *mon);
+int _ILMonitorPulseAll(_ILMonitor *mon);
 int    _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms);
 #define _ILMonitorTryEnter(mon) _ILMonitorTimedTryEnter((mon), 0)
 #define _ILMonitorEnter(mon) _ILMonitorTimedTryEnter((mon), IL_MAX_UINT32)
-int    _ILMonitorExit(_ILMonitor *mon);
-int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
-                                               ILMonitorPredicate predicate, 
void *arg);
-#define _ILMonitorWait(mon, pred, arg) \
-                       _ILMonitorTimedWait((mon), IL_MAX_UINT32, (pred), (arg))
+int _ILMonitorExit(_ILMonitor *mon);
+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".
diff --git a/support/thr_defs.h b/support/thr_defs.h
index 4c12c41..831a2c2 100755
--- a/support/thr_defs.h
+++ b/support/thr_defs.h
@@ -23,34 +23,14 @@
 #define        _THR_DEFS_H
 
 /*
- * NOTE: For modifying a thread's state
- * If the thread's state is going to be modified do it the following way:
- * 1. lock the thread
- * 2. load the thread's state to a local variable
- * 3. do what you want to do with the thread's state with the local variable
- * 4. store the local variable to the thread's state
- * 5. unlock the thread
- *
- * This is done this way to be able to query the current thread's state
- * without having to lock the thread.
- * The reader will read the consistent state before the thread was locked
- * until all changes are done.
- * Additionally the compiler is able to hold the thread's state in a
- * register instead of having to read and write the volatile state multiple
- * times.
+ * Define IL_THREAD_ASSERTIONS for enabling threading assertions.
  */
+/* #define IL_THREAD_ASSERTIONS */
 
 /*
  * Define IL_THREAD_DEBUG for enabling threading debug features.
  */
-/* #define IL_TRHEAD_DEBUG */
-
-/*
- * Predicate function for the _ILMonitorWait functions.
- * The function has to return 0 if the predicate is not true so that the
- * wait has to be called again and != 0 otherwise.
- */
-typedef int (*ILMonitorPredicate)(void *);
+/* #define IL_THREAD_DEBUG */
 
 /*
  * Threading error codes.
@@ -72,7 +52,22 @@ typedef int (*ILMonitorPredicate)(void *);
 #include "thr_choose.h"
 #include "il_utils.h"
 #include "interrupt.h"
+#ifdef IL_THREAD_ASSERTIONS
+#include <stdio.h>
+#include <stdlib.h>
+#endif
 
+#ifdef IL_THREAD_ASSERTIONS
+#define IL_THREAD_ASSERT(expr) \
+       if(!(expr)) \
+       { \
+               fprintf(stderr, "Threading assertion failure at %s:%ld\n", \
+                               __FILE__, (unsigned long)__LINE__); \
+               abort(); \
+       }
+#else
+#define IL_THREAD_ASSERT(expr)
+#endif
 /*
  * Include the package-specific definitions.
  */
@@ -90,6 +85,12 @@ typedef int (*ILMonitorPredicate)(void *);
 extern "C" {
 #endif
 
+/*
+ * Monitor support with the whole .NET monitor semantics.
+ */
+typedef struct _tagILMonitor ILMonitor;
+
+
 typedef struct __tagILWaitMutex ILWaitMutex;
 
 /*
@@ -98,11 +99,11 @@ typedef struct __tagILWaitMutex ILWaitMutex;
 typedef struct _tagILWakeup
 {
        _ILCondMutex                    lock;
-       _ILCondVar                              condition;
+       _ILCondVar                              condition;      
        ILUInt32        volatile        count;
        ILUInt32        volatile        limit;
        int                     volatile        interrupted;
-       void *      volatile    object;
+       void *          volatile    object;
        int                                             ownedMutexesCount;
        int                                             ownedMutexesCapacity;
        ILWaitMutex                             **ownedMutexes;
@@ -115,8 +116,8 @@ typedef struct _tagILWakeupItem _ILWakeupItem;
 struct _tagILWakeupItem
 {
        _ILWakeupItem * volatile next;
-       _ILWakeup     * volatile wakeup;
-       void          * volatile object;
+       _ILWakeup         * volatile wakeup;
+       void              * volatile object;
 
 };
 
@@ -127,8 +128,8 @@ typedef struct _tagILWakeupQueue
 {
        _ILWakeupItem * volatile first;
        _ILWakeupItem * volatile last;
-       _ILWakeupItem                    space;
-       int                         volatile spaceUsed;
+       _ILWakeupItem                    space;
+       int                             volatile spaceUsed;
 
 } _ILWakeupQueue;
 
@@ -144,17 +145,76 @@ struct _tagILThreadCleanupEntry
 };
 
 /*
+ * NOTE: For modifying the thread's state public modifiable state:
+ * 1. lock the thread
+ * 2. load the thread's state to a local variable
+ * 3. do what you want to do with the thread's state with the local variable
+ * 4. store the local variable to the thread's state
+ * 5. unlock the thread
+ *
+ * This is done this way to be able to query the current thread's state
+ * without having to lock the thread.
+ * The reader will read the consistent state before the thread was locked
+ * until all changes are done.
+ * Additionally the compiler is able to hold the thread's state in a
+ * register instead of having to read and write the volatile state multiple
+ * times.
+ */
+
+/*
+ * Helper structure for the thread's state.
+ * The idea behind this is to divide the state into two parts where
+ * the priv part is modified only by the thread the ILThread is belonging to.
+ * The pub part may be modified by any other thread.
+ * So the priv part can be modified without having to lock the thread.
+ * The pub part must be changed only with the thread's lock held (see NOTE).
+ *
+ * Flags in the priv member:
+ * IL_TS_RUNNING
+ * IL_TS_STOPPED
+ * IL_TS_WAIT_SLEEP_JOIN
+ * IL_TS_ABORTED
+ *
+ * Flags in the pub member:
+ * IL_TS_STOP_REQUESTED
+ * IL_TS_SUSPEND_REQUESTED
+ * IL_TS_BACKGROUND
+ * IL_TS_UNSTARTED
+ * IL_TS_SUSPENDED
+ * IL_TS_ABORT_REQUESTED
+ * internal flags
+ * IL_TS_SUSPENDED_SELF
+ *
+ * Special:
+ * The IL_TS_INTERRUPTED flag might be present in both parts
+ * for now until the waithandle stuff is redone.
+ */
+struct _tagILThreadSplitState
+{
+       ILUInt16        priv;
+       ILUInt16        pub;
+};
+
+typedef union _tagILThreadState _ILThreadState;
+union _tagILThreadState
+{
+       ILUInt32                                                comb;
+       struct _tagILThreadSplitState   split;
+};
+
+/*
  * Internal structure of a thread descriptor.
  */
 struct _tagILThread
 {
-       _ILMutex                                                lock;
+       _ILCriticalSection                              lock;
        _ILThreadHandle         volatile        handle;
        _ILThreadIdentifier     volatile        identifier;
-       ILUInt16                        volatile        state;
+       _ILThreadState                                  state;
+       ILInt32                                                 useCount;
        unsigned char           volatile        resumeRequested;
        unsigned char           volatile        suspendRequested;
-       unsigned int            volatile        numLocksHeld;
+       unsigned int            volatile        numLocksHeld;
        _ILSemaphore                                    resumeAck;
        _ILSemaphore                                    suspendAck;
        ILThreadStartFunc       volatile        startFunc;
@@ -164,12 +224,15 @@ struct _tagILThread
        _ILWakeupQueue                                  joinQueue;
        ILThreadCleanupEntry                    *firstCleanupEntry;
        ILThreadCleanupEntry                    *lastCleanupEntry;
-       int                                                             
destroyOnExit;
        ILWaitHandle                                    *monitor;
        /* 1 if the gc knows the thread and is allowed to execute managed code 
*/
 #if defined(IL_INTERRUPT_SUPPORTS)
        ILInterruptHandler                              interruptHandler;
 #endif
+       /* Add the implementation specific thread members */
+#ifdef _IL_THREAD_EXT
+       _IL_THREAD_EXT
+#endif
 };
 
 /*
@@ -241,7 +304,7 @@ struct _tagILWaitHandleVtable
 struct _tagILWaitHandle
 {
        const _ILWaitHandleVtable  *vtable;
-       _ILMutex                                        lock;
+       _ILCriticalSection                      lock;
 };
 
 /*
@@ -301,25 +364,31 @@ typedef struct
 {
        ILWaitMutex                     parent;
        _ILWakeupQueue          signalQueue;
-       int                                     waiters;
+       int                             waiters;
 } ILWaitMonitor;
 
 /*
- * Monitor support with the whole .NET monitor semantics.
- */
-typedef struct _tagILMonitor ILMonitor;
-
-/*
- * Pool used by the monitor.
+ * Safe critical section enter and leave operations that will prevent the
+ * thread from being suspended while it holds a lock.
  */
-typedef struct _tagILMonitorPool ILMonitorPool;
-struct _tagILMonitorPool
-{
-       _ILMutex            lock;               /* Mutex to synchronize the 
access to the pool */
-       ILMonitor          *freeList;   /* List of unused monitors */
-       ILMonitor          *usedList;   /* List of monitors in use */
-       ILMemPool               pool;           /* Pool to allocate the 
monitors from */
-};
+#define        _ILCriticalSectionEnter(critsect)       \
+                       do { \
+                               ILThread *__self = _ILThreadGetSelf(); \
+                               ++(__self->numLocksHeld); \
+                               _ILCriticalSectionEnterUnsafe((critsect)); \
+                       } while (0)
+#define        _ILCriticalSectionLeave(critsect)       \
+                       do { \
+                               ILThread *__self = _ILThreadGetSelf(); \
+                               _ILCriticalSectionLeaveUnsafe((critsect)); \
+                               if(--(__self->numLocksHeld) == 0) \
+                               { \
+                                       if(__self->suspendRequested) \
+                                       { \
+                                               
_ILThreadSuspendRequest(__self); \
+                                       } \
+                               } \
+                       } while (0)
 
 /*
  * Safe mutex lock and unlock operations that will prevent the
@@ -459,6 +528,12 @@ void _ILThreadInitHandleSelf(ILThread *thread);
 int _ILThreadCreateSystem(ILThread *thread);
 
 /*
+ * Interrupt a thread in the wait/sleep/join state or when it enters the
+ * wait/sleep/join state the next time.
+ */
+void _ThreadInterrupt(ILThread *thread);
+
+/*
  * Process a request to suspend the current thread.
  */
 void _ILThreadSuspendRequest(ILThread *thread);
@@ -474,6 +549,23 @@ void _ILThreadSetPriority(ILThread *thread, int priority);
 int _ILThreadGetPriority(ILThread *thread);
 
 /*
+ * Get the number of running threads.
+ * Running threads here is: started but not yet finished.
+ * The function is used to check if we are still in single threaded mode.
+ */
+long _ILThreadGetNumThreads();
+
+/*
+ * Enter the "wait/sleep/join" state on the current thread.
+ */
+int _ILThreadEnterWaitState(ILThread *thread);
+
+/*
+ * Leave the "wait/sleep/join" state on the current thread.
+ */
+int _ILThreadLeaveWaitState(ILThread *thread, int result);
+
+/*
  * Create a thread wakeup object.
  */
 void _ILWakeupCreate(_ILWakeup *wakeup);
@@ -576,34 +668,45 @@ int _ILWaitOneBackupInterruptsAndAborts(ILWaitHandle 
*handle, int timeout);
        (((ILWaitMutex *)handle)->owner == &(t->wakeup))
 
 /*
- * Initialize a monitor pool for the monitor subsystem.
+ * Initialize the monitor subsystem
  */
-void ILMonitorPoolInit(ILMonitorPool *pool);
+void _ILMonitorSystemInit();
 
 /*
- * Destroy a monitor pool.
- * There must be no used monitors in this pool when calling this function.
+ * Destroy the monitor subsystem.
+ * There must be no used monitors left when calling this function.
  */
-void ILMonitorPoolDestroy(ILMonitorPool *pool);
+void _ILMonitorSystemDeinit();
 
 /*
  * Enter a monitor 
  * This function returns IL_THREAD_OK on success, IL_THREAD_BUSY on timeout
  * or any other of the threading return codes on error.
- */
-int ILMonitorTimedTryEnter(ILMonitorPool *pool, void **monitorLocation,
-                                                  ILUInt32 ms);
-#define ILMonitorEnter(pool, loc) \
-                               ILMonitorTimedTryEnter((pool), (loc), 
IL_MAX_UINT32)
-#define ILMonitorTryEnter(pool, loc) \
-                               ILMonitorTimedTryEnter((pool), (loc), 0)
+ * NOTE: The monitor is only entered if IL_THREAD_OK is returned.
+ * On every ohter return value the lock is not obtained.
+ * This is because the code used with monitors usually looks like:
+ * Monitor.Enter(obj);
+ * try
+ * {
+ *    do_something
+ * }
+ * finally
+ * {
+ *    Monitor.Exit(obj);
+ * }
+ * So the exception is thrown outside the try/finally handlier that ensures
+ * propper monitor release.
+ */
+int ILMonitorTimedTryEnter(void **monitorLocation, ILUInt32 ms);
+#define ILMonitorEnter(loc)            ILMonitorTimedTryEnter((loc), 
IL_MAX_UINT32)
+#define ILMonitorTryEnter(loc) ILMonitorTimedTryEnter((loc), 0)
 
 /*
  * Leave the monitor stored at monitorLocation.
  * This function returns IL_THREAD_OK on success, IL_THREAD_BUSY on timeout
  * or any other of the threading return codes on error.
  */
-int ILMonitorExit(ILMonitorPool *pool, void **monitorLocation);
+int ILMonitorExit(void **monitorLocation);
 
 /*
  * Enter the wait state on an owned monitor.
@@ -623,6 +726,15 @@ int ILMonitorPulse(void **monitorLocation);
  */
 int ILMonitorPulseAll(void **monitorLocation);
 
+/*
+ * Reclaim the monitor stored at monitorLocation.
+ * This function is used for example if a monitor is attached to an object
+ * that is going to be reclaimed by a garbage collector.
+ * The monitor will not be needed anymore but it's state is undefined.
+ * Reclaiming a monitor is caused by a bug in the using application.
+ */
+void ILMonitorReclaim(void **monitorLocation);
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/support/thread.c b/support/thread.c
old mode 100644
new mode 100755
index 4f44859..f4c317c
--- a/support/thread.c
+++ b/support/thread.c
@@ -46,7 +46,7 @@ extern        "C" {
 /*
  * Global state that is mutexed between all threads.
  */
-static _ILMutex threadLockAll;
+static _ILCriticalSection threadLockAll;
 /* Number of threads that have started and not finished */
 static long volatile numThreads;
 /* Number of threads that have started and not finished and are background 
threads */
@@ -55,9 +55,9 @@ static long volatile numBackgroundThreads;
 static ILWaitHandle *noFgThreadsEvent;
 
 /*
- * Global mutex for atomic operations.
+ * Global critical section for atomic operations.
  */
-static _ILMutex atomicLock;
+static _ILCriticalSection atomicLock;
 
 /*
  * The "main" thread's object.
@@ -74,30 +74,24 @@ int ILHasThreads(void)
  */
 static void _ILThreadInit(void)
 {
+       /* Initialize the main thread to all 0s */
+       ILMemZero(&mainThread, sizeof(ILThread));
+       
        /* Perform system-specific initialization */
        _ILThreadInitSystem(&mainThread);
 
        /* Initialize synchronization objects that we need */
-       _ILMutexCreate(&threadLockAll); 
-       _ILMutexCreate(&atomicLock);
+       _ILCriticalSectionCreate(&threadLockAll);
+       _ILCriticalSectionCreate(&atomicLock);
 
        /* Set up the "main" thread.  "_ILThreadInitSystem" has already
           set the "handle" and "identifier" fields for us */
-       _ILMutexCreate(&(mainThread.lock));
-       mainThread.state            = IL_TS_RUNNING;
-       mainThread.resumeRequested  = 0;
-       mainThread.suspendRequested = 0;
-       mainThread.numLocksHeld     = 0;
+       _ILCriticalSectionCreate(&(mainThread.lock));
+       mainThread.state.split.priv = IL_TS_RUNNING;
+       mainThread.useCount                     = 2;    /* 2 here because the 
thread is already started */
        _ILSemaphoreCreate(&(mainThread.resumeAck));
        _ILSemaphoreCreate(&(mainThread.suspendAck));
-       mainThread.startFunc        = 0;
-       mainThread.userObject       = 0;
-       mainThread.startArg                     = 0;
-       mainThread.destroyOnExit        = 0;
        mainThread.monitor = ILWaitMonitorCreate();
-       #ifdef IL_INTERRUPT_SUPPORTS
-               mainThread.interruptHandler = 0;
-       #endif
 
        _ILWakeupCreate(&(mainThread.wakeup));
        _ILWakeupQueueCreate(&(mainThread.joinQueue));
@@ -107,21 +101,55 @@ static void _ILThreadInit(void)
        /* Set the thread object for the "main" thread */
        _ILThreadSetSelf(&mainThread);
 
+       /* Initialize the implementation specific thread members */
+       #ifdef _ILTHREAD_EXT_INIT
+               _IL_THREAD_EXT_INIT(&mainThread);
+       #endif
+
        /* We have 1 foreground thread in the system at present */
        numThreads = 1;
        numBackgroundThreads = 0;
 
        _ILInterruptInit();
+
+       /* Initialize the monitor subsystem */
+       _ILMonitorSystemInit();
 }
 
 static void _ILThreadDeinit(void)
 {
+       /* Cleanup the monitor subsystem */
+       _ILMonitorSystemDeinit();
+
        _ILInterruptDeinit();
 
        if(noFgThreadsEvent != 0)
        {
                ILWaitHandleClose(noFgThreadsEvent);
-       }       
+       }
+
+       /* Destroy the main thread's resources */
+       _ILWakeupQueueDestroy(&(mainThread.joinQueue));
+       /* TODO: Find and fix the wakeup not removed
+       _ILWakeupDestroy(&(mainThread.wakeup));
+       */
+       if(mainThread.monitor)
+       {
+               ILWaitHandleClose(mainThread.monitor);
+       }
+       _ILSemaphoreDestroy(&(mainThread.suspendAck));
+       _ILSemaphoreDestroy(&(mainThread.resumeAck));
+
+       /* Deinitialize the implementation specific thread members */
+       #ifdef _ILTHREAD_EXT_DEINIT
+               _IL_THREAD_EXT_DEINIT(&mainThread);
+       #endif
+
+       _ILCriticalSectionDestroy(&(mainThread.lock));
+
+       /* Destroy the synchronization objects */
+       _ILCriticalSectionDestroy(&threadLockAll);
+       _ILCriticalSectionDestroy(&atomicLock);
 }
 
 /*
@@ -129,7 +157,7 @@ static void _ILThreadDeinit(void)
  */
 static void _ILThreadAdjustCount(int numThreadsAdjust, int 
numBackgroundThreadsAdjust)
 {
-       _ILMutexLock(&threadLockAll);
+       _ILCriticalSectionEnter(&threadLockAll);
        {
                numThreads += numThreadsAdjust;         
                numBackgroundThreads += numBackgroundThreadsAdjust;
@@ -145,7 +173,7 @@ static void _ILThreadAdjustCount(int numThreadsAdjust, int 
numBackgroundThreadsA
                        ILWaitEventReset(noFgThreadsEvent);
                }
        }
-       _ILMutexUnlock(&threadLockAll);
+       _ILCriticalSectionLeave(&threadLockAll);
 }
 
 void ILThreadInit(void)
@@ -184,71 +212,63 @@ static void _ILThreadRunAndFreeCleanups(ILThread *thread)
        thread->firstCleanupEntry = 0;
 }
 
-static void _ILPrivateThreadDestroy(ILThread *thread, int allowSelf)
+static void _ILPrivateThreadDestroy(ILThread *thread)
 {
-       ILUInt16 threadState;
+       _ILThreadState threadState;
 
-       /* Bail out if this is the current thread or main thread */
-       if((thread == _ILThreadGetSelf() && !allowSelf) || thread == 
&mainThread)
+       /* Bail out if this is the main thread */
+       if(thread == &mainThread)
        {
                return;
        }
 
        /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
-
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       _ILCriticalSectionEnter(&(thread->lock));
 
-       /* Don't terminate the thread or adjust counts if it has already been 
stopped */
-       if((threadState & IL_TS_STOPPED) == 0)
+       /* Decrement the usage counter */
+       thread->useCount -= 1;
+       
+       if(thread->useCount > 0)
        {
-               threadState |= IL_TS_STOPPED;
-               ILInterlockedStoreU2(&(thread->state), threadState);
-
-               /* Only terminate the system thread if one was created */
-               if((threadState & IL_TS_UNSTARTED) == 0)
-               {
-                       /* Terminating the thread is unsafe so just don't
-                          destroy now and tell the thread to destroy itself
-                          on exit */
-
-                       thread->destroyOnExit = 1;
-
-                       _ILMutexUnlock(&thread->lock);
-                       
-                       ILThreadAbort(thread);
-
-                       return;
-               }
-
-               _ILMutexUnlock(&thread->lock);
-
-               /* Run and free the cleanup handlers */
-               _ILThreadRunAndFreeCleanups(thread);
+               /* The thread is still in use */
+               /* So unlock the thread object and return */
+               _ILCriticalSectionLeave(&(thread->lock));
+               return;
+       }
+       
+       /* Get the complete threadstate */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       
+       /* Don't destroy the thread if it's started and not yet stopped */
+       if(((threadState.split.priv & IL_TS_STOPPED) == 0) &&
+          ((threadState.split.pub & IL_TS_UNSTARTED) == 0))
+       {
+               _ILCriticalSectionLeave(&(thread->lock));
+               return;
        }
        else
        {
                /* Unlock the thread object and free it */
-               _ILMutexUnlock(&(thread->lock));
+               _ILCriticalSectionLeave(&(thread->lock));
        }
 
        /* Only destroy the system thread if one was created */
-       if((threadState & IL_TS_UNSTARTED) == 0)
+       if((threadState.split.pub & IL_TS_UNSTARTED) == 0)
        {
                _ILThreadDestroy(thread);
        }
 
        ILWaitHandleClose(thread->monitor);
-       _ILMutexDestroy(&(thread->lock));
+       _ILCriticalSectionDestroy(&(thread->lock));
        _ILSemaphoreDestroy(&(thread->suspendAck));
-       _ILSemaphoreDestroy(&(thread->resumeAck));      
+       _ILSemaphoreDestroy(&(thread->resumeAck));
        _ILWakeupQueueDestroy(&(thread->joinQueue));
        ILFree(thread);
 }
 
 void ILThreadDestroy(ILThread *thread)
 {
-       _ILPrivateThreadDestroy(thread, 0);
+       _ILPrivateThreadDestroy(thread);
 }
 
 void *ILThreadRunSelf(void *(* thread_func)(void *), void *arg)
@@ -256,33 +276,24 @@ void *ILThreadRunSelf(void *(* thread_func)(void *), void 
*arg)
        ILThread *thread_self;
        void *result;
 
-       /* Create a new thread object and populate it */
+       /*
+        * Create a new thread object and populate it.
+        * All members are guaranteed to be inititialized to 0 after this point.
+        */
        thread_self = (ILThread *)ILCalloc(1, sizeof(ILThread));
        if(!thread_self)
        {
                return 0;
        }
 
-       _ILMutexCreate(&(thread_self->lock));   
-       thread_self->state = IL_TS_UNSTARTED;
-       thread_self->resumeRequested = 0;
-       thread_self->suspendRequested = 0;
-       thread_self->numLocksHeld = 0;
-       thread_self->firstCleanupEntry = 0;
-       thread_self->lastCleanupEntry = 0;
+       _ILCriticalSectionCreate(&(thread_self->lock));
+       thread_self->state.split.priv = IL_TS_RUNNING;
        thread_self->monitor = ILWaitMonitorCreate();
        _ILSemaphoreCreate(&(thread_self->resumeAck));
        _ILSemaphoreCreate(&(thread_self->suspendAck));
-       thread_self->startFunc = 0;
-       thread_self->userObject = 0;
-       thread_self->startArg = 0;
        _ILWakeupCreate(&(thread_self->wakeup));
        _ILWakeupQueueCreate(&(thread_self->joinQueue));
-       thread_self->handle = 0;
-       thread_self->destroyOnExit = 0;
-       #ifdef IL_INTERRUPT_SUPPORTS
-               thread_self->interruptHandler = 0;
-       #endif
+       thread_self->useCount = 2;      /* 2 here because the thread is already 
started */
        
        /* Initialize the handle and the identifier */
        _ILThreadInitHandleSelf(thread_self);
@@ -290,16 +301,25 @@ void *ILThreadRunSelf(void *(* thread_func)(void *), void 
*arg)
        /* Set the thread object for the thread */
        _ILThreadSetSelf(thread_self);
 
+       /* Initialize the implementation specific thread members */
+       #ifdef _ILTHREAD_EXT_INIT
+               _IL_THREAD_EXT_INIT(thread_self);
+       #endif
+
        result = ILGCRunFunc(thread_func, arg);
 
        _ILThreadRunAndFreeCleanups(thread_self);
 
        /* and now destroy the ILThread instance. */
        ILWaitHandleClose(thread_self->monitor);
-       _ILMutexDestroy(&(thread_self->lock));
        _ILSemaphoreDestroy(&(thread_self->suspendAck));
-       _ILSemaphoreDestroy(&(thread_self->resumeAck)); 
+       _ILSemaphoreDestroy(&(thread_self->resumeAck));
        _ILWakeupQueueDestroy(&(thread_self->joinQueue));
+       /* Deinitialize the implementation specific thread members */
+       #ifdef _ILTHREAD_EXT_DEINIT
+               _IL_THREAD_EXT_DEINIT(thread_self);
+       #endif
+       _ILCriticalSectionDestroy(&(thread_self->lock));
 
        _ILThreadSetSelf(0);
        /* Release the handle */
@@ -312,11 +332,21 @@ void *ILThreadRunSelf(void *(* thread_func)(void *), void 
*arg)
 
 void _ILThreadRun(ILThread *thread)
 {
+       _ILThreadState threadState;
+       
        /* When a thread starts, it blocks until the ILThreadStart function
           has finished setup */
        /* Wait until the starting thread has released the lock */
-       _ILMutexLock(&(thread->lock));
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionEnter(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
+
+       /* Initialize the implementation specific thread members */
+       #ifdef _ILTHREAD_EXT_INIT
+               _IL_THREAD_EXT_INIT(thread);
+       #endif
+
+       /* Mark the thread as running */
+       ILInterlockedStoreU2(&(thread->state.split.priv), IL_TS_RUNNING);
 
        /* If we still have a startup function, then execute it.
           The field may have been replaced with NULL if the thread
@@ -328,38 +358,34 @@ void _ILThreadRun(ILThread *thread)
 
        thread->startArg = 0;
        
-       _ILMutexLock(&(thread->lock));
-       {
-               ILUInt16 threadState;
-
-               threadState = ILInterlockedLoadU2(&(thread->state));
-
-               /* Mark the thread as stopped */
-               threadState |= IL_TS_STOPPED;
-               ILInterlockedStoreU2(&(thread->state), threadState);
-               /* Change the thread count */
-               _ILThreadAdjustCount(-1, ((threadState & IL_TS_BACKGROUND) != 
0) ? -1 : 0);
-       }
-       _ILMutexUnlock(&(thread->lock));
-
        /* Run and free the cleanup handlers */
        _ILThreadRunAndFreeCleanups(thread);
        
-       _ILMutexLock(&(thread->lock));
-       {               
+       /* Mark the thread as stopped */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       threadState.split.priv |= IL_TS_STOPPED;
+       ILInterlockedStoreU2(&(thread->state.split.priv), 
threadState.split.priv);
+
+       /* Change the thread count */
+       _ILThreadAdjustCount(-1, ((threadState.split.pub & IL_TS_BACKGROUND) != 
0) ? -1 : 0);
+
+       _ILCriticalSectionEnter(&(thread->lock));
+       {
                /* Wakeup everyone waiting to join */
                _ILWakeupQueueWakeAll(&(thread->joinQueue));
        }
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
 
        /* The wakeup isn't needed anymore so destroy it now to allow
           held mutexes to be released */
        _ILWakeupDestroy(&(thread->wakeup));
 
-       if (thread->destroyOnExit)
-       {
-               _ILPrivateThreadDestroy(thread, 1);
-       }
+       /* Deinitialize the implementation specific thread members */
+       #ifdef _ILTHREAD_EXT_DEINIT
+               _IL_THREAD_EXT_DEINIT(thread);
+       #endif
+
+       _ILPrivateThreadDestroy(thread);
 }
 
 ILThread *ILThreadCreate(ILThreadStartFunc startFunc, void *startArg)
@@ -371,33 +397,26 @@ ILThread *ILThreadCreate(ILThreadStartFunc startFunc, 
void *startArg)
        {
                return 0;
        }
-       /* Create a new thread object and populate it */
+       /*
+        * Create a new thread object and populate it.
+        * All members are guaranteed to be initialized to 0 after this point.
+        */
        thread = (ILThread *)ILCalloc(1, sizeof(ILThread));
        if(!thread)
        {
                return 0;
        }
 
-       _ILMutexCreate(&(thread->lock));        
-       thread->state = IL_TS_UNSTARTED;
-       thread->resumeRequested = 0;
-       thread->suspendRequested = 0;
-       thread->numLocksHeld = 0;
-       thread->firstCleanupEntry = 0;
-       thread->lastCleanupEntry = 0;
+       _ILCriticalSectionCreate(&(thread->lock));
+       thread->state.split.pub = IL_TS_UNSTARTED;
        thread->monitor = ILWaitMonitorCreate();
        _ILSemaphoreCreate(&(thread->resumeAck));
        _ILSemaphoreCreate(&(thread->suspendAck));
        thread->startFunc = startFunc;
-       thread->userObject = 0;
        thread->startArg = startArg;
        _ILWakeupCreate(&(thread->wakeup));
        _ILWakeupQueueCreate(&(thread->joinQueue));
-       thread->handle = 0;
-       thread->destroyOnExit = 0;
-       #ifdef IL_INTERRUPT_SUPPORTS
-               thread->interruptHandler = 0;
-       #endif
+       thread->useCount = 1;   /* 1 here because the handle will be returned */
 
        /* Make sure everything setup is seen by all threads. */
        ILInterlockedMemoryBarrier();
@@ -407,43 +426,57 @@ ILThread *ILThreadCreate(ILThreadStartFunc startFunc, 
void *startArg)
 
 int ILThreadStart(ILThread *thread)
 {
-       int result;
-       ILUInt16 threadState;
-
-       /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
-
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       _ILThreadState threadState;
 
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
        /* Are we in the correct state to start? */
-       if((threadState & IL_TS_UNSTARTED) != 0)
+       if((threadState.split.pub & IL_TS_UNSTARTED) != 0)
        {
-               /* Create the new thread */
-               if(!_ILThreadCreateSystem(thread))
+               int result;
+               
+               /* Lock down the thread object */
+               _ILCriticalSectionEnter(&(thread->lock));
+
+               /* reread the thread's state because of possible race 
conditions */
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+
+               /* And check again with the lock held */
+               if((threadState.split.pub & IL_TS_UNSTARTED) != 0)
                {
-                       result = 0;
+                       /* Create the new thread */
+                       if(!_ILThreadCreateSystem(thread))
+                       {
+                               result = 0;
+                       }
+                       else
+                       {
+                               int isBackground;
+
+                               /* Increment the use count because the thread 
is started now */
+                               thread->useCount += 1;
+                               
+                               /* Clear the thread's unstarted flag */
+                               threadState.split.pub &= ~IL_TS_UNSTARTED;
+                               
+                               ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                        
threadState.split.pub);
+
+                               isBackground = ((threadState.split.pub & 
IL_TS_BACKGROUND) != 0);
+                               _ILThreadAdjustCount(1, isBackground ? 1 : 0);
+
+                               result = 1;
+                       }
                }
                else
                {
-                       /* Set the thread state to running (0) */
-                       threadState &= ~IL_TS_UNSTARTED;
-                       threadState |= IL_TS_RUNNING;
-                       ILInterlockedStoreU2(&(thread->state), threadState);
-
-                       _ILThreadAdjustCount(1, (threadState & 
IL_TS_BACKGROUND) ? 1 : 0);
-
-                       result = 1;
+                       result = 0;
                }
-       }
-       else
-       {
-               result = 0;
-       }
+               /* Unlock the thread object and return */
+               _ILCriticalSectionLeave(&(thread->lock));
 
-       /* Unlock the thread object and return */
-       _ILMutexUnlock(&(thread->lock));
-
-       return result;
+               return result;
+       }
+       return 0;
 }
 
 ILThread *ILThreadSelf(void)
@@ -472,46 +505,50 @@ int ILThreadSuspend(ILThread *thread)
 
 int ILThreadSuspendRequest(ILThread *thread, int requestOnly)
 {
-       ILUInt16 threadState;
+       _ILThreadState threadState;
        int result = IL_SUSPEND_OK;
 
        /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
+       _ILCriticalSectionEnter(&(thread->lock));
 
        /* Determine what to do based on the thread's state */
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & (IL_TS_ABORT_REQUESTED)) != 0)
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.pub & (IL_TS_ABORT_REQUESTED)) != 0)
        {
                result = IL_WAIT_ABORTED;
        }
-       else if((threadState & IL_TS_SUSPENDED) != 0)
+       else if((threadState.split.pub & IL_TS_SUSPENDED) != 0)
        {
                /* Nothing to do here - it is already suspended */
        }
-       else if((threadState & (IL_TS_UNSTARTED | IL_TS_STOPPED)) != 0)
+       else if(((threadState.split.pub & IL_TS_UNSTARTED) != 0) ||
+                        ((threadState.split.priv &  IL_TS_STOPPED) != 0))
        {
                /* We cannot suspend a thread that was never started
                   in the first place, or is stopped */
                result = IL_SUSPEND_FAILED;
        }
-       else if(((threadState & IL_TS_WAIT_SLEEP_JOIN) != 0) || requestOnly)
+       else if(((threadState.split.priv & IL_TS_WAIT_SLEEP_JOIN) != 0) ||
+                       requestOnly)
        {
                /* Request a suspend, but otherwise ignore the request */
-               threadState |= IL_TS_SUSPEND_REQUESTED;
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               threadState.split.pub |= IL_TS_SUSPEND_REQUESTED;
+               ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                        threadState.split.pub);
 
                result = IL_SUSPEND_REQUESTED;
        }
        else if(_ILThreadIsSelf(thread))
        {
                /* Mark the thread as suspended */
-               threadState &= ~ IL_TS_SUSPEND_REQUESTED;
-               threadState |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               threadState.split.pub &= ~ IL_TS_SUSPEND_REQUESTED;
+               threadState.split.pub |= (IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF);
+               ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                        threadState.split.pub);
                thread->resumeRequested = 0;
 
                /* Unlock the thread object prior to suspending */
-               _ILMutexUnlock(&(thread->lock));
+               _ILCriticalSectionLeave(&(thread->lock));
 
                /* Suspend until we receive notification from another thread */
                _ILThreadSuspendSelf(thread);
@@ -521,9 +558,10 @@ int ILThreadSuspendRequest(ILThread *thread, int 
requestOnly)
        }
        else
        {
-               /* Mark the thread as suspended and waiting for a resume */
-               threadState |= IL_TS_SUSPENDED;
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               /* Mark the thread as waiting for a resume */
+               threadState.split.pub |= IL_TS_SUSPENDED;
+               ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                        threadState.split.pub);
                thread->resumeRequested = 0;
 
                /* Put the thread to sleep temporarily */
@@ -532,7 +570,7 @@ int ILThreadSuspendRequest(ILThread *thread, int 
requestOnly)
                /* If the thread does not hold any locks, then everything is OK 
*/
                if(!(thread->numLocksHeld))
                {
-                       _ILMutexUnlock(&(thread->lock));
+                       _ILCriticalSectionLeave(&(thread->lock));
                        return IL_SUSPEND_OK;
                }
 
@@ -544,120 +582,143 @@ int ILThreadSuspendRequest(ILThread *thread, int 
requestOnly)
 
                /* Give up the lock on the thread, but don't reduce
                   "numLocksHeld" on the current thread just yet */
-               _ILMutexUnlockUnsafe(&(thread->lock));
+               _ILCriticalSectionLeaveUnsafe(&(thread->lock));
 
                /* Wait for the thread to signal us that it has put itself to 
sleep */
                _ILSemaphoreWait(&(thread->suspendAck));
 
                /* Re-acquire the lock on the thread object */
-               _ILMutexLockUnsafe(&(thread->lock));
+               _ILCriticalSectionEnterUnsafe(&(thread->lock));
        }
 
        /* Unlock the thread object and return */
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
        return result;
 }
 
 void ILThreadResume(ILThread *thread)
 {
-       ILUInt16 threadState;
+       _ILThreadState threadState;
 
        /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
+       _ILCriticalSectionEnter(&(thread->lock));
 
        /* Determine what to do based on the thread's state */
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & IL_TS_SUSPENDED) != 0)
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.pub & IL_TS_SUSPENDED) != 0)
        {
-               if((threadState & IL_TS_SUSPENDED_SELF) != 0)
+               if((threadState.split.pub & IL_TS_SUSPENDED_SELF) != 0)
                {
                        /* The thread put itself to sleep */
-                       threadState &= ~(IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF);
-                       threadState |= IL_TS_RUNNING;
-                       ILInterlockedStoreU2(&(thread->state), threadState);
+                       threadState.split.pub &= ~(IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF);
+                       threadState.split.pub |= IL_TS_RUNNING;
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
                        _ILThreadResumeSelf(thread);
                }
                else
                {
                        /* Someone else suspended the thread */
-                       threadState &= ~IL_TS_SUSPENDED;
-                       threadState |= IL_TS_RUNNING;
-                       ILInterlockedStoreU2(&(thread->state), threadState);
+                       threadState.split.pub &= ~IL_TS_SUSPENDED;
+                       threadState.split.pub |= IL_TS_RUNNING;
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
                        _ILThreadResumeOther(thread);
                }
        }
-       else if((threadState & IL_TS_SUSPEND_REQUESTED) != 0)
+       else if((threadState.split.pub & IL_TS_SUSPEND_REQUESTED) != 0)
        {
                /* A suspend was requested, but it hadn't started yet */
-               threadState &= ~IL_TS_SUSPEND_REQUESTED;
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               threadState.split.pub &= ~IL_TS_SUSPEND_REQUESTED;
+               ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                        threadState.split.pub);
        }
 
        /* Unlock the thread object */
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
 }
 
 void ILThreadInterrupt(ILThread *thread)
 {
-       ILUInt16 threadState;
-
-       /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
+       _ILThreadState threadState;
 
        /* Determine what to do based on the thread's state */
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & IL_TS_STOPPED) == 0)
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.priv & IL_TS_STOPPED) == 0)
        {
-               /* Mark the thread as interrupted */
-               threadState |= IL_TS_INTERRUPTED;
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               /* Lock down the thread object */
+               _ILCriticalSectionEnter(&(thread->lock));
 
-               /* Unlock the thread object: we never hold the thread
-                  lock when updating the thread's wakeup object */
-               _ILMutexUnlock(&(thread->lock));
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+               if(((threadState.split.pub & IL_TS_UNSTARTED) == 0) &&
+                  ((threadState.split.priv & IL_TS_STOPPED) == 0))
+               {
+                       /* Mark the thread as interrupted */
+                       threadState.split.pub |= IL_TS_INTERRUPTED;
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
 
-               /* Mark the thread as needing to be interrupted the next
-                  time a "wait/sleep/join" occurs */
-               _ILWakeupInterrupt(&(thread->wakeup));
-       }
-       else
-       {
-               /* Unlock the thread object */
-               _ILMutexUnlock(&(thread->lock));
+                       /* Unlock the thread object: we never hold the thread
+                          lock when updating the thread's wakeup object */
+                       _ILCriticalSectionLeave(&(thread->lock));
+
+                       /* Mark the thread as needing to be interrupted the next
+                          time a "wait/sleep/join" occurs */
+                       _ILWakeupInterrupt(&(thread->wakeup));
+
+                       /* post the interrupt request to the thread */
+                       _ILThreadInterrupt(thread);
+               }
+               else
+               {
+                       /* Unlock the thread object */
+                       _ILCriticalSectionLeave(&(thread->lock));
+               }
        }
 }
 
 int ILThreadSelfAborting()
 {
        int result;
-       ILUInt16 threadState;
+       _ILThreadState threadState;
        ILThread *thread = _ILThreadGetSelf();
        
-       _ILMutexLock(&(thread->lock));
-       
        /* Determine if we've already seen the abort request or not */
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & IL_TS_ABORTED) != 0)
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.priv & IL_TS_ABORTED) != 0)
        {
                /* Already aborted */
                result = 0;
        }
-       else if((threadState & IL_TS_ABORT_REQUESTED) != 0)
+       else if((threadState.split.pub & IL_TS_ABORT_REQUESTED) != 0)
        {
                /* Abort was requested */
-               threadState &= ~IL_TS_ABORT_REQUESTED;
-               threadState |= IL_TS_ABORTED;
-               ILInterlockedStoreU2(&(thread->state), threadState);
-               result = 1;
+               _ILCriticalSectionEnter(&(thread->lock));
+       
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+               if((threadState.split.pub & IL_TS_ABORT_REQUESTED) != 0)
+               {
+                       threadState.split.pub &= ~IL_TS_ABORT_REQUESTED;
+                       threadState.split.priv |= IL_TS_ABORTED;
+                       ILInterlockedStoreU4(&(thread->state.comb), 
threadState.comb);
+                       result = 1;
+               }
+               else
+               {
+                       /*
+                        * This possibly can never happen because only the 
current thread
+                        * can change the abort request state once it has been 
set by an
+                        * other thread or the thread itself.
+                        */
+                       result = 0;
+               }
+               _ILCriticalSectionLeave(&(thread->lock));
        }
        else
        {
                /* The thread is not aborting: we were called in error */
                result = 0;
        }
-       
-       _ILMutexUnlock(&(thread->lock));
-       
        return result;
 }
 
@@ -674,14 +735,14 @@ void ILThreadSigAbort(ILThread *thread)
 int ILThreadAbort(ILThread *thread)
 {
        int result;
-       ILUInt16 threadState;
+       _ILThreadState threadState;
 
        /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
+       _ILCriticalSectionEnter(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
-
-       if((threadState & (IL_TS_ABORTED | IL_TS_ABORT_REQUESTED)) != 0)
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.priv & IL_TS_ABORTED) ||
+          (threadState.split.pub & IL_TS_ABORT_REQUESTED))
        {
                /* The thread is already processing an abort or an abort 
request */
                result = 0;
@@ -689,38 +750,48 @@ int ILThreadAbort(ILThread *thread)
        else
        {
                /* Mark the thread as needing to be aborted */
-               threadState |= IL_TS_ABORT_REQUESTED;
+               threadState.split.pub |= IL_TS_ABORT_REQUESTED;
+               ILInterlockedStoreU2_Acquire(&(thread->state.split.pub),
+                                                                        
threadState.split.pub);
+
+               /* And reload the thread state */
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
 
-               /* If the thread is in the "wait/sleep/join" state, then 
interrupt it */
-               if((threadState & IL_TS_WAIT_SLEEP_JOIN) != 0)
+               if (((threadState.split.pub & (IL_TS_SUSPENDED_SELF | 
IL_TS_SUSPENDED))) != 0)
                {
-                       ILInterlockedStoreU2(&(thread->state), threadState);
+                       _ILCriticalSectionLeave(&(thread->lock));
+
+                       ILThreadResume(thread);
 
+                       return 0;
+               }
+               else if((threadState.split.priv & IL_TS_WAIT_SLEEP_JOIN) != 0)
+               {
                        /* Unlock the thread object: we never hold the thread
                           lock when updating the thread's wakeup object */
-                       _ILMutexUnlock(&(thread->lock));
+                       _ILCriticalSectionLeave(&(thread->lock));
 
                        _ILWakeupInterrupt(&(thread->wakeup));
+                       
+                       _ILThreadInterrupt(thread);
 
                        return 0;
                }
-               else if (((threadState & (IL_TS_SUSPENDED_SELF | 
IL_TS_SUSPENDED))) != 0)
+               else
                {
-                       ILInterlockedStoreU2(&(thread->state), threadState);
-
-                       _ILMutexUnlock(&(thread->lock));
-
-                       ILThreadResume(thread);
-
-                       return 0;
+                       /* No need to abort the current thread ?? */
+                       /* Really ?
+                       threadState.split.pub &= ~IL_TS_ABORT_REQUESTED;
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
+                       */
                }
-
-               /* No need to abort the current thread */
+               /* No need to interrupt or resume the current thread */
                result = 0;
        }
 
        /* Unlock the thread object and return */
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
        return result;
 }
 
@@ -729,9 +800,9 @@ int ILThreadIsAborting(void)
        ILThread *thread = _ILThreadGetSelf();
        ILUInt16 threadState;
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       threadState = ILInterlockedLoadU2(&(thread->state.split.priv));
        /* Determine if an abort is in progress on this thread */
-       return ((threadState & (IL_TS_ABORTED)) != 0);
+       return ((threadState & IL_TS_ABORTED) != 0);
 }
 
 int ILThreadIsAbortRequested(void)
@@ -739,28 +810,28 @@ int ILThreadIsAbortRequested(void)
        ILThread *thread = _ILThreadGetSelf();
        ILUInt16 threadState;
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       /* Determine if an abort is in progress on this thread */
-       return ((threadState & (IL_TS_ABORT_REQUESTED)) != 0);
+       threadState = ILInterlockedLoadU2(&(thread->state.split.pub));
+       return ((threadState & IL_TS_ABORT_REQUESTED) != 0);
 }
 
 int ILThreadAbortReset(void)
 {
        ILThread *thread = _ILThreadGetSelf();
        int result;
-       ILUInt16 threadState;
+       _ILThreadState threadState;
 
        /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
+       _ILCriticalSectionEnter(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
 
        /* Reset the "abort" and "abort requested" flags */
-       if((threadState & (IL_TS_ABORTED | IL_TS_ABORT_REQUESTED)) != 0)
+       if((threadState.split.priv & IL_TS_ABORTED) ||
+          (threadState.split.pub & IL_TS_ABORT_REQUESTED))
        {
-               threadState &= ~(IL_TS_ABORTED | IL_TS_ABORT_REQUESTED);
-               threadState &= ~(IL_TS_INTERRUPTED);
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               threadState.split.priv &= ~IL_TS_ABORTED;
+               threadState.split.pub &= ~(IL_TS_ABORT_REQUESTED | 
IL_TS_INTERRUPTED);
+               ILInterlockedStoreU4(&(thread->state.comb), threadState.comb);
 
                _ILWakeupCancelInterrupt(&thread->wakeup);
 
@@ -772,7 +843,7 @@ int ILThreadAbortReset(void)
        }
 
        /* Unlock the thread object and return */
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
        return result;
 }
 
@@ -780,7 +851,7 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
 {
        ILThread *self = _ILThreadGetSelf();
        int result;
-       ILUInt16 threadState;
+       _ILThreadState threadState;
 
        /* Bail out if we are trying to join with ourselves */
        if(self == thread)
@@ -789,17 +860,17 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
        }
 
        /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
+       _ILCriticalSectionEnter(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
 
        /* Determine what to do based on the thread's state */
-       if((threadState & IL_TS_STOPPED) != 0)
+       if((threadState.split.priv & IL_TS_STOPPED) != 0)
        {
                /* The thread is already stopped, so return immediately */
                result = IL_JOIN_OK;
        }
-       else if ((threadState & IL_TS_UNSTARTED) != 0)
+       else if ((threadState.split.pub & IL_TS_UNSTARTED) != 0)
        {
                /* Can't join a thread that hasn't started */
                result = IL_JOIN_UNSTARTED;
@@ -827,26 +898,26 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
                        }
                        else
                        {
-                               ILUInt16 selfState;
+                               _ILThreadState selfState;
 
                                /* Unlock the foreign thread */
-                               _ILMutexUnlock(&(thread->lock));
+                               _ILCriticalSectionLeave(&(thread->lock));
 
                                /* Put ourselves into the "wait/sleep/join" 
state */
-                               _ILMutexLock(&(self->lock));
-                               selfState = ILInterlockedLoadU2(&(self->state));
-                               if((selfState & (IL_TS_ABORT_REQUESTED)) != 0)
+                               _ILCriticalSectionEnter(&(self->lock));
+                               selfState.comb = 
ILInterlockedLoadU4(&(self->state.comb));
+                               if((selfState.split.pub & 
IL_TS_ABORT_REQUESTED) != 0)
                                {
                                        /* The current thread is aborted */
-                                       _ILMutexUnlock(&(self->lock));
-                                       _ILMutexLock(&(thread->lock));
+                                       _ILCriticalSectionLeave(&(self->lock));
+                                       
_ILCriticalSectionEnter(&(thread->lock));
                                        
_ILWakeupQueueRemove(&(thread->joinQueue), &(self->wakeup));
-                                       _ILMutexUnlock(&(thread->lock));
+                                       
_ILCriticalSectionLeave(&(thread->lock));
                                        return IL_JOIN_ABORTED;
                                }
-                               selfState |= IL_TS_WAIT_SLEEP_JOIN;
-                               ILInterlockedStoreU2(&(self->state), selfState);
-                               _ILMutexUnlock(&(self->lock));
+                               selfState.split.priv |= IL_TS_WAIT_SLEEP_JOIN;
+                               ILInterlockedStoreU2(&(self->state.split.priv), 
selfState.split.priv);
+                               _ILCriticalSectionLeave(&(self->lock));
 
                                result = _ILWakeupWait(&(self->wakeup), ms, 
(void **)0);
                                
@@ -868,29 +939,31 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
 
                                /* Remove ourselves from the "wait/sleep/join" 
state,
                                and check for a pending interrupt */
-                               _ILMutexLock(&(self->lock));
+                               _ILCriticalSectionEnter(&(self->lock));
 
-                               selfState = ILInterlockedLoadU2(&(self->state));
-                               if((selfState & IL_TS_INTERRUPTED) != 0)
+                               selfState.comb = 
ILInterlockedLoadU4(&(self->state.comb));
+                               if((selfState.split.pub & IL_TS_INTERRUPTED) != 
0)
                                {
                                        result = IL_JOIN_INTERRUPTED;
                                }
-                               selfState &= ~(IL_TS_WAIT_SLEEP_JOIN | 
IL_TS_INTERRUPTED);
-                               ILInterlockedStoreU2(&(self->state), selfState);
+                               selfState.split.priv &= ~IL_TS_WAIT_SLEEP_JOIN;
+                               selfState.split.pub &= ~IL_TS_INTERRUPTED;
+                               ILInterlockedStoreU4(&(self->state.comb), 
selfState.comb);
                                /* Check and process any pending suspend 
request */
-                               threadState = 
ILInterlockedLoadU2(&(thread->state));
-                               if ((threadState & IL_TS_SUSPEND_REQUESTED) != 
0)
+                               threadState.comb = 
ILInterlockedLoadU4(&(thread->state.comb));
+                               if ((threadState.split.pub & 
IL_TS_SUSPEND_REQUESTED) != 0)
                                {
                                        /* Unlock the thread object prior to 
suspending */
-                                       _ILMutexUnlock(&(self->lock));
+                                       _ILCriticalSectionLeave(&(self->lock));
 
                                        /* Lock down the foreign thread again */
-                                       _ILMutexLock(&(thread->lock));
+                                       
_ILCriticalSectionEnter(&(thread->lock));
 
-                                       threadState = 
ILInterlockedLoadU2(&(thread->state));
-                                       threadState &= ~IL_TS_SUSPEND_REQUESTED;
-                                       threadState |= IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF;
-                                       ILInterlockedStoreU2(&(thread->state), 
threadState);
+                                       threadState.comb = 
ILInterlockedLoadU4(&(thread->state.comb));
+                                       threadState.split.pub &= 
~IL_TS_SUSPEND_REQUESTED;
+                                       threadState.split.pub |= 
(IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF);
+                                       
ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                               
 threadState.split.pub);
                                        thread->resumeRequested = 0;
 
                                        /* Remove ourselves from the foreign 
thread's join queue */
@@ -901,10 +974,10 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
                                }
                                else
                                {
-                                       _ILMutexUnlock(&(self->lock));
+                                       _ILCriticalSectionLeave(&(self->lock));
 
                                        /* Lock down the foreign thread again */
-                                       _ILMutexLock(&(thread->lock));
+                                       
_ILCriticalSectionEnter(&(thread->lock));
 
                                        /* Remove ourselves from the foreign 
thread's join queue */
                                        
_ILWakeupQueueRemove(&(thread->joinQueue), &(self->wakeup));
@@ -914,7 +987,7 @@ int ILThreadJoin(ILThread *thread, ILUInt32 ms)
        }
 
        /* Unlock the thread object and return */
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
        return result;
 }
 
@@ -922,7 +995,7 @@ int ILThreadGetBackground(ILThread *thread)
 {
        ILUInt16 threadState;
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       threadState = ILInterlockedLoadU2(&(thread->state.split.pub));
        /* Determine if this is a background thread */
        return ((threadState & IL_TS_BACKGROUND) != 0);
 }
@@ -930,22 +1003,24 @@ int ILThreadGetBackground(ILThread *thread)
 void ILThreadSetBackground(ILThread *thread, int flag)
 {
        int change = 0;
-       ILUInt16 threadState;
+       _ILThreadState threadState;
 
        /* Lock down the thread object */
-       _ILMutexLock(&(thread->lock));
+       _ILCriticalSectionEnter(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
 
        /* Change the background state of the thread */
        if(flag)
        {
-               if(!(threadState & IL_TS_BACKGROUND))
+               if(!(threadState.split.pub & IL_TS_BACKGROUND))
                {
-                       threadState |= IL_TS_BACKGROUND;
-                       ILInterlockedStoreU2(&(thread->state), threadState);
+                       threadState.split.pub |= IL_TS_BACKGROUND;
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
 
-                       if(!(threadState & (IL_TS_UNSTARTED | IL_TS_STOPPED)))
+                       if(!(threadState.split.pub & IL_TS_UNSTARTED) && 
+                          !(threadState.split.priv & IL_TS_STOPPED))
                        {
                                _ILThreadAdjustCount(0, 1);
                        }
@@ -953,13 +1028,15 @@ void ILThreadSetBackground(ILThread *thread, int flag)
        }
        else
        {
-               if((threadState & IL_TS_BACKGROUND))
+               if((threadState.split.pub & IL_TS_BACKGROUND))
                {
-                       threadState &= ~IL_TS_BACKGROUND;
-                       ILInterlockedStoreU2(&(thread->state), threadState);
+                       threadState.split.pub &= ~IL_TS_BACKGROUND;
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
                        change = -1;
 
-                       if(!(threadState & (IL_TS_UNSTARTED | IL_TS_STOPPED)))
+                       if(!(threadState.split.pub & IL_TS_UNSTARTED) && 
+                          !(threadState.split.priv & IL_TS_STOPPED))
                        {
                                _ILThreadAdjustCount(0, -1);
                        }
@@ -967,27 +1044,26 @@ void ILThreadSetBackground(ILThread *thread, int flag)
        }
 
        /* Unlock the thread object */
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
 }
 
 int ILThreadGetState(ILThread *thread)
 {
-       ILUInt16 threadState;
+       _ILThreadState threadState;
 
-       /* Retrieve the current thread state */
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
        /* Return the publicly-interesting flags to the caller */
-       return (int)(threadState & IL_TS_PUBLIC_FLAGS);
+       return (int)((threadState.split.priv | threadState.split.pub) & 
IL_TS_PUBLIC_FLAGS);
 }
 
 void ILThreadAtomicStart(void)
 {
-       _ILMutexLock(&atomicLock);
+       _ILCriticalSectionEnter(&atomicLock);
 }
 
 void ILThreadAtomicEnd(void)
 {
-       _ILMutexUnlock(&atomicLock);
+       _ILCriticalSectionLeave(&atomicLock);
 }
 
 void ILThreadMemoryBarrier(void)
@@ -995,13 +1071,18 @@ void ILThreadMemoryBarrier(void)
        ILInterlockedMemoryBarrier();
 }
 
+long _ILThreadGetNumThreads()
+{
+       return numThreads;
+}
+
 void ILThreadGetCounts(unsigned long *numForeground,
                                           unsigned long *numBackground)
 {
-       _ILMutexLock(&threadLockAll);
+       _ILCriticalSectionEnter(&threadLockAll);
        *numForeground = (unsigned long)(numThreads - numBackgroundThreads);
        *numBackground = (unsigned long)(numBackgroundThreads);
-       _ILMutexUnlock(&threadLockAll);
+       _ILCriticalSectionLeave(&threadLockAll);
 }
 
 void ILThreadYield()
@@ -1009,97 +1090,129 @@ void ILThreadYield()
        _ILThreadYield();
 }
 
-int ILThreadSleep(ILUInt32 ms)
+/*
+ * Enter the "wait/sleep/join" state on the current thread.
+ */
+int _ILThreadEnterWaitState(ILThread *thread)
 {
-       ILThread *thread = _ILThreadGetSelf();
-       int result;
-       ILUInt16 threadState;
-
-       /* Lock down the thread */
-       _ILMutexLock(&(thread->lock));
+       int result = IL_THREAD_OK;
+       _ILThreadState threadState;
+
+       /*
+        * Set the wait/sleep/join state so that it will be seen by a possible
+        * call to ILThreadAbort by an other thread.
+        */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       threadState.split.priv |= IL_TS_WAIT_SLEEP_JOIN;
+       ILInterlockedStoreU2_Acquire(&(thread->state.split.priv),
+                                                                
threadState.split.priv);
+       /* Requery the thread state */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.pub & IL_TS_ABORT_REQUESTED) != 0)
+       {
+               _ILCriticalSectionEnter(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+               if((threadState.split.pub & (IL_TS_ABORT_REQUESTED | 
IL_TS_INTERRUPTED)) != 0)
+               {
+                       /* Clear the wait/sleep/join state and interrupted flag 
*/
+                       threadState.split.priv |= IL_TS_WAIT_SLEEP_JOIN;
+                       threadState.split.pub &= ~(IL_TS_INTERRUPTED);
+                       ILInterlockedStoreU4(&(thread->state.comb), 
threadState.comb);
 
-       /* Bail out if the current thread is aborted or interrupted */
-       if(threadState & (IL_TS_ABORT_REQUESTED))
-       {
-               _ILMutexUnlock(&(thread->lock));
-               
-               return IL_WAIT_ABORTED;
+                       result = IL_THREAD_ERR_ABORTED;
+               }
+               _ILCriticalSectionLeave(&(thread->lock));
        }
-       else if (threadState & IL_TS_INTERRUPTED)
-       {
-               threadState &= ~(IL_TS_INTERRUPTED);
-               ILInterlockedStoreU2(&(thread->state), threadState);
 
-               _ILMutexUnlock(&(thread->lock));
+       return result;
+}
 
-               return IL_WAIT_INTERRUPTED;
-       }
+/*
+ * Leave the "wait/sleep/join" state on the current thread.
+ */
+int _ILThreadLeaveWaitState(ILThread *thread, int result)
+{
+       _ILThreadState threadState;
+
+       /*
+        * Clear the wait/sleep/join flag before checking for possible 
interrupt,
+        * abort or suspend requests.
+        */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       threadState.split.priv &= ~IL_TS_WAIT_SLEEP_JOIN;
+       ILInterlockedStoreU2_Acquire(&(thread->state.split.priv),
+                                                                
threadState.split.priv);
+       /* And requery the thread state */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.pub & (IL_TS_ABORT_REQUESTED |
+                                                                
IL_TS_INTERRUPTED |
+                                                                
IL_TS_SUSPEND_REQUESTED)) != 0)
+       {
+               _ILCriticalSectionEnter(&(thread->lock));
 
-       /* Put the thread into the "wait/sleep/join" state */
-       threadState |= IL_TS_WAIT_SLEEP_JOIN;
-       ILInterlockedStoreU2(&(thread->state), threadState);
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       
+               /* Abort has more priority over interrupt */
+               if((threadState.split.pub & (IL_TS_ABORT_REQUESTED)) != 0)
+               {
+                       threadState.split.pub &= ~(IL_TS_INTERRUPTED);
+                       _ILWakeupCancelInterrupt(&(thread->wakeup));
+                       result = IL_THREAD_ERR_ABORTED;
+               }
+               else if((threadState.split.pub & IL_TS_INTERRUPTED) != 0)
+               {
+                       threadState.split.pub &= ~(IL_TS_INTERRUPTED);
+                       _ILWakeupCancelInterrupt(&(thread->wakeup));
+                       result = IL_THREAD_ERR_INTERRUPT;
+               }
 
-       /* Unlock the thread to allow others to access it */
-       _ILMutexUnlock(&(thread->lock));
+               if((threadState.split.pub & IL_TS_SUSPEND_REQUESTED) != 0)
+               {
+                       threadState.split.pub &= ~IL_TS_SUSPEND_REQUESTED;
+                       threadState.split.pub |= (IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF);
+                       thread->resumeRequested = 0;
 
-       /* Wait on the thread's wakeup object, which will never be signalled,
-          but which may be interrupted or aborted by some other thread */
-       if(_ILWakeupSetLimit(&(thread->wakeup), 1))
-       {
-               result = (_ILWakeupWait(&(thread->wakeup), ms, (void **)0) >= 
0);
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
                
-               if (result == 0)
+                       /* Unlock the thread object prior to suspending */
+                       _ILCriticalSectionLeave(&(thread->lock));
+
+                       /* Suspend until we receive notification from another 
thread */
+                       _ILThreadSuspendSelf(thread);
+               }
+               else
                {
-                       result = IL_WAIT_TIMEOUT;
+                       ILInterlockedStoreU2(&(thread->state.split.pub),
+                                                                
threadState.split.pub);
+                       _ILCriticalSectionLeave(&(thread->lock));
                }
+               return result;
        }
-       else
-       {
-               
-               result = IL_WAIT_TIMEOUT;
-       }
-
-       /* Lock down the thread again */
-       _ILMutexLock(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if(threadState & (IL_TS_ABORT_REQUESTED))
-       {
-               result = IL_WAIT_ABORTED;
-       }
-       else if(threadState & IL_TS_INTERRUPTED)
-       {
-               result = IL_WAIT_INTERRUPTED;
-       }
+       return result;
+}
 
-       /* Exit from the "wait/sleep/join" and "interrupted" states */
-       threadState &= ~(IL_TS_WAIT_SLEEP_JOIN | IL_TS_INTERRUPTED);
+int ILThreadSleep(ILUInt32 ms)
+{
+       ILThread *thread = _ILThreadGetSelf();
+       int result;
+       int waitStateResult;
 
-       /* Did someone else ask us to suspend? */
-       if((threadState & IL_TS_SUSPEND_REQUESTED) != 0)
+       if((result = _ILThreadEnterWaitState(thread)) != IL_THREAD_OK)
        {
-               /* Suspend the current thread */
-               threadState &= ~IL_TS_SUSPEND_REQUESTED;
-               threadState |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
-               ILInterlockedStoreU2(&(thread->state), threadState);
-               thread->resumeRequested = 0;
-
-               /* Unlock the thread object prior to suspending */
-               _ILMutexUnlock(&(thread->lock));
-
-               /* Suspend until we receive notification from another thread */
-               _ILThreadSuspendSelf(thread);
-
-               /* We are resumed, and the thread object is already unlocked */
+               fprintf(stderr, "ILThreadSleep(%i) enterwaitstate failed with 
result = %i\n", ms, result);
                return result;
        }
 
-       ILInterlockedStoreU2(&(thread->state), threadState);
+       result = _ILThreadSleep(ms);
 
-       /* Unlock the thread and exit */
-       _ILMutexUnlock(&(thread->lock));
+       waitStateResult = _ILThreadLeaveWaitState(thread, result);
+       if(waitStateResult != IL_THREAD_OK)
+       {
+               result = waitStateResult;
+       }
        return result;
 }
 
@@ -1115,16 +1228,20 @@ void ILThreadWaitForForegroundThreads(int timeout)
 int ILThreadRegisterCleanup(ILThread *thread, ILThreadCleanupFunc func)
 {
        ILThreadCleanupEntry *entry;
-       ILUInt16 threadState;
-       
-       _ILMutexLock(&(thread->lock));
+       _ILThreadState threadState;
+
+       IL_THREAD_ASSERT((thread->state.split.pub & IL_TS_UNSTARTED) ||
+                                        (thread == _ILThreadGetSelf()));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & IL_TS_STOPPED))
+       /* Lock down the thread */
+       _ILCriticalSectionEnter(&(thread->lock));
+       
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.priv & IL_TS_STOPPED))
        {
                /* Thread has stopped */
 
-               _ILMutexUnlock(&(thread->lock));
+               _ILCriticalSectionLeave(&(thread->lock));
 
                return -1;
        }
@@ -1137,7 +1254,7 @@ int ILThreadRegisterCleanup(ILThread *thread, 
ILThreadCleanupFunc func)
                {
                        /* Function already registered */
 
-                       _ILMutexUnlock(&(thread->lock));
+                       _ILCriticalSectionLeave(&(thread->lock));
 
                        return -1;
                }
@@ -1147,7 +1264,7 @@ int ILThreadRegisterCleanup(ILThread *thread, 
ILThreadCleanupFunc func)
        {
                /* Out of memory */
 
-               _ILMutexUnlock(&(thread->lock));
+               _ILCriticalSectionLeave(&(thread->lock));
 
                return -1;
        }
@@ -1167,7 +1284,7 @@ int ILThreadRegisterCleanup(ILThread *thread, 
ILThreadCleanupFunc func)
                thread->firstCleanupEntry = thread->lastCleanupEntry = entry;
        }
 
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
        
        return 0;
 }
@@ -1175,16 +1292,20 @@ int ILThreadRegisterCleanup(ILThread *thread, 
ILThreadCleanupFunc func)
 int ILThreadUnregisterCleanup(ILThread *thread, ILThreadCleanupFunc func)
 {
        ILThreadCleanupEntry *entry, *prev;
-       ILUInt16 threadState;
-       
-       _ILMutexLock(&(thread->lock));
+       _ILThreadState threadState;
+
+       IL_THREAD_ASSERT((thread->state.split.pub & IL_TS_UNSTARTED) ||
+                                        (thread == _ILThreadGetSelf()));
+
+       /* Lock down the thread */
+       _ILCriticalSectionEnter(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & IL_TS_STOPPED))
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if((threadState.split.priv & IL_TS_STOPPED))
        {
                /* Thread has stopped */
 
-               _ILMutexUnlock(&(thread->lock));
+               _ILCriticalSectionLeave(&(thread->lock));
 
                return -1;
        }
@@ -1225,7 +1346,7 @@ int ILThreadUnregisterCleanup(ILThread *thread, 
ILThreadCleanupFunc func)
                                }
                        }
 
-                       _ILMutexUnlock(&(thread->lock));
+                       _ILCriticalSectionLeave(&(thread->lock));
 
                        /* Found and removed */
 
@@ -1233,7 +1354,7 @@ int ILThreadUnregisterCleanup(ILThread *thread, 
ILThreadCleanupFunc func)
                }
        }
 
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
 
        /* Not found */
 
@@ -1253,19 +1374,22 @@ int ILThreadGetPriority(ILThread *thread)
 void _ILThreadSuspendRequest(ILThread *thread)
 {
        ILUInt16 threadState;
-       _ILMutexLock(&(thread->lock));
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
+       IL_THREAD_ASSERT(thread == _ILThreadGetSelf());
+
+       _ILCriticalSectionEnter(&(thread->lock));
+
+       threadState = ILInterlockedLoadU2(&(thread->state.split.pub));
        /* Clear the "suspendRequested" and "resumeRequested" flags */
        threadState |= (IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF);
-       ILInterlockedStoreU2(&(thread->state), threadState);
+       ILInterlockedStoreU2(&(thread->state.split.pub), threadState);
        thread->suspendRequested = 0;
        thread->resumeRequested = 0;
 
        /* Signal the thread that wanted to make us suspend that we are */
        _ILSemaphorePost(&(thread->suspendAck));
 
-       _ILMutexUnlock(&(thread->lock));
+       _ILCriticalSectionLeave(&(thread->lock));
 
        /* Suspend the current thread until we receive a resume signal */
        _ILThreadSuspendSelf(thread);
diff --git a/support/w32_defs.c b/support/w32_defs.c
index f63c1cb..ab60b23 100755
--- a/support/w32_defs.c
+++ b/support/w32_defs.c
@@ -19,6 +19,7 @@
  */
 
 #include "thr_defs.h"
+#include "interlocked.h"
 
 #ifdef IL_USE_WIN32_THREADS
 
@@ -29,10 +30,18 @@
 extern "C" {
 #endif
 
+#if defined(USE_COMPILER_TLS)
+/*
+ * Define the thread local variable to hold the ILThread value for the
+ * current thread.
+ */
+_THREAD_ ILThread *_myThread;
+#else
 /*
  * Thread-specific key that is used to store and retrieve the thread object.
  */
 DWORD _ILThreadObjectKey;
+#endif
 
 /*
  *     Sets the thread priority.
@@ -107,8 +116,10 @@ void _ILThreadInitHandleSelf(ILThread *thread)
 
 void _ILThreadInitSystem(ILThread *mainThread)
 {
+#if !defined(USE_COMPILER_TLS)
        /* Allocate a TLS key for storing thread objects */
        _ILThreadObjectKey = TlsAlloc();
+#endif
 
        /* Initialize the "main" thread's handle and identifier.  We have
           to duplicate the thread handle because "GetCurrentThread()" returns
@@ -126,8 +137,13 @@ static DWORD WINAPI ThreadStart(LPVOID arg)
 {
        ILThread *thread = (ILThread *)arg;
 
+#if defined(USE_COMPILER_TLS)
+       /* Store the thread at the thread local storage */
+       _myThread = thread;
+#else
        /* Attach the thread object to the thread */
        TlsSetValue(_ILThreadObjectKey, thread);
+#endif
 
        /* Run the thread */
        _ILThreadRun(thread);
@@ -144,6 +160,52 @@ int _ILThreadCreateSystem(ILThread *thread)
 }
 
 /*
+ * APC procedure for interrupting a thread
+ */
+static VOID CALLBACK _InterruptThread(ULONG_PTR args)
+{
+       /* Nothing to do here */
+}
+
+/*
+ * Send an interrupt request to a thread.
+ */
+void _ILThreadInterrupt(ILThread *thread)
+{
+       QueueUserAPC(_InterruptThread, thread->handle, 0);
+}
+
+/*
+ * Put the current thread to sleep for a number of milliseconds.
+ * The sleep may be interrupted by a call to _ILThreadInterrupt.
+ */
+int _ILThreadSleep(ILUInt32 ms)
+{
+       if((ms <= IL_MAX_INT32) || (ms == IL_MAX_UINT32))
+       {
+               int result;
+
+               result = SleepEx(ms, TRUE);
+               if(result == 0)
+               {
+                       return IL_THREAD_OK;
+               }
+               else if(result == WAIT_IO_COMPLETION)
+               {
+                       return IL_THREAD_ERR_INTERRUPT;
+               }
+               else
+               {
+                       return IL_THREAD_ERR_UNKNOWN;
+               }
+       }
+       else
+       {
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
+/*
  * This function is simply a wrapper around the WaitForSingleObject function
  * to handle the errors and convert them to the unified error codes.
  */
@@ -192,6 +254,60 @@ int        _ILWaitHandleTimedWait(HANDLE handle, ILUInt32 
ms)
 }
 
 /*
+ * This function is the same as _ILWaitHandleTimedWait except that this
+ * version is interruptible by other threads calling _ILThreadInterrupt().
+ */
+int    _ILWaitHandleTimedWaitInterruptible(HANDLE handle, ILUInt32 ms)
+{
+       if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
+       {
+               DWORD result;
+
+               if(ms == IL_MAX_UINT32)
+               {
+                       result = WaitForSingleObjectEx(handle, INFINITE, TRUE);
+               }
+               else
+               {
+                       result = WaitForSingleObjectEx(handle, (DWORD)ms, TRUE);
+               }
+
+               if(result == WAIT_OBJECT_0)
+               {
+                       return IL_THREAD_OK;
+               }
+               else
+               {
+                       switch(result)
+                       {
+                               case WAIT_ABANDONED:
+                               {
+                                       return IL_THREAD_ERR_ABANDONED;
+                               }
+                               break;
+
+                               case WAIT_IO_COMPLETION:
+                               {
+                                       return IL_THREAD_ERR_INTERRUPT;
+                               }
+                               break;
+
+                               case WAIT_TIMEOUT:
+                               {
+                                       return IL_THREAD_BUSY;
+                               }
+                               break;
+                       }
+               }
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       else
+       {
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
+/*
  * Note: this implementation is not fully atomic.  There is a
  * window of opportunity between when the current thread notices
  * that the condition is signalled and when the mutex is regained.
@@ -219,17 +335,11 @@ int _ILCountSemaphoreSignalCount(_ILCountSemaphore *sem, 
ILUInt32 count)
 {
        int result = IL_THREAD_OK;
 
-       /* Lock the count semaphore object. */
-       _ILMutexLock(&(sem->_lock));
-
-       sem->_waiting -= count;
+       ILInterlockedSubI4_Acquire(&(sem->_waiting), count);
 
        result = (ReleaseSemaphore(sem->_sem, (LONG)count, 0) != 0) ? 
                                                IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN;
 
-       /* Unlock the count semaphore object. */
-       _ILMutexUnlock(&(sem->_lock));
-
        return result;
 }
 
@@ -243,7 +353,7 @@ int _ILCountSemaphoreSignalAll(_ILCountSemaphore *sem)
        if(sem->_waiting > 0)
        {
                /* Lock the count semaphore object. */
-               _ILMutexLock(&(sem->_lock));
+               _ILCriticalSectionEnter(&(sem->_lock));
 
                /* We have to recheck because of possible race conditions. */
                if(sem->_waiting > 0)
@@ -255,7 +365,7 @@ int _ILCountSemaphoreSignalAll(_ILCountSemaphore *sem)
                }
 
                /* Unlock the count semaphore object. */
-               _ILMutexUnlock(&(sem->_lock));
+               _ILCriticalSectionLeave(&(sem->_lock));
        }
        return result;
 }
@@ -270,24 +380,24 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms)
                int result = IL_THREAD_OK;
 
                /* Lock the count semaphore object. */
-               _ILMutexLock(&(sem->_lock));
+               _ILCriticalSectionEnter(&(sem->_lock));
 
                sem->_waiting += 1;
 
                /* Unlock the count semaphore object. */
-               _ILMutexUnlock(&(sem->_lock));
+               _ILCriticalSectionLeave(&(sem->_lock));
 
                if((result = _ILWaitHandleTimedWait(sem->_sem, ms)) != 
IL_THREAD_OK)
                {
                        /* We have to decrement the counter again because the 
call failed. */
 
                        /* Lock the count semaphore object. */
-                       _ILMutexLock(&(sem->_lock));
+                       _ILCriticalSectionEnter(&(sem->_lock));
 
                        sem->_waiting -= 1;
 
                        /* Unlock the count semaphore object. */
-                       _ILMutexUnlock(&(sem->_lock));
+                       _ILCriticalSectionLeave(&(sem->_lock));
                }
                return result;
        }
@@ -303,7 +413,7 @@ int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms)
 
        if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
        {
-               result = _ILWaitHandleTimedWait(mon->_mutex, ms);
+               result = _ILWaitHandleTimedWaitInterruptible(mon->_mutex, ms);
        }
        else
        {
@@ -312,92 +422,109 @@ int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms)
        return result;
 }
 
-int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
-                                               ILMonitorPredicate predicate, 
void *arg)
+int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms)
 {
-       DWORD result;
-
        if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
        {
-               /* Increment the number of waiters. */
-               /* Lock the count semaphore object. */
-               _ILMutexLock(&(mon->_sem._lock));
-
-               mon->_sem._waiting += 1;
+               DWORD result;
+               DWORD mutexResult;
 
-               /* Unlock the count semaphore object. */
-               _ILMutexUnlock(&(mon->_sem._lock));
+               /* Decrement the wait count. */
+               ILInterlockedDecrementI4_Acquire(&(mon->_waitValue));
 
                /* Unlock the mutex and wait on the semaphore. */
-               result = SignalObjectAndWait(mon->_mutex, mon->_sem._sem,
-                                                                        
(DWORD)ms, FALSE);
+               result = SignalObjectAndWait(mon->_mutex, mon->_sem,
+                                                                        
(DWORD)ms, TRUE);
 
-               if(result == WAIT_OBJECT_0)
+               if(result != WAIT_OBJECT_0)
                {
-                       /* Now wait until the mutex can be acquired. */
-                       result = _ILWaitHandleWait(mon->_mutex);
-                       if(result == IL_THREAD_OK)
+                       /* Remove us from the waiters. */
+                       ILInterlockedIncrementI4_Acquire(&(mon->_waitValue));
+
+                       if(result == WAIT_IO_COMPLETION)
                        {
-                               /*
-                                * Call the predicate function which should 
return != 0 on
-                                * windows platforms in all cases.
-                                */
-                               if(!predicate(arg))
-                               {
-                                       return IL_THREAD_ERR_UNKNOWN;
-                               }
+                               /* We got interrupted */
+                               result = IL_THREAD_ERR_INTERRUPT;
+                       }
+                       else if(result == WAIT_TIMEOUT)
+                       {
+                               /* Timeout expired before we got signaled */
+                               result = IL_THREAD_BUSY;
+                       }
+                       else
+                       {
+                               /* An unexpected error occured */
+                               return IL_THREAD_ERR_UNKNOWN;
                        }
-                       return result;
                }
                else
                {
-                       /* Lock the count semaphore object. */
-                       _ILMutexLock(&(mon->_sem._lock));
+                       result = IL_THREAD_OK;
+               }
 
-                       if(mon->_sem._waiting > 0)
-                       {
-                               /* Decrement the number of waiters because we 
didn't get */
-                               /* signaled and we didn't miss the signal.*/
-                               mon->_sem._waiting -= 1;
-                       }
+               /* Now wait until the mutex can be acquired. */
+               mutexResult = WaitForSingleObject(mon->_mutex, INFINITE);
 
-                       /* Unlock the count semaphore object. */
-                       _ILMutexUnlock(&(mon->_sem._lock));
+               if(mutexResult == WAIT_OBJECT_0)
+               {
+                       return result;
+               }
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       else
+       {
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
 
-                       if(result == WAIT_TIMEOUT)
-                       {
-                               /* The timeout expired on waiting to get 
pulsed. */
-                               result = _ILWaitHandleWait(mon->_mutex);
+int _ILMonitorPulse(_ILMonitor *mon)
+{
+       if(mon)
+       {
+               ILInt32 waitValue;
 
-                               if(result == IL_THREAD_OK)
-                               {
-                                       /*
-                                        * Call the predicate function which 
should return != 0 on
-                                        * windows platforms in all cases.
-                                        */
-                                       if(!predicate(arg))
-                                       {
-                                               return IL_THREAD_ERR_UNKNOWN;
-                                       }
-                                       /* Returm that we timed out. */
-                                       return IL_THREAD_BUSY;
-                               }
-                               /* In cas of an other error simpy return the 
error. */
-                               return result;
+               waitValue = ILInterlockedLoadI4(&(mon->_waitValue));
+               if(waitValue < 0)
+               {
+                       waitValue = 
ILInterlockedIncrementI4_Acquire(&(mon->_waitValue));
+                       if(waitValue <= 0)
+                       {
+                               ReleaseSemaphore(mon->_sem, 1, NULL);
                        }
                        else
                        {
-                               return IL_THREAD_ERR_UNKNOWN;
+                               
ILInterlockedDecrementI4_Acquire(&(mon->_waitValue));
                        }
                }
+               return IL_THREAD_OK;
        }
-       else
+       return IL_THREAD_ERR_UNKNOWN;
+}
+
+int _ILMonitorPulseAll(_ILMonitor *mon)
+{
+       if(mon)
        {
-               return IL_THREAD_ERR_INVALID_TIMEOUT;
+               ILInt32 waitValue;
+
+               waitValue = ILInterlockedLoadI4(&(mon->_waitValue));
+               if(waitValue < 0)
+               {
+                       waitValue = 
ILInterlockedExchangeI4_Acquire(&(mon->_waitValue), 0);
+                       if(waitValue < 0)
+                       {
+                               ReleaseSemaphore(mon->_sem, -waitValue, NULL);
+                       }
+                       else if(waitValue > 0)
+                       {
+                               ILInterlockedAddI4_Acquire(&(mon->_waitValue), 
waitValue);
+                       }
+               }
+               return IL_THREAD_OK;
        }
+       return IL_THREAD_ERR_UNKNOWN;
 }
 
-
 #ifdef __cplusplus
 };
 #endif
diff --git a/support/w32_defs.h b/support/w32_defs.h
index dbb2e7c..11e89e7 100755
--- a/support/w32_defs.h
+++ b/support/w32_defs.h
@@ -28,6 +28,7 @@ extern        "C" {
 /*
  * Types that are needed elsewhere.
  */
+typedef CRITICAL_SECTION       _ILCriticalSection;
 typedef CRITICAL_SECTION       _ILMutex;
 typedef HANDLE                         _ILCondMutex;
 typedef HANDLE                         _ILCondVar;
@@ -41,9 +42,9 @@ typedef CRITICAL_SECTION      _ILRWLock;
  */
 typedef struct
 {
-       _ILMutex                _lock;
-       _ILSemaphore    _sem;
-       LONG volatile   _waiting;
+       _ILCriticalSection      _lock;
+       _ILSemaphore            _sem;
+       ILInt32 volatile        _waiting;
 } _ILCountSemaphore;
 
 /*
@@ -51,11 +52,23 @@ typedef struct
  */
 typedef struct
 {
-       _ILCountSemaphore       _sem;
+       ILInt32                         _waitValue;
+       _ILSemaphore            _sem;
        _ILCondMutex            _mutex;
 } _ILMonitor;
 
 /*
+ * Determine if we are using compiler thread local storage
+ */
+#if defined(USE_COMPILER_TLS)
+#if !defined(__GNUC__)
+#undef USE_COMPILER_TLS
+#else
+#define _THREAD_ __thread
+#endif
+#endif
+
+/*
  * This is a real thread package.
  */
 #define        _ILThreadIsReal         1
@@ -67,6 +80,11 @@ typedef struct
                        ((thread)->identifier == GetCurrentThreadId())
 
 /*
+ * Send an interrupt request to a thread.
+ */
+void _ILThreadInterrupt(ILThread *thread);
+
+/*
  * Some helper macros for wait handles.
  */
 
@@ -120,6 +138,33 @@ int        _ILWaitHandleTimedWait(HANDLE handle, ILUInt32 
ms);
 #define        _ILThreadDestroy(thread)        
_ILWaitHandleClose((thread)->handle)
 
 /*
+ * Put the current thread to sleep for a number of milliseconds.
+ * The sleep may be interrupted by a call to _ILThreadInterrupt.
+ */
+int _ILThreadSleep(ILUInt32 ms);
+
+/*
+ * Primitive critical section operations.
+ * NOTE:: the "EnterUnsafe" and "LeaveUnsafe" operations are not "suspend-safe"
+ */
+#define        _ILCriticalSectionCreate(critsect)      \
+                       do { \
+                               InitializeCriticalSection((critsect)); \
+                       } while (0)
+#define        _ILCriticalSectionDestroy(critsect)     \
+                       do { \
+                               DeleteCriticalSection((critsect)); \
+                       } while (0)
+#define        _ILCriticalSectionEnterUnsafe(critsect) \
+                       do { \
+                               EnterCriticalSection((critsect)); \
+                       } while (0)
+#define        _ILCriticalSectionLeaveUnsafe(critsect) \
+                       do { \
+                               LeaveCriticalSection((critsect)); \
+                       } while (0)
+
+/*
  * Primitive mutex operations.  Note: the "Lock" and "Unlock"
  * operations are not "suspend-safe".
  */
@@ -203,12 +248,12 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms);
 #define _ILCountSemaphoreCreate(sem)   \
                ({ \
                        (sem)->_waiting = 0; \
-                       _ILMutexCreate(&((sem)->_lock)); \
+                       _ILCriticalSectionCreate(&((sem)->_lock)); \
                        _ILSemaphoreCreate(&(sem)->_sem);       \
                })
 #define _ILCountSemaphoreDestroy(sem)  \
                ({ \
-                       _ILMutexDestroy(&((sem)->_lock)); \
+                       _ILCriticalSectionDestroy(&((sem)->_lock)); \
                        _ILSemaphoreDestroy(&((sem)->_sem)); \
                })
 
@@ -238,16 +283,17 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms);
 #define        _ILMonitorCreate(mon)   \
                ({ \
                        int _result = 0; \
+                       (mon)->_waitValue = 0; \
                        if((_result = _ILCondMutexCreate(&((mon)->_mutex))) == 
IL_THREAD_OK) \
                        { \
-                               _result = 
_ILCountSemaphoreCreate(&((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(_ILCountSemaphoreDestroy(&((mon)->_sem)) != 
IL_THREAD_OK) \
+                       if(_ILSemaphoreDestroy(&((mon)->_sem)) != IL_THREAD_OK) 
\
                        { \
                                _result = IL_THREAD_ERR_UNKNOWN; \
                        } \
@@ -257,37 +303,38 @@ int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, 
ILUInt32 ms);
                        } \
                        _result; \
                })
-#define        _ILMonitorEnter(mon)    \
-                       _ILCondMutexLockUnsafe(&((mon)->_mutex))
-#define        _ILMonitorExit(mon)     \
-                       _ILCondMutexUnlockUnsafe(&((mon)->_mutex))
 
 /*
  * Release one waiter from the waiting queue.
  */
-#define _ILMonitorPulse(mon)   _ILCountSemaphoreSignal(&((mon)->_sem))
+int _ILMonitorPulse(_ILMonitor *mon);
 
 /*
  * Release all waiters from the waiting queue.
  */
-#define        _ILMonitorPulseAll(mon) 
_ILCountSemaphoreSignalAll(&((mon)->_sem))
+int    _ILMonitorPulseAll(_ILMonitor *mon);
 
 int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms);
 #define _ILMonitorTryEnter(mon)        _ILMonitorTimedTryEnter(mon, 0)
-
-int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
-                                               ILMonitorPredicate predicate, 
void *arg);
-#define _ILMonitorWait(mon, pred, arg) \
-                       _ILMonitorTimedWait((mon), IL_MAX_UINT32, (pred), (arg))
+#define _ILMonitorEnter(mon)   _ILMonitorTimedTryEnter(mon, IL_MAX_UINT32)
+#define        _ILMonitorExit(mon)             
_ILCondMutexUnlockUnsafe(&((mon)->_mutex))
+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 DWORD _ILThreadObjectKey;
 #define        _ILThreadGetSelf()      \
                        ((ILThread *)(TlsGetValue(_ILThreadObjectKey)))
 #define        _ILThreadSetSelf(object)        \
                        (TlsSetValue(_ILThreadObjectKey, (object)))
+#endif
 
 /*
  * Call a function "once".
diff --git a/support/wait.c b/support/wait.c
index 344a153..b3800b8 100644
--- a/support/wait.c
+++ b/support/wait.c
@@ -50,25 +50,37 @@ int ILWaitHandleClose(ILWaitHandle *handle)
 int _ILEnterWait(ILThread *thread)
 {
        int result = 0;
-       ILUInt16 threadState;
+       _ILThreadState threadState;
+
+       /*
+        * Set the wait/sleep/join state so that it will be seen by a possible
+        * call to ILThreadAbort by an other thread.
+        */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       threadState.split.priv |= IL_TS_WAIT_SLEEP_JOIN;
+       ILInterlockedStoreU2_Acquire(&(thread->state.split.priv),
+                                                                
threadState.split.priv);
+       /* Requery the thread state */
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if ((threadState.split.pub & (IL_TS_INTERRUPTED_OR_ABORT_REQUESTED)) != 
0)
+       {       
+               _ILCriticalSectionEnter(&(thread->lock));
+
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+               if((threadState.split.pub & (IL_TS_ABORT_REQUESTED)) != 0)
+               {
+                       /* Clear the wait/sleep/join state and interrupted flag 
*/
+                       threadState.split.priv |= IL_TS_WAIT_SLEEP_JOIN;
+                       threadState.split.pub &= ~(IL_TS_INTERRUPTED);
+                       ILInterlockedStoreU4(&(thread->state.comb), 
threadState.comb);
 
-       _ILMutexLock(&(thread->lock));
+                       result = IL_WAIT_ABORTED;
 
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & (IL_TS_ABORT_REQUESTED)) != 0)
-       {
-               result = IL_WAIT_ABORTED;
+                       _ILWakeupCancelInterrupt(&(thread->wakeup));
+               }
 
-               _ILWakeupCancelInterrupt(&(thread->wakeup));
-               threadState &= ~(IL_TS_INTERRUPTED);
+               _ILCriticalSectionLeave(&(thread->lock));
        }
-       else
-       {
-               threadState |= IL_TS_WAIT_SLEEP_JOIN;
-       }
-       ILInterlockedStoreU2(&(thread->state), threadState);
-
-       _ILMutexUnlock(&(thread->lock));
 
        return result;
 }
@@ -79,56 +91,61 @@ int _ILEnterWait(ILThread *thread)
  */
 int _ILLeaveWait(ILThread *thread, int result)
 {
-       ILUInt16 threadState;
-
-       _ILMutexLock(&(thread->lock));
+       _ILThreadState threadState;
 
        /* The double checks for result == IL_WAIT_* are needed to bubble down
           results even if the threadstate has been reset which may happen
           if enter/leavewait are called recursively */
 
-       /* Abort has more priority over interrupt */
-       threadState = ILInterlockedLoadU2(&(thread->state));
-       if((threadState & (IL_TS_ABORT_REQUESTED)) != 0
-               || result == IL_WAIT_ABORTED)
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if ((threadState.split.pub & (IL_TS_ABORT_REQUESTED | IL_TS_INTERRUPTED 
| IL_TS_SUSPEND_REQUESTED)) != 0)
        {
-               result = IL_WAIT_ABORTED;
-       }
-       else if((threadState & IL_TS_INTERRUPTED) != 0
-               || result == IL_WAIT_INTERRUPTED)
-       {                
-               result = IL_WAIT_INTERRUPTED;
-       }
-
-       _ILWakeupCancelInterrupt(&(thread->wakeup));
-       
-       if ((threadState & IL_TS_SUSPEND_REQUESTED) != 0)
-       {
-               threadState &= ~IL_TS_SUSPEND_REQUESTED;
-               threadState |= IL_TS_SUSPENDED | IL_TS_SUSPENDED_SELF;
-               thread->resumeRequested = 0;
-
-               threadState &= ~(IL_TS_INTERRUPTED);
+               _ILCriticalSectionEnter(&(thread->lock));
 
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
 
-               /* Unlock the thread object prior to suspending */
-               _ILMutexUnlock(&(thread->lock));
+               /* Abort has more priority over interrupt */
+               if(((threadState.split.pub & IL_TS_ABORT_REQUESTED) != 0) ||
+                  result == IL_WAIT_ABORTED)
+               {
+                       result = IL_WAIT_ABORTED;
+               }
+               else if(((threadState.split.pub & IL_TS_INTERRUPTED) != 0) ||
+                               result == IL_WAIT_INTERRUPTED)
+               {
+                       result = IL_WAIT_INTERRUPTED;
+               }
 
-               /* Suspend until we receive notification from another thread */
-               _ILThreadSuspendSelf(thread);
+               _ILWakeupCancelInterrupt(&(thread->wakeup));
+       
+               if((threadState.split.pub & IL_TS_SUSPEND_REQUESTED) != 0)
+               {
+                       threadState.split.pub &= ~(IL_TS_SUSPEND_REQUESTED | 
IL_TS_INTERRUPTED);
+                       threadState.split.pub |= (IL_TS_SUSPENDED | 
IL_TS_SUSPENDED_SELF);
+                       threadState.split.priv &= ~IL_TS_WAIT_SLEEP_JOIN;
+                       thread->resumeRequested = 0;
 
-               /* And relock for changing the state */
-               _ILMutexLock(&(thread->lock));
+                       ILInterlockedStoreU4(&(thread->state.comb), 
threadState.comb);
 
-               threadState = ILInterlockedLoadU2(&(thread->state));
-       }
-       threadState &= ~(IL_TS_WAIT_SLEEP_JOIN | IL_TS_INTERRUPTED);
+                       /* Unlock the thread object prior to suspending */
+                       _ILCriticalSectionLeave(&(thread->lock));
 
-       ILInterlockedStoreU2(&(thread->state), threadState);
+                       /* Suspend until we receive notification from another 
thread */
+                       _ILThreadSuspendSelf(thread);
 
-       _ILMutexUnlock(&(thread->lock));
+                       return result;
+               }
+               threadState.split.priv &= ~IL_TS_WAIT_SLEEP_JOIN;
+               
+               ILInterlockedStoreU4(&(thread->state.comb), threadState.comb);
 
+               _ILCriticalSectionLeave(&(thread->lock));
+       }
+       else
+       {
+               threadState.split.priv &= ~IL_TS_WAIT_SLEEP_JOIN;
+               ILInterlockedStoreU2(&(thread->state.split.priv), 
threadState.split.priv);
+       }
        return result;
 }
 
@@ -479,11 +496,12 @@ int _ILWaitOneBackupInterruptsAndAborts(ILWaitHandle 
*handle, int timeout)
 {
        ILThread *thread = _ILThreadGetSelf();
        int result, retval = 0;
-       ILUInt16 threadstate = 0;
-       
+       _ILThreadState threadState;
+
+       threadState.comb = 0;
        for (;;)
        {
-               ILUInt16 newThreadstate;
+               _ILThreadState newThreadState;
 
                /* Wait to re-acquire the monitor (add ourselves to the "ready 
queue") */
                result = ILWaitOne(handle, timeout);
@@ -492,44 +510,44 @@ int _ILWaitOneBackupInterruptsAndAborts(ILWaitHandle 
*handle, int timeout)
                {
                        /* We were aborted or interrupted.  Save the thread 
state
                                and keep trying to reaquire the monitor */
-                       
-                       _ILMutexLock(&thread->lock);
 
-                       newThreadstate = ILInterlockedLoadU2(&(thread->state));
-                       threadstate |= newThreadstate;
+                       _ILCriticalSectionEnter(&thread->lock);
+
+                       newThreadState.comb = 
ILInterlockedLoadU4(&(thread->state.comb));
+                       threadState.comb |= newThreadState.comb;
                        
                        if (result == IL_WAIT_INTERRUPTED)
                        {
                                /* Interrupted is cleared by ILWaitOne so save 
it manually */
-                               threadstate |= IL_TS_INTERRUPTED;
+                               threadState.split.pub |= IL_TS_INTERRUPTED;
                        }
                        
-                       newThreadstate &= 
~(IL_TS_INTERRUPTED_OR_ABORT_REQUESTED);
+                       newThreadState.split.pub &= 
~(IL_TS_INTERRUPTED_OR_ABORT_REQUESTED);
 
                        if (result < retval)
                        {
                                retval = result;
                        }
 
-                       ILInterlockedStoreU2(&(thread->state), newThreadstate);
+                       ILInterlockedStoreU4(&(thread->state.comb), 
newThreadState.comb);
 
-                       _ILMutexUnlock(&thread->lock);
+                       _ILCriticalSectionLeave(&thread->lock);
                        
                        continue;
                }
                else
                {       
-                       if (threadstate != 0)
+                       if (threadState.comb != 0)
                        {
-                               _ILMutexLock(&thread->lock);
+                               _ILCriticalSectionEnter(&thread->lock);
 
                                /* Set the thread state to the thread state 
that was stored 
                                        and clear the interrupted flag */
-                               newThreadstate = 
ILInterlockedLoadU2(&(thread->state));
-                               newThreadstate |= (threadstate & 
~IL_TS_INTERRUPTED);
-                               ILInterlockedStoreU2(&(thread->state), 
newThreadstate);
+                               newThreadState.comb = 
ILInterlockedLoadU4(&(thread->state.comb));
+                               newThreadState.comb |= (threadState.comb & 
~IL_TS_INTERRUPTED);
+                               ILInterlockedStoreU4(&(thread->state.comb), 
newThreadState.comb);
                                
-                               _ILMutexUnlock(&thread->lock);
+                               _ILCriticalSectionLeave(&thread->lock);
                        }       
                        else
                        {
diff --git a/support/wait_event.c b/support/wait_event.c
index 86d04bb..c2c334b 100644
--- a/support/wait_event.c
+++ b/support/wait_event.c
@@ -47,7 +47,7 @@ static int EventRegister(ILWaitEvent *event, _ILWakeup 
*wakeup)
        int result;
 
        /* Lock down the event */
-       _ILMutexLock(&(event->parent.lock));
+       _ILCriticalSectionEnter(&(event->parent.lock));
 
        /* Determine what to do based on the event's current state */
        if((event->data & EVENT_SET_MASK))
@@ -78,7 +78,7 @@ static int EventRegister(ILWaitEvent *event, _ILWakeup 
*wakeup)
        }
 
        /* Unlock the event and return */
-       _ILMutexUnlock(&(event->parent.lock));
+       _ILCriticalSectionLeave(&(event->parent.lock));
 
        return result;
 }
@@ -89,13 +89,13 @@ static int EventRegister(ILWaitEvent *event, _ILWakeup 
*wakeup)
 static void EventUnregister(ILWaitEvent *event, _ILWakeup *wakeup, int release)
 {
        /* Lock down the event */
-       _ILMutexLock(&(event->parent.lock));
+       _ILCriticalSectionEnter(&(event->parent.lock));
 
        /* Remove ourselves from the wait queue if we are currently on it */
        _ILWakeupQueueRemove(&(event->queue), wakeup);
        
        /* Unlock the event and return */
-       _ILMutexUnlock(&(event->parent.lock));
+       _ILCriticalSectionLeave(&(event->parent.lock));
 }
 
 static int EventSignal(ILWaitHandle *waitHandle)
@@ -164,7 +164,7 @@ int ILWaitEventSet(ILWaitHandle *handle)
        }
        
        /* Lock down the event */
-       _ILMutexLock(&(event->parent.lock));
+       _ILCriticalSectionEnter(&(event->parent.lock));
 
        if (!(event->data & (EVENT_SET_MASK)))
        {               
@@ -194,7 +194,7 @@ int ILWaitEventSet(ILWaitHandle *handle)
        }
        
        /* Unlock the event and return */
-       _ILMutexUnlock(&(event->parent.lock));
+       _ILCriticalSectionLeave(&(event->parent.lock));
 
        return 1;
 }
@@ -215,7 +215,7 @@ int ILWaitEventPulse(ILWaitHandle *handle)
        }
        
        /* Lock down the event */
-       _ILMutexLock(&(event->parent.lock));
+       _ILCriticalSectionEnter(&(event->parent.lock));
 
        if (!(event->data & (EVENT_SET_MASK)))
        {               
@@ -233,14 +233,14 @@ int ILWaitEventPulse(ILWaitHandle *handle)
                                _ILWakeupQueueWakeAll(&event->queue);
                        }
                        else
-                       {                               
+                       {
                                _ILWakeupQueueWake(&event->queue);
                        }
                }
        }
 
        /* Unlock the event and return */
-       _ILMutexUnlock(&(event->parent.lock));
+       _ILCriticalSectionLeave(&(event->parent.lock));
 
        return 1;
 }
@@ -261,13 +261,13 @@ int ILWaitEventReset(ILWaitHandle *handle)
        }
        
        /* Lock down the event */
-       _ILMutexLock(&(event->parent.lock));
+       _ILCriticalSectionEnter(&(event->parent.lock));
 
        /* Reset the event */
        event->data &= ~(EVENT_SET_MASK);
        
        /* Unlock the event and return */
-       _ILMutexUnlock(&(event->parent.lock));
+       _ILCriticalSectionLeave(&(event->parent.lock));
 
        return 1;
 }
diff --git a/support/wait_mutex.c b/support/wait_mutex.c
index 4fa460f..8797fb0 100644
--- a/support/wait_mutex.c
+++ b/support/wait_mutex.c
@@ -51,7 +51,7 @@ struct _tagILMutexName
 
 };
 static ILMutexName *nameList;
-static _ILMutex nameListLock;
+static _ILCriticalSection nameListLock;
 
 /*
  * Close a regular mutex.
@@ -59,16 +59,16 @@ static _ILMutex nameListLock;
 static int MutexClose(ILWaitMutex *mutex)
 {
        /* Lock down the mutex and determine if it is currently owned */
-       _ILMutexLock(&(mutex->parent.lock));
+       _ILCriticalSectionEnter(&(mutex->parent.lock));
 
        if(mutex->owner != 0 || !_ILWakeupQueueIsEmpty(&(mutex->queue)))
        {
-               _ILMutexUnlock(&(mutex->parent.lock));
+               _ILCriticalSectionLeave(&(mutex->parent.lock));
                return IL_WAITCLOSE_OWNED;
        }
 
        /* Clean up the mutex */
-       _ILMutexUnlock(&(mutex->parent.lock));
+       _ILCriticalSectionLeave(&(mutex->parent.lock));
        _ILWakeupQueueDestroy(&(mutex->queue));
        _ILMutexDestroy(&(mutex->parent.lock));
        
@@ -83,28 +83,28 @@ static int MutexCloseNamed(ILWaitMutexNamed *mutex)
        ILMutexName *temp, *prev;
 
        /* We need the name list lock */
-       _ILMutexLock(&nameListLock);
+       _ILCriticalSectionEnter(&nameListLock);
 
        /* Lock down the mutex and determine if it is currently owned */
-       _ILMutexLock(&(mutex->parent.parent.lock));
+       _ILCriticalSectionEnter(&(mutex->parent.parent.lock));
        if(mutex->parent.owner != 0 ||
           !_ILWakeupQueueIsEmpty(&(mutex->parent.queue)))
        {
-               _ILMutexUnlock(&(mutex->parent.parent.lock));
-               _ILMutexUnlock(&nameListLock);
+               _ILCriticalSectionLeave(&(mutex->parent.parent.lock));
+               _ILCriticalSectionLeave(&nameListLock);
                return IL_WAITCLOSE_OWNED;
        }
 
        /* Decrease the number of users and bail out if still non-zero */
        if(--(mutex->numUsers) != 0)
        {
-               _ILMutexUnlock(&(mutex->parent.parent.lock));
-               _ILMutexUnlock(&nameListLock);
+               _ILCriticalSectionLeave(&(mutex->parent.parent.lock));
+               _ILCriticalSectionLeave(&nameListLock);
                return IL_WAITCLOSE_DONT_FREE;
        }
 
        /* Clean up the mutex */
-       _ILMutexUnlock(&(mutex->parent.parent.lock));
+       _ILCriticalSectionLeave(&(mutex->parent.parent.lock));
        _ILWakeupQueueDestroy(&(mutex->parent.queue));
        _ILMutexDestroy(&(mutex->parent.parent.lock));
 
@@ -128,7 +128,7 @@ static int MutexCloseNamed(ILWaitMutexNamed *mutex)
                }
                ILFree(temp);
        }
-       _ILMutexUnlock(&nameListLock);
+       _ILCriticalSectionLeave(&nameListLock);
 
        /* The wait handle object is now completely free */
        return IL_WAITCLOSE_FREE;
@@ -317,7 +317,7 @@ static int MutexRegister(ILWaitMutex *mutex, _ILWakeup 
*wakeup)
        int result;
 
        /* Lock down the mutex */
-       _ILMutexLock(&(mutex->parent.lock));
+       _ILCriticalSectionEnter(&(mutex->parent.lock));
 
        /* Determine what to do based on the mutex's current state */
        if(mutex->owner == 0)
@@ -356,7 +356,7 @@ static int MutexRegister(ILWaitMutex *mutex, _ILWakeup 
*wakeup)
        }
 
        /* Unlock the mutex and return */
-       _ILMutexUnlock(&(mutex->parent.lock));
+       _ILCriticalSectionLeave(&(mutex->parent.lock));
        return result;
 }
 
@@ -366,7 +366,7 @@ static int MutexRegister(ILWaitMutex *mutex, _ILWakeup 
*wakeup)
 static void MutexUnregister(ILWaitMutex *mutex, _ILWakeup *wakeup, int release)
 {
        /* Lock down the mutex */
-       _ILMutexLock(&(mutex->parent.lock));
+       _ILCriticalSectionEnter(&(mutex->parent.lock));
 
        /* Remove ourselves from the wait queue if we are currently on it */
        _ILWakeupQueueRemove(&(mutex->queue), wakeup);
@@ -401,7 +401,7 @@ static void MutexUnregister(ILWaitMutex *mutex, _ILWakeup 
*wakeup, int release)
        }
 
        /* Unlock the mutex and return */
-       _ILMutexUnlock(&(mutex->parent.lock));
+       _ILCriticalSectionLeave(&(mutex->parent.lock));
 }
 
 static int MutexSignal(ILWaitHandle *waitHandle)
@@ -469,7 +469,7 @@ ILWaitHandle *ILWaitMutexCreate(int initiallyOwned)
  */
 static void MutexNameListInit(void)
 {
-       _ILMutexCreate(&nameListLock);
+       _ILCriticalSectionCreate(&nameListLock);
        nameList = 0;
 }
 
@@ -494,7 +494,7 @@ ILWaitHandle *ILWaitMutexNamedCreate(const char *name, int 
initiallyOwned,
 
        /* Search for a mutex with the same name */
        _ILCallOnce(MutexNameListInit);
-       _ILMutexLock(&nameListLock);
+       _ILCriticalSectionEnter(&nameListLock);
        temp = nameList;
        while(temp != 0)
        {
@@ -502,12 +502,12 @@ ILWaitHandle *ILWaitMutexNamedCreate(const char *name, 
int initiallyOwned,
                {
                        /* Increase the usage count on the mutex */
                        mutex = (ILWaitMutexNamed *)(temp->handle);
-                       _ILMutexLock(&(mutex->parent.parent.lock));
+                       _ILCriticalSectionEnter(&(mutex->parent.parent.lock));
                        ++(mutex->numUsers);
-                       _ILMutexUnlock(&(mutex->parent.parent.lock));
+                       _ILCriticalSectionLeave(&(mutex->parent.parent.lock));
 
                        /* Unlock the name list */
-                       _ILMutexUnlock(&nameListLock);
+                       _ILCriticalSectionLeave(&nameListLock);
 
                        /* Attempt to acquire ownership of the mutex if 
requested */
                        if(initiallyOwned)
@@ -533,7 +533,7 @@ ILWaitHandle *ILWaitMutexNamedCreate(const char *name, int 
initiallyOwned,
        /* Allocate memory for the mutex */
        if((mutex = (ILWaitMutexNamed *)ILMalloc(sizeof(ILWaitMutexNamed))) == 
0)
        {
-               _ILMutexUnlock(&nameListLock);
+               _ILCriticalSectionLeave(&nameListLock);
                return 0;
        }
 
@@ -541,7 +541,7 @@ ILWaitHandle *ILWaitMutexNamedCreate(const char *name, int 
initiallyOwned,
        temp = (ILMutexName *)ILMalloc(sizeof(ILMutexName) + strlen(name));
        if(!temp)
        {
-               _ILMutexUnlock(&nameListLock);
+               _ILCriticalSectionLeave(&nameListLock);
                ILFree(mutex);
                return 0;
        }
@@ -572,7 +572,7 @@ ILWaitHandle *ILWaitMutexNamedCreate(const char *name, int 
initiallyOwned,
        temp->handle = &(mutex->parent.parent);
        strcpy(temp->name, name);
        nameList = temp;
-       _ILMutexUnlock(&nameListLock);
+       _ILCriticalSectionLeave(&nameListLock);
 
        /* Ready to go */
        return &(mutex->parent.parent);
@@ -585,7 +585,7 @@ int ILWaitMutexRelease(ILWaitHandle *handle)
        int result;
 
        /* Lock down the mutex */
-       _ILMutexLock(&(mutex->parent.lock));
+       _ILCriticalSectionEnter(&(mutex->parent.lock));
 
        wakeup = &_ILThreadGetSelf()->wakeup;
 
@@ -625,7 +625,7 @@ int ILWaitMutexRelease(ILWaitHandle *handle)
        }
 
        /* Unlock the mutex and return */
-       _ILMutexUnlock(&(mutex->parent.lock));
+       _ILCriticalSectionLeave(&(mutex->parent.lock));
        return result;
 }
 
@@ -635,19 +635,19 @@ int ILWaitMutexRelease(ILWaitHandle *handle)
 static int MonitorClose(ILWaitMonitor *monitor)
 {
        /* Lock down the monitor and determine if it is currently owned */
-       _ILMutexLock(&(monitor->parent.parent.lock));
+       _ILCriticalSectionEnter(&(monitor->parent.parent.lock));
        
        /* We we allow monitors to be closed even if they have
           an owner.  It is valid for a program to lock an
           object and never release it before it gets GC-ed.  */
        if(monitor->waiters > 0 || 
!_ILWakeupQueueIsEmpty(&(monitor->parent.queue)))
        {
-               _ILMutexUnlock(&(monitor->parent.parent.lock));
+               _ILCriticalSectionLeave(&(monitor->parent.parent.lock));
                return IL_WAITCLOSE_OWNED;
        }
 
        /* Clean up the monitor */
-       _ILMutexUnlock(&(monitor->parent.parent.lock));
+       _ILCriticalSectionLeave(&(monitor->parent.parent.lock));
        _ILWakeupQueueDestroy(&(monitor->parent.queue));
        _ILWakeupQueueDestroy(&(monitor->signalQueue));
        _ILMutexDestroy(&(monitor->parent.parent.lock));
@@ -721,7 +721,7 @@ int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 
timeout)
        }
                
        /* Lock down the monitor */
-       _ILMutexLock(&(monitor->parent.parent.lock));
+       _ILCriticalSectionEnter(&(monitor->parent.parent.lock));
 
        ++monitor->waiters;
 
@@ -762,7 +762,7 @@ int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 
timeout)
                        }
 
                        /* Unlock the monitor */
-                       _ILMutexUnlock(&(monitor->parent.parent.lock));
+                       _ILCriticalSectionLeave(&(monitor->parent.parent.lock));
 
                        /* Wait until we are signalled */                       
                        result = _ILWakeupWait(wakeup, timeout, 0);
@@ -779,7 +779,7 @@ int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 
timeout)
                else
                {
                        /* Unlock the monitor */
-                       _ILMutexUnlock(&(monitor->parent.parent.lock));
+                       _ILCriticalSectionLeave(&(monitor->parent.parent.lock));
 
                        result = IL_WAIT_INTERRUPTED;
                }
@@ -793,7 +793,7 @@ int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 
timeout)
                }
 
                /* Lock down the monitor and set the count back to the right 
value */
-               _ILMutexLock(&(monitor->parent.parent.lock));
+               _ILCriticalSectionEnter(&(monitor->parent.parent.lock));
 
                if(monitor->parent.owner == 0)
                {
@@ -809,7 +809,7 @@ int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 
timeout)
        --monitor->waiters;
        
        /* Unlock the monitor and return */
-       _ILMutexUnlock(&(monitor->parent.parent.lock));
+       _ILCriticalSectionLeave(&(monitor->parent.parent.lock));
 
        return _ILLeaveWait(thread, result);
 }
@@ -821,7 +821,7 @@ static IL_INLINE int PrivateWaitMonitorPulse(ILWaitHandle 
*handle, int all)
        int result;
 
        /* Lock down the monitor */
-       _ILMutexLock(&(monitor->parent.parent.lock));
+       _ILCriticalSectionEnter(&(monitor->parent.parent.lock));
 
        /* Determine what to do based on the monitor's state */
        if(_ILWaitHandle_kind(&(monitor->parent.parent)) != IL_WAIT_MONITOR)
@@ -840,7 +840,7 @@ static IL_INLINE int PrivateWaitMonitorPulse(ILWaitHandle 
*handle, int all)
                /* GCC should optimise out this if statement */
                
                if (all)
-               {                       
+               {
                        _ILWakeupQueueWakeAll(&(monitor->signalQueue));
                }
                else
@@ -851,7 +851,7 @@ static IL_INLINE int PrivateWaitMonitorPulse(ILWaitHandle 
*handle, int all)
                result = 1;
        }
        /* Unlock the monitor and return */
-       _ILMutexUnlock(&(monitor->parent.parent.lock));
+       _ILCriticalSectionLeave(&(monitor->parent.parent.lock));
        return result;
 }
 
diff --git a/support/wait_mutex.h b/support/wait_mutex.h
index b581ebb..f9c90fe 100644
--- a/support/wait_mutex.h
+++ b/support/wait_mutex.h
@@ -36,6 +36,7 @@ static IL_INLINE int ILWaitMutexFastEnter(ILThread *thread, 
ILWaitHandle *handle
 {
        int result = 0;
        ILWaitMutex *mutex = (ILWaitMutex *)handle;
+       _ILThreadState threadState;
        
        /*
         * MS.NET behaviour is weird.  If a thread is interrupted and
@@ -57,25 +58,24 @@ static IL_INLINE int ILWaitMutexFastEnter(ILThread *thread, 
ILWaitHandle *handle
         * entered (not just *any* monitor like with MS.NET) is
         * locked.  Currently, PNET uses the first option.
         */
-       if ((thread->state & (IL_TS_INTERRUPTED_OR_ABORT_REQUESTED)) != 0)
+       threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+       if ((threadState.split.pub & (IL_TS_INTERRUPTED_OR_ABORT_REQUESTED)) != 
0)
        {
-               ILUInt16 threadState;
-
                _ILMutexLock(&thread->lock);
 
-               threadState = ILInterlockedLoadU2(&(thread->state));
-               if ((threadState & (IL_TS_ABORT_REQUESTED)) != 0)
+               threadState.comb = ILInterlockedLoadU4(&(thread->state.comb));
+               if ((threadState.split.pub & (IL_TS_ABORT_REQUESTED)) != 0)
                {
                        result = IL_WAIT_ABORTED;
                }
-               else if ((threadState & (IL_TS_INTERRUPTED)) != 0)
+               else if ((threadState.split.pub & (IL_TS_INTERRUPTED)) != 0)
                {
                        result = IL_WAIT_INTERRUPTED;
                }
                
                _ILWakeupCancelInterrupt(&(thread->wakeup));
-               threadState &= ~(IL_TS_INTERRUPTED);
-               ILInterlockedStoreU2(&(thread->state), threadState);
+               threadState.split.pub &= ~(IL_TS_INTERRUPTED);
+               ILInterlockedStoreU2(&(thread->state.split.pub), 
threadState.split.pub);
 
                _ILMutexUnlock(&thread->lock);
        }
diff --git a/tests/test_thread.c b/tests/test_thread.c
index 9beb186..d6dc02a 100755
--- a/tests/test_thread.c
+++ b/tests/test_thread.c
@@ -156,12 +156,12 @@ static void thread_create_arg(void *arg)
        /* Start the thread running */
        ILThreadStart(thread);
 
-       /* Wait for the thread to exit */
-       sleepFor(1);
+       /* Wait for the thread to finish */
+       ILThreadJoin(thread, 10000);
 
-       /* Clean up the thread object (the thread itself is now dead) */
+       /* Destroy the thread object */
        ILThreadDestroy(thread);
-
+       
        /* Determine if the test was successful or not */
        if(globalFlag == -1)
        {
@@ -258,8 +258,8 @@ static void thread_create_state(void *arg)
        sleepFor(1);
        state2 = ILThreadGetState(thread);
 
-       /* Wait 2 more time steps for the thread to exit */
-       sleepFor(2);
+       /* Wait for the thread to exit */
+       ILThreadJoin(thread, 10000);
        state3 = ILThreadGetState(thread);
 
        /* Clean up the thread object (the thread itself is now dead) */
@@ -481,6 +481,9 @@ static void thread_suspend_destroy(void *arg)
        /* Wait 1 time step to let the system settle */
        sleepFor(1);
 
+       /* Abort the thread */
+       ILThreadAbort(thread);
+       
        /* Destroy the thread */
        ILThreadDestroy(thread);
 }
@@ -817,9 +820,20 @@ static void thread_sleep(void *arg)
        {
                ILUnitFailed("sleep did not end when expected");
        }
-       if(!sleepResult)
+       if(sleepResult != IL_THREAD_OK)
        {
-               ILUnitFailed("sleep was interrupted");
+               if(sleepResult == IL_THREAD_ERR_INTERRUPT)
+               {
+                       ILUnitFailed("sleep was interrupted");
+               }
+               else if(sleepResult == IL_THREAD_ERR_ABORTED)
+               {
+                       ILUnitFailed("thread was aborted");
+               }
+               else
+               {
+                       ILUnitFailed("sleep failed");
+               }
        }
 }
 
@@ -870,9 +884,9 @@ static void thread_sleep_interrupt(void *arg)
        {
                ILUnitFailed("sleep was not interrupted");
        }
-       if(sleepResult != IL_WAIT_INTERRUPTED)
+       if(sleepResult != IL_THREAD_ERR_INTERRUPT)
        {
-               ILUnitFailed("sleep should have returned IL_WAIT_INTERRUPTED");
+               ILUnitFailed("sleep should have returned 
IL_THREAD_ERR_INTERRUPT");
        }
 }
 
@@ -1800,17 +1814,10 @@ static void primitive_monitor_enter(void *arg)
        _ILMonitorDestroy(&mon);
 }
 
-static int _result;
+static volatile int _result;
 static _ILMonitor _mon1;
 
-/*
- * A simple monitor predicate returning success in every case.
- */
-static int _monitor_predicate(void *arg)
-{
-       return 1;
-}
-
+#ifndef IL_USE_PTHREADS
 static void _primitive_monitor_exit_unowned(void *arg)
 {
        _ILMonitor *mon1 = (_ILMonitor *)arg;
@@ -1877,6 +1884,7 @@ static void primitive_monitor_exit_unowned(void *arg)
        }
        _ILMonitorDestroy(&_mon1);
 }
+#endif /* !IL_USE_PTHREADS */
 
 /*
  * Test monitor enter1.
@@ -2266,7 +2274,7 @@ static void primitive_monitor_wait1(void *arg)
        /* The result1 should be 0 now. */
        result1 = _result;
 
-       if(_ILMonitorWait(&_mon1, _monitor_predicate, 0) != IL_THREAD_OK)
+       if(_ILMonitorWait(&_mon1) != IL_THREAD_OK)
        {
                /* Clean up the thread object. */
                ILThreadDestroy(thread);
@@ -2402,7 +2410,7 @@ static void primitive_monitor_timed_wait1(void *arg)
        /* The result1 should be 0 now. */
        result1 = _result;
 
-       result = _ILMonitorTimedWait(&_mon1, 2, _monitor_predicate, 0);
+       result = _ILMonitorTimedWait(&_mon1, 2);
        if(result != IL_THREAD_BUSY)
        {
                /* Clean up the thread object. */
@@ -2450,47 +2458,27 @@ static void primitive_monitor_timed_wait1(void *arg)
  */
 static void monitor_create(void *arg)
 {
-       ILMonitorPool monitorPool;
        void *monitorLocation;
        int result;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&monitorPool);
+       /* initialize the test location */
        monitorLocation = 0;
 
-       result = ILMonitorEnter(&monitorPool, &monitorLocation);
+       result = ILMonitorEnter(&monitorLocation);
        if(result != IL_THREAD_OK)
        {
                ILUnitFailed("could not enter a new monitor");
        }
-       if(monitorPool.usedList == 0)
-       {
-               ILUnitFailed("new monitor is not on the used list in the pool");
-       }
        if(monitorLocation == 0)
        {
                ILUnitFailed("new monitor is not set at the monitor location");
        }
 
-       result = ILMonitorExit(&monitorPool, &monitorLocation);
+       result = ILMonitorExit(&monitorLocation);
        if(result != IL_THREAD_OK)
        {
                ILUnitFailed("could not exit a monitor");
        }
-       if(monitorPool.usedList != 0)
-       {
-               ILUnitFailed("monitor left is not removed from the used list in 
the pool");
-       }
-       if(monitorPool.freeList == 0)
-       {
-               ILUnitFailed("monitor left is not moved to the free list in the 
pool");
-       }
-       if(monitorLocation != 0)
-       {
-               ILUnitFailed("monitor location is not cleared");
-       }
-
-       ILMonitorPoolDestroy(&monitorPool);
 }
 
 /*
@@ -2498,51 +2486,32 @@ static void monitor_create(void *arg)
  */
 static void monitor_enter_multiple(void *arg)
 {
-       ILMonitorPool monitorPool;
        void *monitorLocation;
        int result;
        int i;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&monitorPool);
+       /* initialize the test location */
        monitorLocation = 0;
 
        for(i = 0; i < 10; ++i)
        {
-               result = ILMonitorEnter(&monitorPool, &monitorLocation);
+               result = ILMonitorEnter(&monitorLocation);
                if(result != IL_THREAD_OK)
                {
-                       ILMonitorPoolDestroy(&monitorPool);
                        ILUnitFailed("could not enter a new monitor at i = %i", 
i);
                }
        }
 
        for(i = 0; i < 10; ++i)
        {
-               result = ILMonitorExit(&monitorPool, &monitorLocation);
+               result = ILMonitorExit(&monitorLocation);
                if(result != IL_THREAD_OK)
                {
-                       ILMonitorPoolDestroy(&monitorPool);
                        ILUnitFailed("could not exit the new monitor at i = 
%i", i);
                }
        }
-       if(monitorPool.usedList != 0)
-       {
-               ILUnitFailed("monitor left is not removed from the used list in 
the pool");
-       }
-       if(monitorPool.freeList == 0)
-       {
-               ILUnitFailed("monitor left is not moved to the free list in the 
pool");
-       }
-       if(monitorLocation != 0)
-       {
-               ILUnitFailed("monitor location is not cleared");
-       }
-
-       ILMonitorPoolDestroy(&monitorPool);
 }
 
-ILMonitorPool _monitorPool;
 void *_monitorLocation;
 
 /*
@@ -2554,13 +2523,13 @@ static void _monitor_enter_locked(void *arg)
 
        monitorLocation = (void **)arg;
        _result = 1;
-       if(ILMonitorEnter(&_monitorPool, monitorLocation) != IL_THREAD_OK)
+       if(ILMonitorEnter(monitorLocation) != IL_THREAD_OK)
        {
                _result = 999;
                return;
        }
        _result = 2;
-       if(ILMonitorExit(&_monitorPool, monitorLocation) != IL_THREAD_OK)
+       if(ILMonitorExit(monitorLocation) != IL_THREAD_OK)
        {
                _result = 998;
        }
@@ -2573,14 +2542,11 @@ static void monitor_enter_locked(void *arg)
        int result1 = 0;
        int result2 = 0;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&_monitorPool);
+       /* initialize the test location */
        _monitorLocation = 0;
 
-       if((result = ILMonitorEnter(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       if((result = ILMonitorEnter(&_monitorLocation)) != IL_THREAD_OK)
        {
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
                ILUnitFailed("could not enter a new monitor");
        }
 
@@ -2588,9 +2554,7 @@ static void monitor_enter_locked(void *arg)
        thread = ILThreadCreate(_monitor_enter_locked, (void 
*)&_monitorLocation);
        if(!thread)
        {
-               ILMonitorExit(&_monitorPool, &_monitorLocation);
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
+               ILMonitorExit(&_monitorLocation);
                ILUnitOutOfMemory();
        }
 
@@ -2605,7 +2569,7 @@ static void monitor_enter_locked(void *arg)
        /* The result1 should be 1 now. */
        result1 = _result;
 
-       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       if((result = ILMonitorExit(&_monitorLocation)) != IL_THREAD_OK)
        {
                ILThreadDestroy(thread);
                ILUnitFailed("could not exit a monitor");
@@ -2624,22 +2588,6 @@ static void monitor_enter_locked(void *arg)
        {
                ILUnitFailed("lock on monitor enter doesn't work");
        }
-
-       if(_monitorPool.usedList != 0)
-       {
-               ILUnitFailed("monitor left is not removed from the used list in 
the pool");
-       }
-       if(_monitorPool.freeList == 0)
-       {
-               ILUnitFailed("monitor left is not moved to the free list in the 
pool");
-       }
-       if(_monitorLocation != 0)
-       {
-               ILUnitFailed("monitor location is not cleared");
-       }
-
-       /* Clean up the monitor pool */
-       ILMonitorPoolDestroy(&_monitorPool);
 }
 
 static void _monitor_tryenter_locked(void *arg)
@@ -2648,13 +2596,13 @@ static void _monitor_tryenter_locked(void *arg)
        int result;
 
        monitorLocation = (void **)arg;
-       result = ILMonitorTryEnter(&_monitorPool, monitorLocation);
+       result = ILMonitorTryEnter(monitorLocation);
        switch(result)
        {
                case IL_THREAD_OK:
                {
                        _result = 0;
-                       if(ILMonitorExit(&_monitorPool, monitorLocation) != 
IL_THREAD_OK)
+                       if(ILMonitorExit(monitorLocation) != IL_THREAD_OK)
                        {
                                _result = 998;
                        }
@@ -2683,14 +2631,11 @@ static void monitor_tryenter1(void *arg)
        int result = 0;
        int result1 = 0;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&_monitorPool);
+       /* initialize the test location */
        _monitorLocation = 0;           
 
-       if((result = ILMonitorEnter(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       if((result = ILMonitorEnter(&_monitorLocation)) != IL_THREAD_OK)
        {
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
                ILUnitFailed("could not enter a monitor");
        }
 
@@ -2698,9 +2643,7 @@ static void monitor_tryenter1(void *arg)
        thread = ILThreadCreate(_monitor_tryenter_locked, (void 
*)&_monitorLocation);
        if(!thread)
        {
-               ILMonitorExit(&_monitorPool, &_monitorLocation);
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
+               ILMonitorExit(&_monitorLocation);
                ILUnitOutOfMemory();
        }
 
@@ -2715,7 +2658,7 @@ static void monitor_tryenter1(void *arg)
        /* The result1 should be 1 now. */
        result1 = _result;
 
-       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       if((result = ILMonitorExit(&_monitorLocation)) != IL_THREAD_OK)
        {
                ILThreadDestroy(thread);
                ILUnitFailed("could not exit a monitor");
@@ -2729,22 +2672,6 @@ static void monitor_tryenter1(void *arg)
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("tryenter on a locked monitor doesn't work");
        }
-
-       if(_monitorPool.usedList != 0)
-       {
-               ILUnitFailed("monitor left is not removed from the used list in 
the pool");
-       }
-       if(_monitorPool.freeList == 0)
-       {
-               ILUnitFailed("monitor left is not moved to the free list in the 
pool");
-       }
-       if(_monitorLocation != 0)
-       {
-               ILUnitFailed("monitor location is not cleared");
-       }
-
-       /* Clean up the monitor pool */
-       ILMonitorPoolDestroy(&_monitorPool);
 }
 
 /*
@@ -2755,16 +2682,13 @@ static void monitor_tryenter2(void *arg)
        ILThread *thread;
        int result = 0;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&_monitorPool);
+       /* initialize the test location */
        _monitorLocation = 0;
 
        /* Create the thread */
        thread = ILThreadCreate(_monitor_tryenter_locked, (void 
*)&_monitorLocation);
        if(!thread)
        {
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
                ILUnitOutOfMemory();
        }
 
@@ -2786,9 +2710,6 @@ static void monitor_tryenter2(void *arg)
                printf("Wrong result is %i\n", result);
                ILUnitFailed("tryenter on a unlocked monitor doesn't work");
        }
-
-       /* Clean up the monitor pool */
-       ILMonitorPoolDestroy(&_monitorPool);
 }
 
 static void _monitor_timed_tryenter(void *arg)
@@ -2797,13 +2718,13 @@ static void _monitor_timed_tryenter(void *arg)
        int result;
 
        monitorLocation = (void **)arg;
-       result = ILMonitorTimedTryEnter(&_monitorPool, monitorLocation, 1);
+       result = ILMonitorTimedTryEnter(monitorLocation, 1);
        switch(result)
        {
                case IL_THREAD_OK:
                {
                        _result = 0;
-                       if(ILMonitorExit(&_monitorPool, monitorLocation) != 
IL_THREAD_OK)
+                       if(ILMonitorExit(monitorLocation) != IL_THREAD_OK)
                        {
                                _result = 998;
                        }
@@ -2829,14 +2750,11 @@ static void monitor_timed_tryenter1(void *arg)
        int result = 0;
        int result1 = 0;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&_monitorPool);
+       /* initialize the test location */
        _monitorLocation = 0;
 
-       if((result = ILMonitorEnter(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       if((result = ILMonitorEnter(&_monitorLocation)) != IL_THREAD_OK)
        {
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
                ILUnitFailed("could not enter a monitor");
        }
 
@@ -2844,9 +2762,7 @@ static void monitor_timed_tryenter1(void *arg)
        thread = ILThreadCreate(_monitor_timed_tryenter, (void 
*)&_monitorLocation);
        if(!thread)
        {
-               ILMonitorExit(&_monitorPool, (void *)&_monitorLocation);
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
+               ILMonitorExit((void *)&_monitorLocation);
                ILUnitOutOfMemory();
        }
 
@@ -2863,7 +2779,7 @@ static void monitor_timed_tryenter1(void *arg)
        /* Clean up the thread object (the thread itself is now dead) */
        ILThreadDestroy(thread);
 
-       if((result = ILMonitorExit(&_monitorPool, (void *)&_monitorLocation)) 
!= IL_THREAD_OK)
+       if((result = ILMonitorExit((void *)&_monitorLocation)) != IL_THREAD_OK)
        {
                ILThreadDestroy(thread);
                ILUnitFailed("could not exit a monitor");
@@ -2874,9 +2790,6 @@ static void monitor_timed_tryenter1(void *arg)
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("timed tryenter on a locked monitor with timeout 
doesn't work");
        }
-
-       /* Clean up the monitor pool */
-       ILMonitorPoolDestroy(&_monitorPool);
 }
 
 /*
@@ -2886,7 +2799,7 @@ static void _monitor_exit_unowned(void *arg)
 {
        void **monitorLocation = (void **)arg;
 
-       _result = ILMonitorExit(&_monitorPool, monitorLocation);
+       _result = ILMonitorExit(monitorLocation);
 }
 
 /*
@@ -2897,8 +2810,7 @@ static void monitor_exit_unowned(void *arg)
        int result = 0;
        ILThread *thread;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&_monitorPool);
+       /* initialize the test location */
        _monitorLocation = 0;           
 
        /* Create the thread */
@@ -2908,7 +2820,7 @@ static void monitor_exit_unowned(void *arg)
                ILUnitOutOfMemory();
        }
 
-       result = ILMonitorEnter(&_monitorPool, &_monitorLocation);
+       result = ILMonitorEnter(&_monitorLocation);
        if(result != IL_THREAD_OK)
        {
                ILUnitFailed("could not enter a new monitor");
@@ -2928,19 +2840,16 @@ static void monitor_exit_unowned(void *arg)
 
        if(_result != IL_THREAD_ERR_SYNCLOCK)
        {
-               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               ILMonitorExit(&_monitorLocation);
                printf("Wrong result is %i\n", _result);
                ILUnitFailed("exiting an unowned monitor returned the wrong 
result");
        }
 
-       result = ILMonitorExit(&_monitorPool, &_monitorLocation);
+       result = ILMonitorExit(&_monitorLocation);
        if(result)
        {
                ILUnitFailed("could not exit a monitor");
        }
-
-       /* Clean up the monitor pool */
-       ILMonitorPoolDestroy(&_monitorPool);
 }
 
 static void _monitor_wait1(void *arg)
@@ -2950,7 +2859,7 @@ static void _monitor_wait1(void *arg)
 
        monitorLocation = (void **)arg;
        _result = 0;
-       result = ILMonitorEnter(&_monitorPool, monitorLocation);
+       result = ILMonitorEnter(monitorLocation);
        switch(result)
        {
                case IL_THREAD_OK:
@@ -2959,11 +2868,11 @@ static void _monitor_wait1(void *arg)
                        if(ILMonitorPulse(monitorLocation) == IL_THREAD_OK)
                        {
                                result = 997;
-                               ILMonitorExit(&_monitorPool, monitorLocation);
+                               ILMonitorExit(monitorLocation);
                        }
                        else
                        {
-                               if(ILMonitorExit(&_monitorPool, 
monitorLocation) == IL_THREAD_OK)
+                               if(ILMonitorExit(monitorLocation) == 
IL_THREAD_OK)
                                {
                                        _result = 998;
                                }
@@ -2985,14 +2894,11 @@ static void monitor_wait1(void *arg)
        int result1 = 0;
        int result2 = 0;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&_monitorPool);
+       /* initialize the test location */
        _monitorLocation = 0;           
 
-       if(ILMonitorEnter(&_monitorPool, &_monitorLocation) != IL_THREAD_OK)
+       if(ILMonitorEnter(&_monitorLocation) != IL_THREAD_OK)
        {
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
                ILUnitFailed("could not enter a monitor");
        }
 
@@ -3000,9 +2906,7 @@ static void monitor_wait1(void *arg)
        thread = ILThreadCreate(_monitor_wait1, (void *)&_monitorLocation);
        if(!thread)
        {
-               ILMonitorExit(&_monitorPool, &_monitorLocation);
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
+               ILMonitorExit(&_monitorLocation);
                ILUnitOutOfMemory();
        }
 
@@ -3021,9 +2925,7 @@ static void monitor_wait1(void *arg)
        {
                /* Clean up the thread object. */
                ILThreadDestroy(thread);
-               ILMonitorExit(&_monitorPool, &_monitorLocation);
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
+               ILMonitorExit(&_monitorLocation);
                ILUnitFailed("wait on a monitor doesn't work");
        }
 
@@ -3038,17 +2940,13 @@ static void monitor_wait1(void *arg)
 
        if(result1 != 0)
        {
-               ILMonitorExit(&_monitorPool, &_monitorLocation);
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
+               ILMonitorExit(&_monitorLocation);
                printf("Wrong result is %i\n", result1);
                ILUnitFailed("tryenter on a locked monitor doesn't work");
        }
 
-       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       if((result = ILMonitorExit(&_monitorLocation)) != IL_THREAD_OK)
        {
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
                ILUnitFailed("could not exit a monitor");
        }
 
@@ -3056,9 +2954,6 @@ static void monitor_wait1(void *arg)
        {
                ILUnitFailed("testcase failed");
        }
-
-       /* Clean up the monitor pool */
-       ILMonitorPoolDestroy(&_monitorPool);
 }
 
 static void _monitor_timed_wait1(void *arg)
@@ -3068,7 +2963,7 @@ static void _monitor_timed_wait1(void *arg)
 
        monitorLocation = (void **)arg;
        _result = 0;
-       result = ILMonitorEnter(&_monitorPool, monitorLocation);
+       result = ILMonitorEnter(monitorLocation);
        switch(result)
        {
                case IL_THREAD_OK:
@@ -3079,18 +2974,18 @@ static void _monitor_timed_wait1(void *arg)
                        if(ILMonitorPulse(monitorLocation) != IL_THREAD_OK)
                        {
                                result = 997;
-                               ILMonitorExit(&_monitorPool, monitorLocation);
+                               ILMonitorExit(monitorLocation);
                        }
                        else
                        {
-                               if(ILMonitorExit(&_monitorPool, 
monitorLocation) != IL_THREAD_OK)
+                               if(ILMonitorExit(monitorLocation) != 
IL_THREAD_OK)
                                {
                                        _result = 998;
                                }
                                else
                                {
                                        sleepFor(1);
-                                       if((result = 
ILMonitorTryEnter(&_monitorPool, monitorLocation)) == IL_THREAD_BUSY)
+                                       if((result = 
ILMonitorTryEnter(monitorLocation)) == IL_THREAD_BUSY)
                                        {
                                                _result = 3;
                                        }
@@ -3099,7 +2994,7 @@ static void _monitor_timed_wait1(void *arg)
                                                if(result == IL_THREAD_OK)
                                                {
                                                        _result = 996;
-                                                       
ILMonitorExit(&_monitorPool, monitorLocation);
+                                                       
ILMonitorExit(monitorLocation);
                                                }
                                                else
                                                {
@@ -3125,11 +3020,10 @@ static void monitor_timed_wait1(void *arg)
        int result1 = 0;
        int result2 = 0;
 
-       /* initialize the monitor pool and the test location */
-       ILMonitorPoolInit(&_monitorPool);
+       /* initialize the test location */
        _monitorLocation = 0;           
 
-       if(ILMonitorEnter(&_monitorPool, &_monitorLocation) != IL_THREAD_OK)
+       if(ILMonitorEnter(&_monitorLocation) != IL_THREAD_OK)
        {
                ILUnitFailed("could not enter a monitor");
        }
@@ -3138,9 +3032,7 @@ static void monitor_timed_wait1(void *arg)
        thread = ILThreadCreate(_monitor_timed_wait1, (void 
*)&_monitorLocation);
        if(!thread)
        {
-               ILMonitorExit(&_monitorPool, &_monitorLocation);
-               /* Clean up the monitor pool */
-               ILMonitorPoolDestroy(&_monitorPool);
+               ILMonitorExit(&_monitorLocation);
                ILUnitOutOfMemory();
        }
 
@@ -3180,7 +3072,7 @@ static void monitor_timed_wait1(void *arg)
                ILUnitFailed("tryenter on a locked monitor doesn't work");
        }
 
-       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       if((result = ILMonitorExit(&_monitorLocation)) != IL_THREAD_OK)
        {
                ILUnitFailed("could not exit a monitor");
        }
@@ -3189,9 +3081,289 @@ static void monitor_timed_wait1(void *arg)
        {
                ILUnitFailed("testcase failed");
        }
+}
+
+static void _monitor_enter(void *arg)
+{
+       void **monitorLocation;
+
+       monitorLocation = (void **)arg;
+       _result = 0;
+       _result = ILMonitorEnter(monitorLocation);
+}
+
+static void monitor_interrupt_during_enter(void *arg)
+{
+       ILThread *thread;
+       int haveError = 0;
+       int result = 0;
+       int result1 = 0;
+
+       /* initialize the test location */
+       _monitorLocation = 0;
+
+       if(ILMonitorEnter(&_monitorLocation) != IL_THREAD_OK)
+       {
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_enter, (void *)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorLocation);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 2 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 0 now. */
+       result1 = _result;
+
+       /* interrupt the thread */
+       ILThreadInterrupt(thread);
+       
+       if((result = ILThreadJoin(thread, 10000)) != IL_JOIN_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Failed to join thread with returncode %i", 
result);
+       }
+
+       ILThreadDestroy(thread);
 
-       /* Clean up the monitor pool */
-       ILMonitorPoolDestroy(&_monitorPool);
+       if(_result != IL_THREAD_ERR_INTERRUPT)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Wrong returncode for abort during enter was 
%i", result);
+       }
+       ILMonitorExit(&_monitorLocation);
+       if(haveError)
+       {
+               ILUnitFailEndMessages();
+       }
+}
+
+static void monitor_abort_during_enter(void *arg)
+{
+       ILThread *thread;
+       int haveError = 0;
+       int result = 0;
+       int result1 = 0;
+
+       /* initialize the test location */
+       _monitorLocation = 0;
+
+       if(ILMonitorEnter(&_monitorLocation) != IL_THREAD_OK)
+       {
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_enter, (void *)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorLocation);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 2 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 0 now. */
+       result1 = _result;
+
+       /* Abort the thread */
+       result = ILThreadAbort(thread);
+       
+       if((result = ILThreadJoin(thread, 10000)) != IL_JOIN_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Failed to join thread with returncode %i", 
result);
+       }
+
+       ILThreadDestroy(thread);
+
+       if(_result != IL_THREAD_ERR_ABORTED)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Wrong returncode for abort during enter was 
%i", result);
+       }
+       ILMonitorExit(&_monitorLocation);
+       if(haveError)
+       {
+               ILUnitFailEndMessages();
+       }
+}
+
+static void _monitor_wait(void *arg)
+{
+       void **monitorLocation = (void **)arg;
+
+       /* First enter the monitor for this location */
+       if(ILMonitorEnter(monitorLocation) != IL_THREAD_OK)
+       {
+               _result = 999;
+               return;
+       }
+       /* Now pulse the monitor to releaase the main thread */
+       if(ILMonitorPulse(monitorLocation)  != IL_THREAD_OK)
+       {
+               _result = 998;
+               return;
+       }
+       /*
+        * Wait 2 time steps to give the main thread the possibility to
+        * run again and get the pulsed signal.
+        */
+       sleepFor(2);
+
+       /* Wait on the monitor */
+       _result = ILMonitorWait(monitorLocation);
+       
+       /* And exit the monitor again */
+       if(ILMonitorExit(monitorLocation) != IL_THREAD_OK)
+       {
+               _result = 996;
+       }
+}
+
+static void monitor_interrupt_during_wait(void *arg)
+{
+       ILThread *thread;
+       int haveError = 0;
+       int result = 0;
+
+       /* initialize the test location */
+       _monitorLocation = 0;
+
+       if(ILMonitorEnter(&_monitorLocation) != IL_THREAD_OK)
+       {
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_wait, (void *)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorLocation);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* And wait on the monitor */
+       if((result = ILMonitorWait(&_monitorLocation)) != IL_THREAD_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Wait on the monitor failed with returncode 
%i", result);
+       }
+       
+       /* interrupt the thread while it is waiting on the monitor*/
+       ILThreadInterrupt(thread);
+       
+       /* And exit the monitor */
+       if((result = ILMonitorExit(&_monitorLocation)) != IL_THREAD_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Exiting the monitor failed with returncode 
%i", result);
+       }
+       
+       if((result = ILThreadJoin(thread, 10000)) != IL_JOIN_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Failed to join thread with returncode %i", 
result);
+       }
+
+       ILThreadDestroy(thread);
+
+       if(_result != IL_THREAD_ERR_INTERRUPT)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Wrong returncode for interrupt during wait 
was %i", _result);
+       }
+
+       if(haveError)
+       {
+               ILUnitFailEndMessages();
+       }
+}
+
+static void monitor_abort_during_wait(void *arg)
+{
+       ILThread *thread;
+       int haveError = 0;
+       int result = 0;
+
+       /* initialize the test location */
+       _monitorLocation = 0;
+
+       if(ILMonitorEnter(&_monitorLocation) != IL_THREAD_OK)
+       {
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_wait, (void *)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorLocation);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* And wait on the monitor */
+       if((result = ILMonitorWait(&_monitorLocation)) != IL_THREAD_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Wait on the monitor failed with returncode 
%i", result);
+       }
+       
+       /* interrupt the thread while it is waiting on the monitor*/
+       ILThreadAbort(thread);
+       
+       /* And exit the monitor */
+       if((result = ILMonitorExit(&_monitorLocation)) != IL_THREAD_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Exiting the monitor failed with returncode 
%i", result);
+       }
+       
+       if((result = ILThreadJoin(thread, 10000)) != IL_JOIN_OK)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Failed to join thread with returncode %i", 
result);
+       }
+
+       ILThreadDestroy(thread);
+
+       if(_result != IL_THREAD_ERR_ABORTED)
+       {
+               haveError = 1;
+               ILUnitFailMessage("Wrong returncode for abort during wait was 
%x", _result);
+       }
+
+       if(haveError)
+       {
+               ILUnitFailEndMessages();
+       }
 }
 
 /*
@@ -3304,7 +3476,13 @@ void ILUnitRegisterTests(void)
        ILUnitRegisterSuite("Monitor primitives Tests");
        RegisterSimple(primitive_monitor_create);
        RegisterSimple(primitive_monitor_enter);
+#ifndef IL_USE_PTHREADS
+       /*
+        * Disable this tests for pthreads because the the behavior is
+        * unpredictable on this platform.
+        */
        RegisterSimple(primitive_monitor_exit_unowned);
+#endif /* !IL_USE_PTHREADS */
        RegisterSimple(primitive_monitor_enter1);
        RegisterSimple(primitive_monitor_tryenter1);
        RegisterSimple(primitive_monitor_tryenter2);
@@ -3333,6 +3511,10 @@ void ILUnitRegisterTests(void)
        RegisterSimple(monitor_exit_unowned);
        RegisterSimple(monitor_wait1);
        RegisterSimple(monitor_timed_wait1);
+       RegisterSimple(monitor_interrupt_during_enter);
+       RegisterSimple(monitor_abort_during_enter);
+       RegisterSimple(monitor_interrupt_during_wait);
+       RegisterSimple(monitor_abort_during_wait);
 }
 
 void ILUnitCleanupTests(void)

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

Summary of changes:
 ChangeLog            |   65 ++++
 configure.in         |    5 +-
 engine/engine.h      |    5 +
 engine/lib_monitor.c |  436 ++-----------------------
 engine/lib_thread.c  |    9 +-
 engine/thread.c      |   54 +++-
 support/monitor.c    |  432 +++++++++++++++++++------
 support/no_defs.c    |   59 +++-
 support/no_defs.h    |   27 ++-
 support/pt_defs.c    |  757 ++++++++++++++++++++++++++++++++----------
 support/pt_defs.h    |  119 ++++++-
 support/thr_defs.h   |  236 ++++++++++----
 support/thread.c     |  896 ++++++++++++++++++++++++++++----------------------
 support/w32_defs.c   |  273 +++++++++++----
 support/w32_defs.h   |   85 ++++-
 support/wait.c       |  154 +++++----
 support/wait_event.c |   22 +-
 support/wait_mutex.c |   74 ++--
 support/wait_mutex.h |   16 +-
 tests/test_thread.c  |  556 +++++++++++++++++++++-----------
 20 files changed, 2704 insertions(+), 1576 deletions(-)
 mode change 100644 => 100755 support/monitor.c
 mode change 100644 => 100755 support/thread.c


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




reply via email to

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