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. 0a670419df553f7bbe3890f87fa9ed8c25744d47
Date: Tue, 01 Sep 2009 17:42:22 +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  0a670419df553f7bbe3890f87fa9ed8c25744d47 (commit)
      from  e7b771770b514589ee8a7c84781fd17ef7ceaf8a (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=0a670419df553f7bbe3890f87fa9ed8c25744d47

commit 0a670419df553f7bbe3890f87fa9ed8c25744d47
Author: Klaus Treichel <address@hidden>
Date:   Tue Sep 1 19:16:47 2009 +0200

    Add syncronization monitor implementation.

diff --git a/ChangeLog b/ChangeLog
index ba0e242..08c90c0 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,51 @@
+2009-09-01  Klaus Treichel  <address@hidden>
+
+       * configure.in: Add checks for availability of pthread_mutex_timedlock,
+       sem_timedwait and pthread_cond_timedwait.
+
+       * support/Makefile.am: Add monitor.c to the sources.
+
+       * support/monitor.c: Add monitor implementation.
+
+       * support/no_defs.c (_ILMonitorTimedWait): Add dummy implementation that
+       simply calls the predicate function.
+
+       * support/no_defs.h: Add macros for the dummy monitor implementation.
+
+       * support/pt_defs.c: Add pthread monitor implementation Add replacements
+       for pthread_mutex_timedlock and sem_timedwait if not available.
+       (_ILCondMutexTimedLockUnsafe): Added
+       (_ILSemaphoreTimedWait): Added
+       (_ILCountSemaphoreSignalCount): Added
+       (_ILCountSemaphoreSignalAll): Added
+       (_ILCountSemaphoreTimedWait): Added
+
+       * support/pt_defs.h: Add declarations for _ILCountSemaphore and
+       _ILMonitor.
+
+       * support/thr_defs.h: Add first threading error codes.
+       Rename the current ILMonitor to ILWaitMonitor because it's not a real
+       monitor implementation.
+       Add declarations for the conforming monitor implementation.
+
+       * support/w32_defs.c (_ILWaitHandleTimedWait): Added
+       (_ILCountSemaphoreSignalCount): Added
+       (_ILCountSemaphoreSignalAll): Added
+       (_ILCountSemaphoreTimedWait): Added
+       Add windows monitor implementation.
+
+       * support/w32_defs.h: Add declarations for _ILCountSemaphore and
+       _ILMonitor.
+
+       * support/wait_mutex.c: Rename the occurances of ILMonitor to
+       ILWaitMonitor.
+
+       * tests/Makefile.am: Add additional include directries to AM_FLAGS
+       needed for the additional tests.
+
+       * tests/test_thread.c: Add first tests for the monitor primitives and
+       the monitor implementation.
+
 2009-08-13  Klaus Treichel  <address@hidden>
 
        * cscc/csharp/cs_gather.c (AddImplementedInterface): Add helper function
diff --git a/configure.in b/configure.in
index 9c6d804..0f44ddc 100644
--- a/configure.in
+++ b/configure.in
@@ -619,7 +619,7 @@ AC_CHECK_FUNCS(stat lstat vfprintf waitpid wait fork execv 
open)
 AC_CHECK_FUNCS(getpid qsort unlink remove getcwd getwd)
 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 rint trunc)
+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)
@@ -676,6 +676,7 @@ fi
 
 dnl Add the thread libraries to the end of the link line.
 LIBS="$LIBS $THREADLIBS"
+AC_CHECK_FUNCS(pthread_mutex_timedlock sem_timedwait pthread_cond_timedwait)
 
 dnl Determine if we should compile in the tools.
 AC_ARG_ENABLE(tools,
diff --git a/support/Makefile.am b/support/Makefile.am
index 83af9e5..7677011 100644
--- a/support/Makefile.am
+++ b/support/Makefile.am
@@ -46,6 +46,7 @@ libILSupport_a_SOURCES = aes.c \
                                                 memory.c \
                                                 mempool.c \
                                                 memstack.c \
+                                                monitor.c \
                                                 mul_long.c \
                                                 mutex.c \
                                                 no_defs.c \
diff --git a/support/monitor.c b/support/monitor.c
new file mode 100644
index 0000000..3c285ab
--- /dev/null
+++ b/support/monitor.c
@@ -0,0 +1,393 @@
+/*
+ * monitor.c - Syncronization Monitor routines.
+ *
+ * Copyright (C) 2009  Southern Storm Software, Pty Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*
+ * This is the generic code for monitor support for all pattforms.
+ * The patform dependent code in in the *_defs files.
+ */
+
+#include <il_utils.h>
+#include "thr_defs.h"
+#include "interlocked.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+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 */
+       ILUInt32                        users;          /* The number of 
threads using this monitor */
+       _ILMonitor                      monitor;        /* The platform 
dependent monitor */
+};
+
+static void ILMonitorInit(ILMonitor *monitor)
+{
+       monitor->next = 0;
+       monitor->owner = 0;
+       monitor->enterCount = 0;
+       monitor->users = 0;
+       _ILMonitorCreate(&(monitor->monitor));
+}
+
+static void ILMonitorDestroy(ILMonitor *monitor)
+{
+       monitor->next = 0;
+       monitor->owner = 0;
+       monitor->enterCount = 0;
+       monitor->users = 0;
+       _ILMonitorDestroy(&(monitor->monitor));
+}
+
+static void DestroyMonitorList(ILMonitor *monitor)
+{
+       while(monitor)
+       {
+               ILMonitor *next;
+
+               next = monitor->next;
+               ILMonitorDestroy(monitor);
+               monitor = next;
+       }
+}
+
+void ILMonitorPoolInit(ILMonitorPool *pool)
+{
+       if(!pool)
+       {
+               return;
+       }
+       ILMemPoolInitType(&(pool->pool), ILMonitor, 20);
+       pool->freeList = 0;
+       pool->usedList = 0;
+       _ILMutexCreate(&(pool->lock));
+}
+
+void ILMonitorPoolDestroy(ILMonitorPool *pool)
+{
+       if(!pool)
+       {
+               return;
+       }
+       DestroyMonitorList(pool->freeList);
+       pool->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.
+        */
+       DestroyMonitorList(pool->usedList);
+       pool->usedList = 0;
+       _ILMutexDestroy(&(pool->lock));
+       ILMemPoolDestroy(&(pool->pool));
+}
+
+/*
+ * Get a new monitor from the monitor pool.
+ * This function must be called with the monitorpool lock held.
+ */
+static ILMonitor *ILMonitorPoolAllocMonitor(ILMonitorPool *pool)
+{
+       ILMonitor *monitor;
+
+       if(pool->freeList)
+       {
+               /* We have a monitor on the freelist so reuse this one */
+               monitor = pool->freeList;
+               pool->freeList = monitor->next;
+               /* And add the monitor to the used list */
+               monitor->next = pool->usedList;
+               pool->usedList = monitor;
+       }
+       else
+       {
+               monitor = ILMemPoolAllocItem(&(pool->pool));
+               if(monitor)
+               {
+                       ILMonitorInit(monitor);
+                       /* And add the monitor to the used list */
+                       monitor->next = pool->usedList;
+                       pool->usedList = monitor;
+               }
+       }
+       return monitor;
+}
+
+/*
+ * 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)
+{
+       if(pool->usedList == monitor)
+       {
+               pool->usedList = monitor->next;
+               monitor->next = pool->freeList;
+               pool->freeList = monitor;
+       }
+       else
+       {
+               ILMonitor *prevMonitor;
+
+               prevMonitor = pool->usedList;
+               while(prevMonitor)
+               {
+                       if(prevMonitor->next == monitor)
+                       {
+                               prevMonitor->next = monitor->next;
+                               monitor->next = pool->freeList;
+                               pool->freeList = monitor;
+                               return;
+                       }
+                       prevMonitor = prevMonitor->next;
+               }
+       }
+}
+
+int ILMonitorTimedTryEnter(ILMonitorPool *pool, void **monitorLocation,
+                                                  ILUInt32 ms)
+{
+       ILMonitor * volatile *monLoc;
+       ILMonitor *monitor;
+       ILThread *thread;
+
+       if(!pool || !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)
+       {
+               /*
+                * I'm already the owner of this monitor.
+                * So simply increase the enter count.
+                */
+               ++(monitor->enterCount);
+       }
+       else
+       {
+               /*
+                * We have to enter the monitor.
+                */
+               int result;
+
+               result = _ILMonitorTimedTryEnter(&(monitor->monitor), ms);
+               if(result == IL_THREAD_OK)
+               {
+                       /*
+                        * The owner should be 0 at this point.
+                        */
+                       monitor->owner = thread;
+                       monitor->enterCount = 1;
+               }
+               else
+               {
+                       /* We have to leave the monitor again */
+                       _ILMutexLock(&(pool->lock));
+
+                       /* Remove me from the monitor users */
+                       --(monitor->users);
+                       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);
+                               /* And clear the monitor location */
+                               *monitorLocation = 0;
+                       }
+                       _ILMutexUnlock(&(pool->lock));
+               }
+               return result;
+       }
+       return IL_THREAD_OK;
+}
+
+int ILMonitorExit(ILMonitorPool *pool, void **monitorLocation)
+{
+       ILMonitor * volatile *monLoc;
+       ILMonitor *monitor;
+       ILThread *thread;
+
+       if(!pool || !monitorLocation)
+       {
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       /* Store the location in a volatile variable */
+       monLoc = (ILMonitor **)monitorLocation;
+       if((monitor = *monLoc) == 0)
+       {
+               return IL_THREAD_ERR_SYNCLOCK;
+       }
+       thread = _ILThreadGetSelf();
+       if(monitor->owner != thread)
+       {
+               return IL_THREAD_ERR_SYNCLOCK;
+       }
+       /* Decrement the enter count */
+       --(monitor->enterCount);
+       if(monitor->enterCount <= 0)
+       {
+               /* We really are leaving the monitor */
+               _ILMutexLock(&(pool->lock));
+
+               /* Remove me from the monitor users */
+               --(monitor->users);
+               /* Clear the owner */
+               monitor->owner = 0;
+               monitor->enterCount = 0;
+               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);
+                       /* And clear the monitor location */
+                       *monitorLocation = 0;
+               }
+               _ILMonitorExit(&(monitor->monitor));
+               _ILMutexUnlock(&(pool->lock));
+       }
+       return IL_THREAD_OK;
+}
+
+int ILMonitorPulse(void **monitorLocation)
+{
+       ILMonitor *monitor;
+       ILThread *thread;
+
+       if(!monitorLocation)
+       {
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       if((monitor = (ILMonitor *)(*monitorLocation)) == 0)
+       {
+               return IL_THREAD_ERR_SYNCLOCK;
+       }
+       thread = _ILThreadGetSelf();
+       if(monitor->owner != thread)
+       {
+               return IL_THREAD_ERR_SYNCLOCK;
+       }
+       _ILMonitorPulse(&(monitor->monitor));
+       return IL_THREAD_OK;
+}
+
+int ILMonitorPulseAll(void **monitorLocation)
+{
+       ILMonitor *monitor;
+       ILThread *thread;
+
+       if(!monitorLocation)
+       {
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       if((monitor = (ILMonitor *)(*monitorLocation)) == 0)
+       {
+               return IL_THREAD_ERR_SYNCLOCK;
+       }
+       thread = _ILThreadGetSelf();
+       if(monitor->owner != thread)
+       {
+               return IL_THREAD_ERR_SYNCLOCK;
+       }
+       _ILMonitorPulseAll(&(monitor->monitor));
+       return IL_THREAD_OK;
+}
+
+/*
+ * Predicate function for monitor wait.
+ */
+static int MonitorPredicate(void *mon)
+{
+       ILMonitor *monitor;
+       ILThread *thread;
+
+       monitor = (ILMonitor *)mon;
+       thread = _ILThreadGetSelf();
+       ILInterlockedCompareAndExchangePointers((void **)&(monitor->owner),
+                                                                               
        thread, 0);
+       return (monitor->owner == thread);
+}
+
+int ILMonitorTimedWait(void **monitorLocation, ILUInt32 ms)
+{
+       ILMonitor *monitor;
+       ILThread *thread;
+       int result;
+       ILUInt32 enterCount;
+
+       if(!monitorLocation)
+       {
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       thread = _ILThreadGetSelf();
+       monitor = (ILMonitor *)(*monitorLocation);
+       if(!monitor || monitor->owner != thread)
+       {
+               return IL_THREAD_ERR_SYNCLOCK;
+       }
+       /*
+        * Save the number of times this thread entered the monitor and reset
+        + the value in the monitor
+        */
+       enterCount = monitor->enterCount;
+       monitor->enterCount = 0;
+       result = _ILMonitorTimedWait(&(monitor->monitor), ms, MonitorPredicate, 
monitor);
+       if(result == IL_THREAD_OK || result == IL_THREAD_BUSY)
+       {
+               monitor->enterCount = enterCount;
+               monitor->owner = thread;
+       }
+       return result;
+}
+
+#ifdef __cplusplus
+};
+#endif
diff --git a/support/no_defs.c b/support/no_defs.c
index b33c9a3..d3ca605 100644
--- a/support/no_defs.c
+++ b/support/no_defs.c
@@ -94,6 +94,16 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms)
 #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
old mode 100644
new mode 100755
index 3882479..6882d30
--- a/support/no_defs.h
+++ b/support/no_defs.h
@@ -35,6 +35,7 @@ typedef int   _ILThreadHandle;
 typedef int    _ILThreadIdentifier;
 typedef int    _ILSemaphore;
 typedef int    _ILRWLock;
+typedef int _ILMonitor;
 
 /*
  * This is not a real thread package.
@@ -78,7 +79,8 @@ typedef int   _ILRWLock;
  */
 #define        _ILCondMutexCreate(mutex)               do { *(mutex) = 0; } 
while (0)
 #define        _ILCondMutexDestroy(mutex)              do { ; } while (0)
-#define        _ILCondMutexLockUnsafe(mutex)   do { ; } while (0)
+#define        _ILCondMutexLockUnsafe(mutex)           (IL_THREAD_OK)
+#define        _ILCondMutexTryLockUnsafe(mutex)        (IL_THREAD_OK)
 #define        _ILCondMutexUnlockUnsafe(mutex) do { ; } while (0)
 
 /*
@@ -107,6 +109,23 @@ typedef int        _ILRWLock;
 #define        _ILCondVarSignal(cond)          do { ; } while (0)
 int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex *mutex, ILUInt32 ms);
 
+
+/*
+ * Primitive monitor operations.
+ */
+#define        _ILMonitorCreate(mon)                           IL_THREAD_OK
+#define        _ILMonitorDestroy(mon)                          IL_THREAD_OK
+#define        _ILMonitorPulse(mon)                            IL_THREAD_OK
+#define        _ILMonitorPulseAll(mon)                         IL_THREAD_OK
+#define        _ILMonitorTimedTryEnter(mon, ms)        IL_THREAD_OK
+#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))
+
 /*
  * Get or set the thread object that is associated with "self".
  */
diff --git a/support/pt_defs.c b/support/pt_defs.c
old mode 100644
new mode 100755
index 15d4635..bb60fcd
--- a/support/pt_defs.c
+++ b/support/pt_defs.c
@@ -291,9 +291,121 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms)
 }
 
 /*
- * Increase the semaphore count by count to release count threads waiting
- * at the semaphore.
+ * Define some functions from the Timeouts options that need not be provided
+ * in all implementations.
  */
+
+#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+int pthread_mutex_timedlock (pthread_mutex_t *mutex,
+                           const struct timespec *abs_timeout)
+{
+       struct timeval tv;
+       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 = pthread_mutex_trylock(mutex)) == EBUSY)
+       {
+               gettimeofday(&tv, NULL);
+               
+               if(tv.tv_sec >= abs_timeout->tv_sec &&
+                   (tv.tv_usec * 1000) >= abs_timeout->tv_nsec)
+               {
+                       return ETIMEDOUT;
+               }
+               nanosleep(&ts, NULL);
+       }
+       return retcode;
+}
+#endif /* !HAVE_PTHREAD_MUTEX_TIMEDLOCK */
+
+#ifndef HAVE_SEM_TIMEDWAIT
+int sem_timedwait(sem_t *sem,
+                                 const struct timespec *abs_timeout)
+{
+       struct timeval tv;
+       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)
+       {
+               gettimeofday(&tv, NULL);
+               
+               if(tv.tv_sec >= abs_timeout->tv_sec &&
+                   (tv.tv_usec * 1000) >= abs_timeout->tv_nsec)
+               {
+                       return ETIMEDOUT;
+               }
+               nanosleep(&ts, NULL);
+       }
+       return retcode;
+}
+#endif /* !HAVE_SEM_TIMEDWAIT */
+
+int _ILCondMutexTimedLockUnsafe(_ILCondMutex *mutex, ILUInt32 ms)
+{
+       if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
+       {
+               int result;
+
+               if(ms == IL_MAX_UINT32)
+               {
+                       /* This is the same as the call to 
_ILCondMutexLockUnsafe. */
+                       result = pthread_mutex_lock(mutex);
+               }
+               else if(ms == 0)
+               {
+                       /* This is the same as the call to _ILCondMutexTryLock. 
*/
+                       result = pthread_mutex_trylock(mutex);
+               }
+               else
+               {
+                       struct timeval tv;
+                       struct timespec ts;
+
+                       gettimeofday(&tv, 0);
+                       ts.tv_sec = tv.tv_sec + (long)(ms / 1000);
+                       ts.tv_nsec = (tv.tv_usec + (long)((ms % 1000) * 1000)) 
* 1000L;
+                       if(ts.tv_nsec >= 1000000000L)
+                       {
+                               ++(ts.tv_sec);
+                               ts.tv_nsec -= 1000000000L;
+                       }
+                       result = pthread_mutex_timedlock(mutex, &ts);
+               }
+               switch(result)
+               {
+                       case 0:
+                       {
+                               return IL_THREAD_OK;
+                       }
+                       break;
+
+                       case EBUSY:
+                       case ETIMEDOUT:
+                       {
+                               return IL_THREAD_BUSY;
+                       }
+                       break;
+               }
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       else
+       {
+               /* Invalid negative value for ms. */
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
 int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 count)
 {
        if((count > 0) && (count < IL_MAX_INT32))
@@ -304,12 +416,359 @@ int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 
count)
                {
                        if(sem_post(sem))
                        {
-                               return 0;
+                               /* An error occured. */
+                               return IL_THREAD_ERR_UNKNOWN;
                        }
                }
-               return 1;
+               return IL_THREAD_OK;
+       }
+       /* Invalid value for the release count. */
+       return IL_THREAD_ERR_INVALID_RELEASECOUNT;
+}
+
+int _ILSemaphoreTimedWait(_ILSemaphore *sem, ILUInt32 ms, ILInt32 
interruptable)
+{
+       if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
+       {
+               int result;
+
+               if(ms == IL_MAX_UINT32)
+               {
+                       /* This is the same as the call to _ILSemaphoreWait. */
+                       do
+                       {
+                               result = sem_wait(sem);
+                       } while(!interruptable && (result == EINTR));
+               }
+               else if(ms == 0)
+               {
+                       /* This is the same as the call to _ILSemaphoreTryWait. 
*/
+                       do
+                       {
+                               result = sem_trywait(sem);
+                       } while(!interruptable && (result == EINTR));
+               }
+               else
+               {
+                       struct timeval tv;
+                       struct timespec ts;
+
+                       gettimeofday(&tv, 0);
+                       ts.tv_sec = tv.tv_sec + (long)(ms / 1000);
+                       ts.tv_nsec = (tv.tv_usec + (long)((ms % 1000) * 1000)) 
* 1000L;
+                       if(ts.tv_nsec >= 1000000000L)
+                       {
+                               ++(ts.tv_sec);
+                               ts.tv_nsec -= 1000000000L;
+                       }
+                       do
+                       {
+                               result = sem_timedwait(sem, &ts);
+                       } while(!interruptable && (result == EINTR));
+               }
+               switch(result)
+               {
+                       case 0:
+                       {
+                               return IL_THREAD_OK;
+                       }
+                       break;
+
+                       case EINTR:
+                       {
+                               return IL_THREAD_ERR_INTERRUPT;
+                       }
+                       break;
+
+                       case EAGAIN:
+                       case ETIMEDOUT:
+                       {
+                               return IL_THREAD_BUSY;
+                       }
+                       break;
+               }
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       else
+       {
+               /* Invalid negative value for ms. */
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
+/*
+ * Release a number of waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalCount(_ILCountSemaphore *sem, ILUInt32 count)
+{
+       int result = IL_THREAD_OK;
+
+       if((count > 0) && (count <= IL_MAX_INT32))
+       {
+               ILUInt32 current;
+
+               /* Lock the count semaphore object. */
+               _ILMutexLock(&(sem->_lock));
+
+               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
+       {
+               /* Invalid value for the release count. */
+               result = IL_THREAD_ERR_INVALID_RELEASECOUNT;
+       }
+       return result;
+}
+
+/*
+ * Release all waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalAll(_ILCountSemaphore *sem)
+{
+       int result = IL_THREAD_OK;
+
+       if(sem->_waiting > 0)
+       {
+               /* Lock the count semaphore object. */
+               _ILMutexLock(&(sem->_lock));
+
+               /* We have to recheck because of possible race conditions. */
+               while(sem->_waiting > 0)
+               {
+                       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));
+       }
+       return result;
+}
+
+/*
+ * Wait on a count semaphore.
+ */
+int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, ILUInt32 ms)
+{
+       if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
+       {
+               int result = IL_THREAD_OK;
+
+               /* Lock the count semaphore object. */
+               _ILMutexLock(&(sem->_lock));
+
+               ++sem->_waiting;
+
+               /* Unlock the count semaphore object. */
+               _ILMutexUnlock(&(sem->_lock));
+
+               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));
+               }
+               return result;
+       }
+       else
+       {
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
+int _ILMonitorExit(_ILMonitor *mon)
+{
+       int result;
+
+       if(!(result = _ILCondMutexUnlockUnsafe(&(mon->_mutex))))
+       {
+               /* 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;
+}
+
+int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms)
+{
+       if(ms == IL_MAX_UINT32)
+       {
+               if(!_ILCondMutexLockUnsafe(&(mon->_mutex)))
+               {
+                       return IL_THREAD_OK;
+               }
+               return IL_THREAD_ERR_UNKNOWN;
+       }
+       else if(ms == 0)
+       {
+               int result;
+
+               if(!(result = _ILCondMutexTryLockUnsafe(&(mon->_mutex))))
+               {
+                       return IL_THREAD_OK;
+               }
+               return result == EBUSY ? IL_THREAD_BUSY : IL_THREAD_ERR_UNKNOWN;
+       }
+       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;
+       }
+       else
+       {
+               /* Invalid negative value for ms. */
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
+int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
+                                               ILMonitorPredicate predicate, 
void *arg)
+{
+       int result = 0;
+
+       if(ms == IL_MAX_UINT32)
+       {
+               do
+               {
+                       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)
+       {
+               /*
+                * 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).
+                */
+               if(!(result = _ILCondMutexUnlockUnsafe(&(mon->_mutex))))
+               {
+                       result = _ILCondMutexLockUnsafe(&(mon->_mutex));
+                       if(!result)
+                       {
+                               /*
+                                * In this case the predicate should always 
return a
+                                * value != 0
+                                */
+                               if(predicate(arg))
+                               {
+                                       return IL_THREAD_OK;
+                               }
+                               return IL_THREAD_ERR_UNKNOWN;
+                       }
+               }
+               return result;
+       }
+       else if(ms <= IL_MAX_INT32)
+       {
+               struct timeval tv;
+               struct timespec ts;
+
+               gettimeofday(&tv, 0);
+               ts.tv_sec = tv.tv_sec + (long)(ms / 1000);
+               ts.tv_nsec = (tv.tv_usec + (long)((ms % 1000) * 1000)) * 1000L;
+               if(ts.tv_nsec >= 1000000000L)
+               {
+                       ++(ts.tv_sec);
+                       ts.tv_nsec -= 1000000000L;
+               }
+
+               /* Wait until we are signalled or the timeout expires */
+               do
+               {
+                       result = pthread_cond_timedwait(&(mon->_cond),
+                                                                               
    &(mon->_mutex), &ts);
+                       if((result == 0) || (result == ETIMEDOUT))
+                       {
+                               if(predicate(arg))
+                               {
+                                       return result == 0 ? IL_THREAD_OK : 
IL_THREAD_BUSY;
+                               }
+                       }
+                       else
+                       {
+                               return IL_THREAD_ERR_UNKNOWN;
+                       }
+               } while(1);
+       }
+       else
+       {
+               /* Invalid negative value for ms. */
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
        }
-       return 0;
 }
 
 #ifdef __cplusplus
diff --git a/support/pt_defs.h b/support/pt_defs.h
old mode 100644
new mode 100755
index 8655598..9a22a79
--- a/support/pt_defs.h
+++ b/support/pt_defs.h
@@ -102,6 +102,22 @@ typedef pthread_mutex_t            _ILRWLock;
 #endif
 
 /*
+ * Semaphore which allows to release multiple or all waiters.
+ */
+typedef struct
+{
+       _ILMutex                        _lock;
+       _ILSemaphore            _sem;
+       ILInt32 volatile        _waiting;
+} _ILCountSemaphore;
+
+typedef struct
+{
+       _ILCondMutex    _mutex;
+       _ILCondVar              _cond;
+} _ILMonitor;
+
+/*
  * This is a real thread package.
  */
 #define        _ILThreadIsReal         1
@@ -175,9 +191,20 @@ extern pthread_mutexattr_t _ILMutexAttr;
 #define        _ILCondMutexCreate(mutex)               _ILMutexCreate((mutex))
 #define        _ILCondMutexDestroy(mutex)              _ILMutexDestroy((mutex))
 #define        _ILCondMutexLockUnsafe(mutex)   _ILMutexLockUnsafe((mutex))
+#define        _ILCondMutexTryLockUnsafe(mutex)        \
+                       (pthread_mutex_trylock((mutex)))
 #define        _ILCondMutexUnlockUnsafe(mutex) _ILMutexUnlockUnsafe((mutex))
 
 /*
+ * Try to lock a condition mutex wor a given amount of time.
+ * Returns IL_THREAD_OK if the mutex could be acquired, IL_THREAD_BUSY if the
+ * operation timed out, IL_THREAD_ERR_INVALID_TIMEOUT if a negative timeout not
+ * equal to IL_MAX_UINT32 was supplied or IL_THREAD_ERR_UNKNOWN on every other
+ * error.
+ */
+int _ILCondMutexTimedLockUnsafe(_ILCondMutex *mutex, ILUInt32 ms);
+
+/*
  * Primitive read/write lock operations.  Note: the "Lock" and
  * "Unlock" operations are not "suspend-safe".
  */
@@ -227,6 +254,60 @@ int _ILSemaphorePostMultiple(_ILSemaphore *sem, ILUInt32 
count);
 int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex *mutex, ILUInt32 ms);
 
 /*
+ * Release a number of waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalCount(_ILCountSemaphore *sem, ILUInt32 count);
+
+/*
+ * Release all waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalAll(_ILCountSemaphore *sem);
+
+#define _ILCountSemaphoreSignal(sem)   _ILCountSemaphoreSignalCount((sem), 1)
+
+/*
+ * Wait on a count semaphore.
+ */
+int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, ILUInt32 ms);
+
+#define _ILCountSemaphoreWait(sem)     _ILCountSemaphoreTimedWait((sem), 
IL_MAX_UINT32)
+#define _ILCountSemaphoreTryWait(sem)  _ILCountSemaphoreTimedWait((sem), 0)
+
+/*
+ * Primitive monitor operations.
+ */
+#define        _ILMonitorCreate(mon)   \
+               ({ \
+                       int __result = _ILCondMutexCreate(&((mon)->_mutex)); \
+                       if(!__result) \
+                       { \
+                               __result = _ILCondVarCreate(&((mon)->_cond)); \
+                       } \
+                       __result == 0 ? IL_THREAD_OK : IL_THREAD_ERR_UNKNOWN; \
+               })
+#define        _ILMonitorDestroy(mon)  \
+               ({ \
+                       int __result = _ILCondVarDestroy(&((mon)->_cond)); \
+                       if(!__result) \
+                       { \
+                               __result = 
_ILCondMutexDestroy(&((mon)->_mutex)); \
+                       } \
+                       __result == 0 ? IL_THREAD_OK : IL_THREAD_ERR_UNKNOWN; \
+               })
+#define        _ILMonitorPulse(mon)    \
+                       _ILCondVarSignal(&((mon)->_cond))
+#define        _ILMonitorPulseAll(mon) \
+                       (pthread_cond_broadcast(&((mon)->_cond)))
+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))
+
+/*
  * Get or set the thread object that is associated with "self".
  */
 extern pthread_key_t _ILThreadObjectKey;
diff --git a/support/thr_defs.h b/support/thr_defs.h
old mode 100644
new mode 100755
index 6245123..541f212
--- a/support/thr_defs.h
+++ b/support/thr_defs.h
@@ -23,6 +23,26 @@
 #define        _THR_DEFS_H
 
 /*
+ * 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 *);
+
+/*
+ * Threading error codes.
+ */
+#define IL_THREAD_OK                                           0x00000000
+#define IL_THREAD_ERR_ABANDONED                                0x00000080
+#define IL_THREAD_BUSY                                         0x00000102
+#define IL_THREAD_ERR_INTERRUPT                                0x80131519
+#define IL_THREAD_ERR_INVALID_TIMEOUT          0x80131502
+#define IL_THREAD_ERR_SYNCLOCK                         0x80131518
+#define IL_THREAD_ERR_INVALID_RELEASECOUNT     0xFFFFFFFD
+#define IL_THREAD_ERR_IN_USE                           0xFFFFFFFE
+#define IL_THREAD_ERR_UNKNOWN                          0xFFFFFFFF
+
+/*
  * Choose which thread package we will be using.
  */
 #include "thr_choose.h"
@@ -138,7 +158,7 @@ struct _tagILThread
 /*
  * Wait handle kinds.
  */
-#define        IL_WAIT_EVENT                   0x800
+#define        IL_WAIT_EVENT                   0x0800
 #define        IL_WAIT_MUTEX                   0x1000
 #define        IL_WAIT_NAMED_MUTEX             0x1001
 #define        IL_WAIT_MONITOR                 0x1002
@@ -232,15 +252,33 @@ typedef struct
 } ILWaitMutexNamed;
 
 /*
- * Internal structure of a monitor, which extends a wait
+ * Internal structure of a wait monitor, which extends a wait
  * mutex with Wait/Pulse/PulseAll semantics.
  */
+
 typedef struct
 {
        ILWaitMutex                     parent;
        _ILWakeupQueue          signalQueue;
        int                             waiters;
-} ILMonitor;
+} ILWaitMonitor;
+
+/*
+ * Monitor support with the whole .NET monitor semantics.
+ */
+typedef struct _tagILMonitor ILMonitor;
+
+/*
+ * Pool used ba the monitor.
+ */
+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 */
+};
 
 /*
  * Safe mutex lock and unlock operations that will prevent the
@@ -270,10 +308,30 @@ typedef struct
  * the thread from being suspended while it holds a lock.
  */
 #define        _ILCondMutexLock(mutex) \
+                       ({ \
+                               int __result; \
+                               ILThread *__self = _ILThreadGetSelf(); \
+                               ++(__self->numLocksHeld); \
+                               if((__result = 
_ILCondMutexLockUnsafe((mutex)))) \
+                               { \
+                                       --(__self->numLocksHeld); \
+                               }\
+                               __result; \
+                       })
+#define        _ILCondMutexTryLock(mutex, errval)      \
                        do { \
                                ILThread *__self = _ILThreadGetSelf(); \
                                ++(__self->numLocksHeld); \
-                               _ILCondMutexLockUnsafe((mutex)); \
+                               if((errval) = 
_ILCondMutexTryLockUnsafe((mutex))) \
+                               { \
+                                       if(--(__self->numLocksHeld) == 0) \
+                                       { \
+                                               if(__self->suspendRequested) \
+                                               { \
+                                                       
_ILThreadSuspendRequest(__self); \
+                                               } \
+                                       } \
+                               } \
                        } while (0)
 #define        _ILCondMutexUnlock(mutex)       \
                        do { \
@@ -469,6 +527,53 @@ int _ILWaitOneBackupInterruptsAndAborts(ILWaitHandle 
*handle, int timeout);
 #define ILWaitMutexThreadOwns(t, handle) \
        (((ILWaitMutex *)handle)->owner == &(t->wakeup))
 
+/*
+ * Initialize a monitor pool for the monitor subsystem.
+ */
+void ILMonitorPoolInit(ILMonitorPool *pool);
+
+/*
+ * Destroy a monitor pool.
+ * There must be no used monitors in this pool when calling this function.
+ */
+void ILMonitorPoolDestroy(ILMonitorPool *pool);
+
+/*
+ * 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)
+
+/*
+ * 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);
+
+/*
+ * Enter the wait state on an owned monitor.
+ */
+int ILMonitorTimedWait(void **monitorLocation, ILUInt32 ms);
+#define ILMonitorWait(loc)     ILMonitorTimedWait((loc), IL_MAX_UINT32)
+
+/*
+ * Move one thread in the waiting queue to the ready queue in the monitor
+ * stored at monitorLocation.
+ */
+int ILMonitorPulse(void **monitorLocation);
+
+/*
+ * Move all threads in the waiting queue to the ready queue in the monitor
+ * stored at monitorLocation.
+ */
+int ILMonitorPulseAll(void **monitorLocation);
 
 #ifdef __cplusplus
 };
diff --git a/support/w32_defs.c b/support/w32_defs.c
old mode 100644
new mode 100755
index 394a1c5..f63c1cb
--- a/support/w32_defs.c
+++ b/support/w32_defs.c
@@ -144,6 +144,54 @@ int _ILThreadCreateSystem(ILThread *thread)
 }
 
 /*
+ * This function is simply a wrapper around the WaitForSingleObject function
+ * to handle the errors and convert them to the unified error codes.
+ */
+int    _ILWaitHandleTimedWait(HANDLE handle, ILUInt32 ms)
+{
+       if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
+       {
+               DWORD result;
+
+               if(ms == IL_MAX_UINT32)
+               {
+                       result = WaitForSingleObject(handle, INFINITE);
+               }
+               else
+               {
+                       result = WaitForSingleObject(handle, (DWORD)ms);
+               }
+
+               if(result == WAIT_OBJECT_0)
+               {
+                       return IL_THREAD_OK;
+               }
+               else
+               {
+                       switch(result)
+                       {
+                               case WAIT_ABANDONED:
+                               {
+                                       return IL_THREAD_ERR_ABANDONED;
+                               }
+                               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.
@@ -164,6 +212,192 @@ int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex 
*mutex, ILUInt32 ms)
        return (result == WAIT_OBJECT_0);
 }
 
+/*
+ * Release a number of waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalCount(_ILCountSemaphore *sem, ILUInt32 count)
+{
+       int result = IL_THREAD_OK;
+
+       /* Lock the count semaphore object. */
+       _ILMutexLock(&(sem->_lock));
+
+       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;
+}
+
+/*
+ * Release all waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalAll(_ILCountSemaphore *sem)
+{
+       int result = IL_THREAD_OK;
+
+       if(sem->_waiting > 0)
+       {
+               /* Lock the count semaphore object. */
+               _ILMutexLock(&(sem->_lock));
+
+               /* We have to recheck because of possible race conditions. */
+               if(sem->_waiting > 0)
+               {
+                       result = (ReleaseSemaphore(sem->_sem, sem->_waiting, 0) 
!= 0) ? 
+                                               IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN;
+
+                       sem->_waiting = 0;
+               }
+
+               /* Unlock the count semaphore object. */
+               _ILMutexUnlock(&(sem->_lock));
+       }
+       return result;
+}
+
+/*
+ * Wait on a count semaphore.
+ */
+int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, ILUInt32 ms)
+{
+       if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
+       {
+               int result = IL_THREAD_OK;
+
+               /* Lock the count semaphore object. */
+               _ILMutexLock(&(sem->_lock));
+
+               sem->_waiting += 1;
+
+               /* Unlock the count semaphore object. */
+               _ILMutexUnlock(&(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));
+
+                       sem->_waiting -= 1;
+
+                       /* Unlock the count semaphore object. */
+                       _ILMutexUnlock(&(sem->_lock));
+               }
+               return result;
+       }
+       else
+       {
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
+int _ILMonitorTimedTryEnter(_ILMonitor *mon, ILUInt32 ms)
+{
+       DWORD result;
+
+       if((ms == IL_MAX_UINT32) || (ms <= IL_MAX_INT32))
+       {
+               result = _ILWaitHandleTimedWait(mon->_mutex, ms);
+       }
+       else
+       {
+               result = IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+       return result;
+}
+
+int _ILMonitorTimedWait(_ILMonitor *mon, ILUInt32 ms,
+                                               ILMonitorPredicate predicate, 
void *arg)
+{
+       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;
+
+               /* Unlock the count semaphore object. */
+               _ILMutexUnlock(&(mon->_sem._lock));
+
+               /* Unlock the mutex and wait on the semaphore. */
+               result = SignalObjectAndWait(mon->_mutex, mon->_sem._sem,
+                                                                        
(DWORD)ms, FALSE);
+
+               if(result == WAIT_OBJECT_0)
+               {
+                       /* Now wait until the mutex can be acquired. */
+                       result = _ILWaitHandleWait(mon->_mutex);
+                       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;
+                               }
+                       }
+                       return result;
+               }
+               else
+               {
+                       /* Lock the count semaphore object. */
+                       _ILMutexLock(&(mon->_sem._lock));
+
+                       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;
+                       }
+
+                       /* Unlock the count semaphore object. */
+                       _ILMutexUnlock(&(mon->_sem._lock));
+
+                       if(result == WAIT_TIMEOUT)
+                       {
+                               /* The timeout expired on waiting to get 
pulsed. */
+                               result = _ILWaitHandleWait(mon->_mutex);
+
+                               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;
+                       }
+                       else
+                       {
+                               return IL_THREAD_ERR_UNKNOWN;
+                       }
+               }
+       }
+       else
+       {
+               return IL_THREAD_ERR_INVALID_TIMEOUT;
+       }
+}
+
+
 #ifdef __cplusplus
 };
 #endif
diff --git a/support/w32_defs.h b/support/w32_defs.h
old mode 100644
new mode 100755
index 4cf9d28..dbb2e7c
--- a/support/w32_defs.h
+++ b/support/w32_defs.h
@@ -37,6 +37,25 @@ typedef HANDLE                               _ILSemaphore;
 typedef CRITICAL_SECTION       _ILRWLock;
 
 /*
+ * Semaphore which allows to release multiple or all waiters.
+ */
+typedef struct
+{
+       _ILMutex                _lock;
+       _ILSemaphore    _sem;
+       LONG volatile   _waiting;
+} _ILCountSemaphore;
+
+/*
+ * Structure of a monitor.
+ */
+typedef struct
+{
+       _ILCountSemaphore       _sem;
+       _ILCondMutex            _mutex;
+} _ILMonitor;
+
+/*
  * This is a real thread package.
  */
 #define        _ILThreadIsReal         1
@@ -48,6 +67,25 @@ typedef CRITICAL_SECTION     _ILRWLock;
                        ((thread)->identifier == GetCurrentThreadId())
 
 /*
+ * Some helper macros for wait handles.
+ */
+
+/*
+ * Close (destroy) a WaitHandle.
+ */
+#define _ILWaitHandleClose(handle) (CloseHandle(handle) != 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN)
+
+/*
+ * Wait for a WaitHandle for the given amount of time.
+ */
+int    _ILWaitHandleTimedWait(HANDLE handle, ILUInt32 ms);
+
+/*
+ * Wait for a WaitHandle infinitely untit the WaitHandle is signaled.
+ */
+#define _ILWaitHandleWait(handle)      _ILWaitHandleTimedWait((handle), 
IL_MAX_UINT32)
+
+/*
  * Suspend and resume threads.  Note: these are the primitive
  * versions, which are not "suspend-safe".
  */
@@ -79,10 +117,7 @@ typedef CRITICAL_SECTION    _ILRWLock;
 /*
  * Destroy a thread handle that is no longer required.
  */
-#define        _ILThreadDestroy(thread)        \
-                       do { \
-                               CloseHandle((thread)->handle); \
-                       } while (0)
+#define        _ILThreadDestroy(thread)        
_ILWaitHandleClose((thread)->handle)
 
 /*
  * Primitive mutex operations.  Note: the "Lock" and "Unlock"
@@ -111,21 +146,23 @@ typedef CRITICAL_SECTION  _ILRWLock;
  * variables to do an atomic "unlock and wait" operation.
  */
 #define        _ILCondMutexCreate(mutex)       \
-                       do { \
+                       ({ \
                                *(mutex) = CreateMutex(NULL, FALSE, NULL); \
-                       } while (0)
-#define        _ILCondMutexDestroy(mutex)      \
-                       do { \
-                               CloseHandle(*(mutex)); \
-                       } while (0)
-#define        _ILCondMutexLockUnsafe(mutex)   \
-                       do { \
-                               WaitForSingleObject(*(mutex), INFINITE); \
-                       } while (0)
-#define        _ILCondMutexUnlockUnsafe(mutex) \
-                       do { \
-                               ReleaseMutex(*(mutex)); \
-                       } while (0)
+                               *(mutex) != 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN; \
+                       })
+#define        _ILCondMutexDestroy(mutex)      _ILWaitHandleClose(*(mutex))
+#define        _ILCondMutexLockUnsafe(mutex)   _ILWaitHandleWait(*(mutex))
+#define        _ILCondMutexTryLockUnsafe(mutex)        
_ILWaitHandleTimedWait(*(mutex), 0)
+#define        _ILCondMutexUnlockUnsafe(mutex) (ReleaseMutex(*(mutex)) != 0 ? 
IL_THREAD_OK : IL_THREAD_ERR_SYNCLOCK)
+
+/*
+ * Try to lock a condition mutex wor a given amount of time.
+ * Returns IL_THREAD_OK if the mutex could be acquired, IL_THREAD_BUSY if the
+ * operation timed out, IL_THREAD_ERR_INVALID_TIMEOUT if a negative timeout not
+ * equal to IL_MAX_UINT32 was supplied or IL_THREAD_ERR_UNKNOWN on every other
+ * error.
+ */
+#define _ILCondMutexTimedLockUnsafe(mutex, ms) _ILWaitHandleTimedWait((mutex), 
(ms))
 
 /*
  * Primitive read/write lock operations.  Note: the "Lock" and
@@ -141,25 +178,16 @@ typedef CRITICAL_SECTION  _ILRWLock;
  * Primitive semaphore operations.
  */
 #define        _ILSemaphoreCreate(sem) \
-                       do { \
+                       ({ \
                                *(sem) = CreateSemaphore(NULL, 0, 0x7FFFFFFF, 
NULL); \
-                       } while (0)
-#define        _ILSemaphoreDestroy(sem)        \
-                       do { \
-                               CloseHandle(*(sem)); \
-                       } while (0)
-#define        _ILSemaphoreWait(sem)   \
-                       do { \
-                               WaitForSingleObject(*(sem), INFINITE); \
-                       } while (0)
+                               *(sem) != 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN; \
+                       })
+#define        _ILSemaphoreDestroy(sem)        _ILWaitHandleClose(*(sem))
+#define        _ILSemaphoreWait(sem)   _ILWaitHandleWait(*(sem))
 #define        _ILSemaphorePost(sem)   \
-                       do { \
-                               ReleaseSemaphore(*(sem), 1, NULL); \
-                       } while (0)
+       (ReleaseSemaphore(*(sem), 1, NULL) != 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN)
 #define        _ILSemaphorePostMultiple(sem, count)    \
-                       do { \
-                               ReleaseSemaphore(*(sem), (count), NULL); \
-                       } while (0)
+       (ReleaseSemaphore(*(sem), (count), NULL) != 0 ? IL_THREAD_OK : 
IL_THREAD_ERR_UNKNOWN)
 
 /*
  * Primitive condition variable operations.
@@ -170,6 +198,89 @@ typedef CRITICAL_SECTION   _ILRWLock;
 int _ILCondVarTimedWait(_ILCondVar *cond, _ILCondMutex *mutex, ILUInt32 ms);
 
 /*
+ * Primitive counting semaphore operations.
+ */
+#define _ILCountSemaphoreCreate(sem)   \
+               ({ \
+                       (sem)->_waiting = 0; \
+                       _ILMutexCreate(&((sem)->_lock)); \
+                       _ILSemaphoreCreate(&(sem)->_sem);       \
+               })
+#define _ILCountSemaphoreDestroy(sem)  \
+               ({ \
+                       _ILMutexDestroy(&((sem)->_lock)); \
+                       _ILSemaphoreDestroy(&((sem)->_sem)); \
+               })
+
+/*
+ * Release a number of waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalCount(_ILCountSemaphore *sem, ILUInt32 count);
+
+/*
+ * Release all waiting threads from the count semaphore.
+ */
+int _ILCountSemaphoreSignalAll(_ILCountSemaphore *sem);
+
+#define _ILCountSemaphoreSignal(sem)   _ILCountSemaphoreSignalCount((sem), 1)
+
+/*
+ * Wait on a count semaphore.
+ */
+int _ILCountSemaphoreTimedWait(_ILCountSemaphore *sem, ILUInt32 ms);
+
+#define _ILCountSemaphoreWait(sem)     _ILCountSemaphoreTimedWait((sem), 
IL_MAX_UINT32)
+#define _ILCountSemaphoreTryWait(sem)  _ILCountSemaphoreTimedWait((sem), 0)
+
+/*
+ * Primitive monitor operations.
+ */
+#define        _ILMonitorCreate(mon)   \
+               ({ \
+                       int _result = 0; \
+                       if((_result = _ILCondMutexCreate(&((mon)->_mutex))) == 
IL_THREAD_OK) \
+                       { \
+                               _result = 
_ILCountSemaphoreCreate(&((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) \
+                       { \
+                               _result = IL_THREAD_ERR_UNKNOWN; \
+                       } \
+                       if(_ILCondMutexDestroy(&((mon)->_mutex)) != 
IL_THREAD_OK) \
+                       { \
+                               _result = IL_THREAD_ERR_UNKNOWN; \
+                       } \
+                       _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))
+
+/*
+ * Release all waiters from the waiting queue.
+ */
+#define        _ILMonitorPulseAll(mon) 
_ILCountSemaphoreSignalAll(&((mon)->_sem))
+
+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))
+
+/*
  * Get or set the thread object that is associated with "self".
  */
 extern DWORD _ILThreadObjectKey;
diff --git a/support/wait_mutex.c b/support/wait_mutex.c
index 53ec49a..d08fd98 100644
--- a/support/wait_mutex.c
+++ b/support/wait_mutex.c
@@ -616,7 +616,7 @@ int ILWaitMutexRelease(ILWaitHandle *handle)
 /*
  * Close a monitor.
  */
-static int MonitorClose(ILMonitor *monitor)
+static int MonitorClose(ILWaitMonitor *monitor)
 {
        /* Lock down the monitor and determine if it is currently owned */
        _ILMutexLock(&(monitor->parent.parent.lock));
@@ -640,10 +640,10 @@ static int MonitorClose(ILMonitor *monitor)
 
 ILWaitHandle *ILWaitMonitorCreate(void)
 {
-       ILMonitor *monitor;
+       ILWaitMonitor *monitor;
 
        /* Allocate memory for the monitor */
-       if((monitor = (ILMonitor *)ILMalloc(sizeof(ILMonitor))) == 0)
+       if((monitor = (ILWaitMonitor *)ILMalloc(sizeof(ILWaitMonitor))) == 0)
        {
                return 0;
        }
@@ -685,7 +685,7 @@ ILWaitHandle *ILWaitMonitorCreate(void)
 int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 timeout)
 {
        ILThread *thread = ILThreadSelf();
-       ILMonitor *monitor = (ILMonitor *)handle;
+       ILWaitMonitor *monitor = (ILWaitMonitor *)handle;
        _ILWakeup *wakeup = &((ILThreadSelf())->wakeup);
        int result, result2;
        unsigned long saveCount;
@@ -793,7 +793,7 @@ int ILWaitMonitorWait(ILWaitHandle *handle, ILUInt32 
timeout)
 
 static IL_INLINE int PrivateWaitMonitorPulse(ILWaitHandle *handle, int all)
 {
-       ILMonitor *monitor = (ILMonitor *)handle;
+       ILWaitMonitor *monitor = (ILWaitMonitor *)handle;
        _ILWakeup *wakeup = &((ILThreadSelf())->wakeup);
        int result;
 
diff --git a/tests/Makefile.am b/tests/Makefile.am
old mode 100644
new mode 100755
index 84cd77d..95fef40
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -11,7 +11,7 @@ test_crypt_SOURCES  = test_crypt.c \
 test_crypt_LDADD    = ../image/libILImage.a ../support/libILSupport.a \
                                          $(GCLIBS)     
 
-AM_CFLAGS = -I$(top_srcdir)/include
+AM_CFLAGS = -I$(top_srcdir)/include -I$(top_srcdir)/libgc/include 
-I$(top_srcdir)/libgc/libatomic_ops/src
 
 TESTS = test_thread test_crypt
 
diff --git a/tests/test_thread.c b/tests/test_thread.c
old mode 100644
new mode 100755
index 84adb2f..9148d4e
--- a/tests/test_thread.c
+++ b/tests/test_thread.c
@@ -19,6 +19,7 @@
  */
 
 #include "ilunit.h"
+#include "../support/thr_defs.h"
 #include "il_thread.h"
 #include "il_gc.h"
 #if HAVE_UNISTD_H
@@ -1181,7 +1182,7 @@ static void mutex_create(void *arg)
 /*
  * Test monitor creation.
  */
-static void monitor_create(void *arg)
+static void wait_monitor_create(void *arg)
 {
        ILWaitHandle *handle;
        handle = ILWaitMonitorCreate();
@@ -1195,7 +1196,7 @@ static void monitor_create(void *arg)
 /*
  * Test monitor acquire/release.
  */
-static void monitor_acquire(void *arg)
+static void wait_monitor_acquire(void *arg)
 {
        ILWaitHandle *handle;
 
@@ -1241,7 +1242,7 @@ static void monitor_acquire(void *arg)
 /*
  * Thread start function that holds a monitor for a period of time.
  */
-static void monitorHold(void *arg)
+static void waitMonitorHold(void *arg)
 {
        ILWaitHandle *monitor = ILWaitMonitorCreate();
        ILWaitMonitorEnter(monitor);
@@ -1255,13 +1256,13 @@ static void monitorHold(void *arg)
 /*
  * Test that a thread can be suspended while it holds a monitor.
  */
-static void monitor_suspend(void *arg)
+static void wait_monitor_suspend(void *arg)
 {
        ILThread *thread;
        int savedFlag;
 
        /* Create the thread */
-       thread = ILThreadCreate(monitorHold, 0);
+       thread = ILThreadCreate(waitMonitorHold, 0);
        if(!thread)
        {
                ILUnitOutOfMemory();
@@ -1307,6 +1308,1440 @@ static void monitor_suspend(void *arg)
 }
 
 /*
+ * Test monitor creation.
+ */
+static void primitive_monitor_create(void *arg)
+{
+       /* We are using the primitive versions for now. */
+       _ILMonitor mon;
+       if(_ILMonitorCreate(&mon))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+       _ILMonitorDestroy(&mon);
+}
+
+/*
+ * Test monitor enter.
+ */
+static void primitive_monitor_enter(void *arg)
+{
+       int result = 0;
+
+       /* We are using the primitive versions for now. */
+       _ILMonitor mon;
+       if(_ILMonitorCreate(&mon))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+       if((result = _ILMonitorEnter(&mon)))
+       {
+               _ILMonitorDestroy(&mon);
+               ILUnitFailed("could not enter a monitor");
+       }
+       if((result = _ILMonitorExit(&mon)))
+       {
+               _ILMonitorDestroy(&mon);
+               ILUnitFailed("could not exit a monitor");
+       }
+       _ILMonitorDestroy(&mon);
+}
+
+static int _result;
+static _ILMonitor _mon1;
+
+/*
+ * A simple monitor predicate returning success in every case.
+ */
+static int _monitor_predicate(void *arg)
+{
+       return 1;
+}
+
+static void _primitive_monitor_exit_unowned(void *arg)
+{
+       _ILMonitor *mon1 = (_ILMonitor *)arg;
+
+       _result = _ILMonitorExit(mon1);
+}
+
+/*
+ * Test exiting an unowned monitor.
+ */
+static void primitive_monitor_exit_unowned(void *arg)
+{
+       int result = 0;
+       ILThread *thread;
+
+       if(_ILMonitorCreate(&_mon1))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_primitive_monitor_exit_unowned, &_mon1);
+       if(!thread)
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitOutOfMemory();
+       }
+
+       if((result = _ILMonitorEnter(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Set the result to an invalid value. */
+       _result = -1;
+
+       /* Start the thread, which should immediately try to exit the unowned 
monitor */
+       ILThreadStart(thread);
+
+       /* Wait 3 time steps */
+       sleepFor(3);
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(_result != IL_THREAD_ERR_SYNCLOCK)
+       {
+               _ILMonitorExit(&_mon1);
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailMessage("exiting an unowned monitor returned the 
wrong result");
+               ILUnitFailMessage("the Wrong result is %i", _result);
+               if(_result == IL_THREAD_OK)
+               {
+                       ILUnitFailMessage("This is expected in pthread 
implementations");
+               }
+               ILUnitFailEndMessages();
+       }
+
+       if((result = _ILMonitorExit(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not exit a monitor");
+       }
+       _ILMonitorDestroy(&_mon1);
+}
+
+/*
+ * Test monitor enter1.
+ */
+static void _primitive_monitor_enter_locked(void *arg)
+{
+       _ILMonitor *mon1 = (_ILMonitor *)arg;
+
+       _result = 1;
+       if(_ILMonitorEnter(mon1))
+       {
+               _result = 999;
+               return;
+       }
+       _result = 2;
+       if(_ILMonitorExit(mon1))
+       {
+               _result = 998;
+       }
+}
+
+static void primitive_monitor_enter1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+       int result2 = 0;
+
+       /* We are using the primitive versions for now. */
+       if(_ILMonitorCreate(&_mon1))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+
+       if((result = _ILMonitorEnter(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_primitive_monitor_enter_locked, &_mon1);
+       if(!thread)
+       {
+               _ILMonitorExit(&_mon1);
+               _ILMonitorDestroy(&_mon1);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 1 time steps */
+       sleepFor(1);
+
+       /* The result1 should be 1 now. */
+       result1 = _result;
+
+       if((result = _ILMonitorExit(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILThreadDestroy(thread);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       /* Wait 3 time steps */
+       sleepFor(3);
+
+       /* The result1 should be 2 now. */
+       result2 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 1 || result2 != 2)
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("lock on monitor enter doesn't work");
+       }
+
+       if((result = _ILMonitorDestroy(&_mon1)))
+       {
+               ILUnitFailed("could not destroy a monitor");
+       }
+}
+
+static void _primitive_monitor_tryenter_locked(void *arg)
+{
+       _ILMonitor *mon1 = (_ILMonitor *)arg;
+       int result = _ILMonitorTryEnter(mon1);
+
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 0;
+                       if(_ILMonitorExit(mon1))
+                       {
+                               _result = 998;
+                       }
+               }
+               break;
+
+               case IL_THREAD_BUSY:
+               {
+                       _result = 1;
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+static void primitive_monitor_tryenter1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+
+       /* We are using the primitive versions for now. */
+       if(_ILMonitorCreate(&_mon1))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+
+       if((result = _ILMonitorEnter(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_primitive_monitor_tryenter_locked, &_mon1);
+       if(!thread)
+       {
+               _ILMonitorExit(&_mon1);
+               _ILMonitorDestroy(&_mon1);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 1 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 1 now. */
+       result1 = _result;
+
+       if((result = _ILMonitorExit(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILThreadDestroy(thread);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 1)
+       {
+               _ILMonitorDestroy(&_mon1);
+               printf("Wrong result is %i\n", result1);
+               ILUnitFailed("tryenter on a locked monitor doesn't work");
+       }
+
+       if((result = _ILMonitorDestroy(&_mon1)))
+       {
+               ILUnitFailed("could not destroy a monitor");
+       }
+}
+
+static void primitive_monitor_tryenter2(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+
+       /* We are using the primitive versions for now. */
+       if(_ILMonitorCreate(&_mon1))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_primitive_monitor_tryenter_locked, &_mon1);
+       if(!thread)
+       {
+               _ILMonitorExit(&_mon1);
+               _ILMonitorDestroy(&_mon1);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 2 time steps to let the thread enter the monitor. */
+       sleepFor(2);
+
+       result1 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 0)
+       {
+               _ILMonitorDestroy(&_mon1);
+               printf("Wrong result is %i\n", result1);
+               ILUnitFailed("tryenter on a unlocked monitor doesn't work");
+       }
+
+       if((result = _ILMonitorDestroy(&_mon1)))
+       {
+               ILUnitFailed("could not destroy a monitor");
+       }
+}
+
+static void _primitive_monitor_timed_tryenter(void *arg)
+{
+       _ILMonitor *mon1 = (_ILMonitor *)arg;
+       int result = _ILMonitorTimedTryEnter(mon1, 1);
+
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 0;
+                       if(_ILMonitorExit(mon1))
+                       {
+                               _result = 998;
+                       }
+               }
+               break;
+
+               case IL_THREAD_BUSY:
+               {
+                       _result = 1;
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+static void primitive_monitor_timed_tryenter1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+
+       /* We are using the primitive versions for now. */
+       if(_ILMonitorCreate(&_mon1))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+
+       if((result = _ILMonitorEnter(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_primitive_monitor_timed_tryenter, &_mon1);
+       if(!thread)
+       {
+               _ILMonitorExit(&_mon1);
+               _ILMonitorDestroy(&_mon1);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 2 time steps to let the thread try to enter the monitor. */
+       sleepFor(2);
+
+       result1 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if((result = _ILMonitorExit(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILThreadDestroy(thread);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       if(result1 != 1)
+       {
+               _ILMonitorDestroy(&_mon1);
+               printf("Wrong result is %i\n", result1);
+               ILUnitFailed("timed tryenter on a locked monitor with timeout 
doesn't work");
+       }
+
+       if((result = _ILMonitorDestroy(&_mon1)))
+       {
+               ILUnitFailed("could not destroy a monitor");
+       }
+}
+
+static void _primitive_monitor_wait1(void *arg)
+{
+       _ILMonitor *mon1 = (_ILMonitor *)arg;
+       int result;
+
+       _result = 0;
+       result = _ILMonitorEnter(mon1);
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 1;
+                       if(_ILMonitorPulse(mon1))
+                       {
+                               result = 997;
+                               _ILMonitorExit(mon1);
+                       }
+                       else
+                       {
+                               if(_ILMonitorExit(mon1))
+                               {
+                                       _result = 998;
+                               }
+                       }
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+static void primitive_monitor_wait1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+       int result2 = 0;
+
+       /* We are using the primitive versions for now. */
+       if(_ILMonitorCreate(&_mon1))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+
+       if(_ILMonitorEnter(&_mon1))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_primitive_monitor_wait1, &_mon1);
+       if(!thread)
+       {
+               _ILMonitorExit(&_mon1);
+               _ILMonitorDestroy(&_mon1);
+               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;
+
+       if(_ILMonitorWait(&_mon1, _monitor_predicate, 0) != IL_THREAD_OK)
+       {
+               /* Clean up the thread object. */
+               ILThreadDestroy(thread);
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("wait on a monitor doesn't work");
+       }
+
+       /* Wait 2 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 1 now. */
+       result2 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 0)
+       {
+               _ILMonitorDestroy(&_mon1);
+               printf("Wrong result is %i\n", result1);
+               ILUnitFailed("tryenter on a locked monitor doesn't work");
+       }
+
+       if((result = _ILMonitorExit(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       if((result = _ILMonitorDestroy(&_mon1)))
+       {
+               ILUnitFailed("could not destroy a monitor");
+       }
+
+       if(result1 != 0 && result2 != 1)
+       {
+               ILUnitFailed("testcase failed");
+       }
+}
+
+static void _primitive_monitor_timed_wait1(void *arg)
+{
+       _ILMonitor *mon1 = (_ILMonitor *)arg;
+       int result;
+
+       _result = 0;
+       result = _ILMonitorEnter(mon1);
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 1;
+                       /* Wait 3 time steps to let the calling thread 
timeout.*/
+                       sleepFor(3);
+                       if(_ILMonitorPulse(mon1))
+                       {
+                               result = 997;
+                               _ILMonitorExit(mon1);
+                       }
+                       else
+                       {
+                               if(_ILMonitorExit(mon1))
+                               {
+                                       _result = 998;
+                               }
+                               else
+                               {
+                                       sleepFor(1);
+                                       if((result = _ILMonitorTryEnter(mon1)) 
== IL_THREAD_BUSY)
+                                       {
+                                               _result = 3;
+                                       }
+                                       else
+                                       {
+                                               if(result == IL_THREAD_OK)
+                                               {
+                                                       _result = 996;
+                                                       _ILMonitorExit(mon1);
+                                               }
+                                               else
+                                               {
+                                                       _result = 997;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+static void primitive_monitor_timed_wait1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+       int result2 = 0;
+
+       /* We are using the primitive versions for now. */
+       if(_ILMonitorCreate(&_mon1))
+       {
+               ILUnitFailed("could not create a monitor");
+       }
+
+       if(_ILMonitorEnter(&_mon1))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_primitive_monitor_timed_wait1, &_mon1);
+       if(!thread)
+       {
+               _ILMonitorExit(&_mon1);
+               _ILMonitorDestroy(&_mon1);
+               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;
+
+       result = _ILMonitorTimedWait(&_mon1, 2, _monitor_predicate, 0);
+       if(result != IL_THREAD_BUSY)
+       {
+               /* Clean up the thread object. */
+               ILThreadDestroy(thread);
+               _ILMonitorDestroy(&_mon1);
+               printf("Wrong result is %i\n", result);
+               ILUnitFailed("timed wait on a monitor doesn't work");
+       }
+
+       /* Wait 2 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 3 now. */
+       result2 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 0 || result2 != 3)
+       {
+               _ILMonitorDestroy(&_mon1);
+               printf("Wrong result is %i\n", result1);
+               ILUnitFailed("tryenter on a locked monitor doesn't work");
+       }
+
+       if((result = _ILMonitorExit(&_mon1)))
+       {
+               _ILMonitorDestroy(&_mon1);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       if((result = _ILMonitorDestroy(&_mon1)))
+       {
+               ILUnitFailed("could not destroy a monitor");
+       }
+
+       if(result1 != 0 && result2 != 1)
+       {
+               ILUnitFailed("testcase failed");
+       }
+}
+
+/*
+ * Test monitor creation
+ */
+static void monitor_create(void *arg)
+{
+       ILMonitorPool monitorPool;
+       void *monitorLocation;
+       int result;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&monitorPool);
+       monitorLocation = 0;
+
+       result = ILMonitorEnter(&monitorPool, &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);
+       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);
+}
+
+/*
+ * Test entering and leaving a monitor multiple times
+ */
+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);
+       monitorLocation = 0;
+
+       for(i = 0; i < 10; ++i)
+       {
+               result = ILMonitorEnter(&monitorPool, &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);
+               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;
+
+/*
+ * Try to enter a locked monitor
+ */
+static void _monitor_enter_locked(void *arg)
+{
+       void **monitorLocation;
+
+       monitorLocation = (void **)arg;
+       _result = 1;
+       if(ILMonitorEnter(&_monitorPool, monitorLocation) != IL_THREAD_OK)
+       {
+               _result = 999;
+               return;
+       }
+       _result = 2;
+       if(ILMonitorExit(&_monitorPool, monitorLocation) != IL_THREAD_OK)
+       {
+               _result = 998;
+       }
+}
+
+static void monitor_enter_locked(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+       int result2 = 0;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&_monitorPool);
+       _monitorLocation = 0;
+
+       if((result = ILMonitorEnter(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       {
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitFailed("could not enter a new monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_enter_locked, (void 
*)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 1 time steps */
+       sleepFor(1);
+
+       /* The result1 should be 1 now. */
+       result1 = _result;
+
+       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       {
+               ILThreadDestroy(thread);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       /* Wait 3 time steps */
+       sleepFor(3);
+
+       /* The result1 should be 2 now. */
+       result2 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 1 || result2 != 2)
+       {
+               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)
+{
+       void **monitorLocation;
+       int result;
+
+       monitorLocation = (void **)arg;
+       result = ILMonitorTryEnter(&_monitorPool, monitorLocation);
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 0;
+                       if(ILMonitorExit(&_monitorPool, monitorLocation) != 
IL_THREAD_OK)
+                       {
+                               _result = 998;
+                       }
+               }
+               break;
+
+               case IL_THREAD_BUSY:
+               {
+                       _result = 1;
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+/*
+ * Test TryEnter on a locked monitor
+ */
+static void monitor_tryenter1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&_monitorPool);
+       _monitorLocation = 0;           
+
+       if((result = ILMonitorEnter(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       {
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_tryenter_locked, (void 
*)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 1 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 1 now. */
+       result1 = _result;
+
+       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       {
+               ILThreadDestroy(thread);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 1)
+       {
+               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);
+}
+
+/*
+ * Test TryEnter on an unlocked monitor
+ */
+static void monitor_tryenter2(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&_monitorPool);
+       _monitorLocation = 0;
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_tryenter_locked, (void 
*)&_monitorLocation);
+       if(!thread)
+       {
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 2 time steps to let the thread enter the monitor. */
+       sleepFor(2);
+
+       result = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result != 0)
+       {
+               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)
+{
+       void **monitorLocation;
+       int result;
+
+       monitorLocation = (void **)arg;
+       result = ILMonitorTimedTryEnter(&_monitorPool, monitorLocation, 1);
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 0;
+                       if(ILMonitorExit(&_monitorPool, monitorLocation) != 
IL_THREAD_OK)
+                       {
+                               _result = 998;
+                       }
+               }
+               break;
+
+               case IL_THREAD_BUSY:
+               {
+                       _result = 1;
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+static void monitor_timed_tryenter1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&_monitorPool);
+       _monitorLocation = 0;
+
+       if((result = ILMonitorEnter(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       {
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_timed_tryenter, (void 
*)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorPool, (void *)&_monitorLocation);
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitOutOfMemory();
+       }
+
+       _result = -1;
+
+       /* Start the thread, which should immediately try to enter the monitor. 
*/
+       ILThreadStart(thread);
+
+       /* Wait 2 time steps to let the thread try to enter the monitor. */
+       sleepFor(2);
+
+       result1 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if((result = ILMonitorExit(&_monitorPool, (void *)&_monitorLocation)) 
!= IL_THREAD_OK)
+       {
+               ILThreadDestroy(thread);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       if(result1 != 1)
+       {
+               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);
+}
+
+/*
+ * Test for exiting an unowned monitor.
+ */
+static void _monitor_exit_unowned(void *arg)
+{
+       void **monitorLocation = (void **)arg;
+
+       _result = ILMonitorExit(&_monitorPool, monitorLocation);
+}
+
+/*
+ * Test exiting an unowned monitor.
+ */
+static void monitor_exit_unowned(void *arg)
+{
+       int result = 0;
+       ILThread *thread;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&_monitorPool);
+       _monitorLocation = 0;           
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_exit_unowned, (void 
*)(&_monitorLocation));
+       if(!thread)
+       {
+               ILUnitOutOfMemory();
+       }
+
+       result = ILMonitorEnter(&_monitorPool, &_monitorLocation);
+       if(result != IL_THREAD_OK)
+       {
+               ILUnitFailed("could not enter a new monitor");
+       }
+
+       /* Set the result to an invalid value. */
+       _result = -1;
+
+       /* Start the thread, which should immediately try to exit the unowned 
monitor */
+       ILThreadStart(thread);
+
+       /* Wait 3 time steps */
+       sleepFor(3);
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(_result != IL_THREAD_ERR_SYNCLOCK)
+       {
+               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               printf("Wrong result is %i\n", _result);
+               ILUnitFailed("exiting an unowned monitor returned the wrong 
result");
+       }
+
+       result = ILMonitorExit(&_monitorPool, &_monitorLocation);
+       if(result)
+       {
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       /* Clean up the monitor pool */
+       ILMonitorPoolDestroy(&_monitorPool);
+}
+
+static void _monitor_wait1(void *arg)
+{
+       void **monitorLocation;
+       int result;
+
+       monitorLocation = (void **)arg;
+       _result = 0;
+       result = ILMonitorEnter(&_monitorPool, monitorLocation);
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 1;
+                       if(ILMonitorPulse(monitorLocation) == IL_THREAD_OK)
+                       {
+                               result = 997;
+                               ILMonitorExit(&_monitorPool, monitorLocation);
+                       }
+                       else
+                       {
+                               if(ILMonitorExit(&_monitorPool, 
monitorLocation) == IL_THREAD_OK)
+                               {
+                                       _result = 998;
+                               }
+                       }
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+static void monitor_wait1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+       int result2 = 0;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&_monitorPool);
+       _monitorLocation = 0;           
+
+       if(ILMonitorEnter(&_monitorPool, &_monitorLocation) != IL_THREAD_OK)
+       {
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_wait1, (void *)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               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;
+
+       if(ILMonitorWait(&_monitorLocation) != IL_THREAD_OK)
+       {
+               /* Clean up the thread object. */
+               ILThreadDestroy(thread);
+               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitFailed("wait on a monitor doesn't work");
+       }
+
+       /* Wait 2 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 1 now. */
+       result2 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 0)
+       {
+               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               printf("Wrong result is %i\n", result1);
+               ILUnitFailed("tryenter on a locked monitor doesn't work");
+       }
+
+       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       {
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       if(result1 != 0 && result2 != 1)
+       {
+               ILUnitFailed("testcase failed");
+       }
+
+       /* Clean up the monitor pool */
+       ILMonitorPoolDestroy(&_monitorPool);
+}
+
+static void _monitor_timed_wait1(void *arg)
+{
+       void **monitorLocation;
+       int result;
+
+       monitorLocation = (void **)arg;
+       _result = 0;
+       result = ILMonitorEnter(&_monitorPool, monitorLocation);
+       switch(result)
+       {
+               case IL_THREAD_OK:
+               {
+                       _result = 1;
+                       /* Wait 3 time steps to let the calling thread 
timeout.*/
+                       sleepFor(3);
+                       if(ILMonitorPulse(monitorLocation) != IL_THREAD_OK)
+                       {
+                               result = 997;
+                               ILMonitorExit(&_monitorPool, monitorLocation);
+                       }
+                       else
+                       {
+                               if(ILMonitorExit(&_monitorPool, 
monitorLocation) != IL_THREAD_OK)
+                               {
+                                       _result = 998;
+                               }
+                               else
+                               {
+                                       sleepFor(1);
+                                       if((result = 
ILMonitorTryEnter(&_monitorPool, monitorLocation)) == IL_THREAD_BUSY)
+                                       {
+                                               _result = 3;
+                                       }
+                                       else
+                                       {
+                                               if(result == IL_THREAD_OK)
+                                               {
+                                                       _result = 996;
+                                                       
ILMonitorExit(&_monitorPool, monitorLocation);
+                                               }
+                                               else
+                                               {
+                                                       _result = 997;
+                                               }
+                                       }
+                               }
+                       }
+               }
+               break;
+
+               default:
+               {
+                       _result = 999;
+               }
+       }
+}
+
+static void monitor_timed_wait1(void *arg)
+{
+       ILThread *thread;
+       int result = 0;
+       int result1 = 0;
+       int result2 = 0;
+
+       /* initialize the monitor pool and the test location */
+       ILMonitorPoolInit(&_monitorPool);
+       _monitorLocation = 0;           
+
+       if(ILMonitorEnter(&_monitorPool, &_monitorLocation) != IL_THREAD_OK)
+       {
+               ILUnitFailed("could not enter a monitor");
+       }
+
+       /* Create the thread */
+       thread = ILThreadCreate(_monitor_timed_wait1, (void 
*)&_monitorLocation);
+       if(!thread)
+       {
+               ILMonitorExit(&_monitorPool, &_monitorLocation);
+               /* Clean up the monitor pool */
+               ILMonitorPoolDestroy(&_monitorPool);
+               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;
+
+       result = ILMonitorTimedWait(&_monitorLocation, 2);
+       if(result != IL_THREAD_BUSY)
+       {
+               /* Clean up the thread object. */
+               ILThreadDestroy(thread);
+               printf("Wrong result is %i\n", result);
+               ILUnitFailed("timed wait on a monitor doesn't work");
+       }
+
+       /* Wait 2 time steps */
+       sleepFor(2);
+
+       /* The result1 should be 3 now. */
+       result2 = _result;
+
+       /* Clean up the thread object (the thread itself is now dead) */
+       ILThreadDestroy(thread);
+
+       if(result1 != 0 || result2 != 3)
+       {
+               printf("Wrong result1 is %i\n", result1);
+               printf("Wrong result2 is %i\n", result2);
+               ILUnitFailed("tryenter on a locked monitor doesn't work");
+       }
+
+       if((result = ILMonitorExit(&_monitorPool, &_monitorLocation)) != 
IL_THREAD_OK)
+       {
+               ILUnitFailed("could not exit a monitor");
+       }
+
+       if(result1 != 0 && result2 != 1)
+       {
+               ILUnitFailed("testcase failed");
+       }
+
+       /* Clean up the monitor pool */
+       ILMonitorPoolDestroy(&_monitorPool);
+}
+
+/*
  * Simple test registration macro.
  */
 #define        RegisterSimple(name)    (ILUnitRegister(#name, name, 0))
@@ -1390,12 +2825,40 @@ void ILUnitRegisterTests(void)
        RegisterSimple(mutex_create);
 
        /*
-        * Test monitor behaviours.
+        * Test for the implementation of the monitor primitives.
+        */
+       ILUnitRegisterSuite("Monitor primitives Tests");
+       RegisterSimple(primitive_monitor_create);
+       RegisterSimple(primitive_monitor_enter);
+       RegisterSimple(primitive_monitor_exit_unowned);
+       RegisterSimple(primitive_monitor_enter1);
+       RegisterSimple(primitive_monitor_tryenter1);
+       RegisterSimple(primitive_monitor_tryenter2);
+       RegisterSimple(primitive_monitor_timed_tryenter1);
+       RegisterSimple(primitive_monitor_wait1);
+       RegisterSimple(primitive_monitor_timed_wait1);
+
+       /*
+        * Test wait monitor behaviours.
+        */
+       ILUnitRegisterSuite("Wait Monitor Tests");
+       RegisterSimple(wait_monitor_create);
+       RegisterSimple(wait_monitor_acquire);
+       RegisterSimple(wait_monitor_suspend);
+
+       /*
+        * Tests for the monitor implementation.
         */
        ILUnitRegisterSuite("Monitor Tests");
        RegisterSimple(monitor_create);
-       RegisterSimple(monitor_acquire);
-       RegisterSimple(monitor_suspend);
+       RegisterSimple(monitor_enter_multiple);
+       RegisterSimple(monitor_enter_locked);
+       RegisterSimple(monitor_tryenter1);
+       RegisterSimple(monitor_tryenter2);      
+       RegisterSimple(monitor_timed_tryenter1);
+       RegisterSimple(monitor_exit_unowned);
+       RegisterSimple(monitor_wait1);
+       RegisterSimple(monitor_timed_wait1);
 }
 
 #ifdef __cplusplus

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

Summary of changes:
 ChangeLog            |   48 ++
 configure.in         |    3 +-
 support/Makefile.am  |    1 +
 support/monitor.c    |  393 +++++++++++++
 support/no_defs.c    |   10 +
 support/no_defs.h    |   21 +-
 support/pt_defs.c    |  469 ++++++++++++++++-
 support/pt_defs.h    |   81 +++
 support/thr_defs.h   |  113 ++++-
 support/w32_defs.c   |  234 ++++++++
 support/w32_defs.h   |  179 +++++--
 support/wait_mutex.c |   10 +-
 tests/Makefile.am    |    2 +-
 tests/test_thread.c  | 1479 +++++++++++++++++++++++++++++++++++++++++++++++++-
 14 files changed, 2984 insertions(+), 59 deletions(-)
 create mode 100644 support/monitor.c
 mode change 100644 => 100755 support/no_defs.h
 mode change 100644 => 100755 support/pt_defs.c
 mode change 100644 => 100755 support/pt_defs.h
 mode change 100644 => 100755 support/thr_defs.h
 mode change 100644 => 100755 support/w32_defs.c
 mode change 100644 => 100755 support/w32_defs.h
 mode change 100644 => 100755 tests/Makefile.am
 mode change 100644 => 100755 tests/test_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]