summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrpj <rpj>2001-02-09 06:51:30 +0000
committerrpj <rpj>2001-02-09 06:51:30 +0000
commit1648c7a97f27d10ad302c6141562ece01065e1d7 (patch)
treec16f939acf7ac98db38039d747f5804d04c33fe1
parent2b3eede0b834a82c7dce5ec328f3929c0effc536 (diff)
Remodeled mutex routines again to eliminate critical sections.
-rw-r--r--ANNOUNCE43
-rw-r--r--ChangeLog21
-rw-r--r--README.NONPORTABLE31
-rw-r--r--global.c6
-rw-r--r--implement.h34
-rw-r--r--mutex.c399
-rw-r--r--nonportable.c56
-rw-r--r--pthread.def3
-rw-r--r--pthread.h18
9 files changed, 252 insertions, 359 deletions
diff --git a/ANNOUNCE b/ANNOUNCE
index 8ba2989..d2def8b 100644
--- a/ANNOUNCE
+++ b/ANNOUNCE
@@ -55,24 +55,47 @@ New:
be different to some other implementations, eg
Solaris.
- PTHREAD_MUTEX_NORMAL will simulate thread deadlock
+ PTHREAD_MUTEX_NORMAL will cause thread deadlock
if the owner of a mutex tries to relock it without
- first unlocking it, however the lock will be released
- if the owner thread is async-canceled.
+ first unlocking it. It has slightly less overhead.
-- Pthreads-win32 mutexes are now always based on
- Win32 critical sections. We no longer use Win32
- mutexes when TryEnterCriticalSection isn't
- supported.
+ The behaviour of PTHREAD_MUTEX_DEFAULT can be
+ remapped to any other type through the new
+ non-portable function
+
+ pthread_mutex_setdefaulttype_np()
+
+ (see README.NONPORTABLE)
+
+ Remapping only effects newly initialised mutexes.
+ So if you want behaviour more like Solaris
+ POSIX mutexes, which are non-recursive by default,
+ you can call this at the start of your application:
+
+ int previousType;
+ pthread_mutex_setdefaulttype_np(PTHREAD_MUTEX_ERRORCHECK,
+ &previousType);
+
+- Pthreads-win32 mutexes are now based on Win32
+ critical sections for all Windows versions. We no longer
+ depend on TryEnterCriticalSection.
- Thomas Pfaff <tpfaff@gmx.net>
+ This may change again before the next snapshot
+ to rely solely on Win32's Interlocked* routines.
+
Bugs fixed:
+- Pthread_mutex_trylock() now properly returns EBUSY
+ even when the current thread owns the mutex.
+ Consequently, pthread_mutex_destroy() will no longer
+ destroy a locked mutex (it will return EBUSY).
+ - Thomas Pfaff <tpfaff@gmx.net>
+
- The condition variable and read-write lock functions
- have been improved. For details re the [fixed] problems
- in the CV implementation see the file README.CV
+ have been improved. For discussion re the [fixed]
+ problems in the CV implementation see the file README.CV
- Alexander Terekhov <TEREKHOV@de.ibm.com>
-
Known bugs in this snapshot
---------------------------
diff --git a/ChangeLog b/ChangeLog
index 71c7f2f..5a8c6a6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,24 @@
+2001-02-09 Ross Johnson <rpj@setup1.ise.canberra.edu.au>
+
+ * nonportable.c (pthread_mutex_setdefaulttype_np): New
+ function for changing the default mutex type.
+
+ * mutex.c (ptw32_InitializeCriticalSection): Removed.
+ (ptw32_InitializeCriticalSection): Removed.
+ (ptw32_InitializeCriticalSection): Removed.
+ (ptw32_InitializeCriticalSection): Removed.
+ (ptw32_InitializeCriticalSection): Removed.
+ (pthread_mutex_init): Apply Thomas Pfaff's original
+ patches but altered slightly to avoid using
+ critical sections and retain/adapt for different
+ mutex types (see log entry for 2001-01-10).
+ (pthread_mutex_destroy): Likewise.
+ (pthread_mutex_lock): Likewise.
+ (pthread_mutex_unlock): Likewise.
+ (pthread_mutex_trylock): Likewise.
+
+ * Tagged repository 'exp-2001-02-09-passed'.
+
2001-02-09 Ross Johnson <rpj@special.ise.canberra.edu.au>
* sched.c (pthread_setconcurrency): Moved to misc.c.
diff --git a/README.NONPORTABLE b/README.NONPORTABLE
index 7dfba7f..8319853 100644
--- a/README.NONPORTABLE
+++ b/README.NONPORTABLE
@@ -40,6 +40,37 @@ pthread_delay_np (const struct timespec *interval);
0 Successful completion.
[EINVAL] The value specified by interval is invalid.
+int
+pthread_mutex_setdefaulttype_np (int newtype, int * oldtype);
+
+ The routine sets the default type to be given to all
+ POSIX mutexes initialised after the function
+ is called. Any of the following type values
+ can be made the default type:
+
+ PTHREAD_MUTEX_NORMAL
+ PTHREAD_MUTEX_ERRORCHECK
+ PTHREAD_MUTEX_RECURSIVE
+ PTHREAD_MUTEX_DEFAULT
+
+ Any mutex initialised with type PTHREAD_MUTEX_DEFAULT
+ will be set to the mapped type instead. Previously
+ initialised mutexes are not changed.
+
+ When set to PTHREAD_MUTEX_DEFAULT (the initial
+ value), mutexes will behave as for the
+ PTHREAD_MUTEX_RECURSIVE type.
+
+ If 'oldtype' is a non-NULL pointer, the previous type is
+ returned through it.
+ To get the previous type without setting a new type,
+ use -1 as the 'newtype' value.
+
+ Return Values
+
+ 0 Successfully changed to new type.
+ [EINVAL] New type isn't valid.
+
BOOL
pthread_win32_process_attach_np (void);
diff --git a/global.c b/global.c
index 128a17b..9278f07 100644
--- a/global.c
+++ b/global.c
@@ -54,3 +54,9 @@ CRITICAL_SECTION ptw32_cond_test_init_lock;
* created read/write locks.
*/
CRITICAL_SECTION ptw32_rwlock_test_init_lock;
+
+/*
+ * The default mutex type can be remapped by teh application
+ * via the pthread_mutex_setdefaulttype_np() function.
+ */
+int ptw32_mutex_mapped_default = PTHREAD_MUTEX_DEFAULT;
diff --git a/implement.h b/implement.h
index 165708a..a1a52f8 100644
--- a/implement.h
+++ b/implement.h
@@ -121,33 +121,17 @@ struct pthread_attr_t_ {
#define PTW32_OBJECT_AUTO_INIT ((void *) -1)
#define PTW32_OBJECT_INVALID NULL
-/*
- * Our own critical section type, used
- * when the system doesn't support TryEnterCriticalSection()
- */
-typedef struct ptw32_cs_t_ {
- int valid;
- pthread_t owner;
- long lock_idx;
- long entered_count;
-} ptw32_cs_t;
-
-typedef union ptw32_cs_u_t_ {
- CRITICAL_SECTION cs;
- ptw32_cs_t csFake;
-} ptw32_cs_u_t;
-
struct pthread_mutexattr_t_ {
int pshared;
int type;
};
struct pthread_mutex_t_ {
- ptw32_cs_u_t cs;
- int lockCount;
+ int lock_idx;
+ int try_lock;
int pshared;
int type;
- pthread_t ownerThread;
+ pthread_t owner;
};
struct pthread_key_t_ {
@@ -324,7 +308,7 @@ extern CRITICAL_SECTION ptw32_mutex_test_init_lock;
extern CRITICAL_SECTION ptw32_cond_test_init_lock;
extern CRITICAL_SECTION ptw32_rwlock_test_init_lock;
extern BOOL (WINAPI *ptw32_try_enter_critical_section)(LPCRITICAL_SECTION);
-
+extern int ptw32_mutex_mapped_default;
/* Declared in misc.c */
#ifdef NEED_CALLOC
@@ -380,16 +364,6 @@ BOOL ptw32_increase_semaphore(sem_t * sem,
unsigned int n);
#endif /* NEED_SEM */
-int ptw32_InitializeCriticalSection (ptw32_cs_u_t *);
-
-void ptw32_DeleteCriticalSection (ptw32_cs_u_t *);
-
-void ptw32_EnterCriticalSection (ptw32_cs_u_t *);
-
-void ptw32_LeaveCriticalSection (ptw32_cs_u_t *);
-
-BOOL ptw32_TryEnterCriticalSection (ptw32_cs_u_t *);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */
diff --git a/mutex.c b/mutex.c
index f43286c..f99ce86 100644
--- a/mutex.c
+++ b/mutex.c
@@ -85,252 +85,6 @@ ptw32_mutex_check_need_init(pthread_mutex_t *mutex)
}
-/*
- * The following internal versions of *CriticalSection()
- * include an implementation of TryEnterCriticalSection
- * for platforms on which that function has not been
- * provided by Microsoft (eg. W95/98). This allows us
- * to avoid using Win32 mutexes as the basis
- * of our implementation of POSIX mutex locks.
- *
- * Where TryEnterCriticalSection() is provided by the
- * platform, these routines act as wrappers with
- * minimal additional overhead. Otherwise, these
- * routines manage additional state in order to
- * properly emulate TryEnterCriticalSection().
- */
-
-int
-ptw32_InitializeCriticalSection (ptw32_cs_u_t * csect)
- /*
- * ------------------------------------------------------
- *
- * PARAMETERS
- * csect
- * pointer to an instance of ptw32_cs_u_t
- * csect->csFake must be NULL on entry.
- *
- * DESCRIPTION
- * Internal implementation of InitializeCriticalSection.
- *
- * RETURN
- * 0 Initialisation successful
- * EINVAL csFake already initialised
- *
- * ------------------------------------------------------
- */
-{
- int result = 0;
-
- if (NULL != ptw32_try_enter_critical_section)
- {
- InitializeCriticalSection(&csect->cs);
- }
- else
- {
- while (InterlockedIncrement(&csect->csFake.lock_idx) > 0)
- {
- InterlockedDecrement(&csect->csFake.lock_idx);
- Sleep(0);
- }
-
- if (csect->csFake.valid)
- {
- result = EINVAL;
- }
- else
- {
- csect->csFake.owner = NULL;
- csect->csFake.entered_count = 0;
- csect->csFake.valid = 1;
- }
-
- InterlockedDecrement(&csect->csFake.lock_idx);
- }
-
- return result;
-}
-
-void
-ptw32_DeleteCriticalSection (ptw32_cs_u_t * csect)
- /*
- * ------------------------------------------------------
- *
- * PARAMETERS
- * csect
- * pointer to an instance of ptw32_cs_u_t
- *
- * DESCRIPTION
- * Internal implementation of DeleteCriticalSection.
- *
- * ------------------------------------------------------
- */
-{
- if (NULL != ptw32_try_enter_critical_section)
- {
- DeleteCriticalSection(&csect->cs);
- }
- else
- {
- while (InterlockedIncrement(&csect->csFake.lock_idx) > 0)
- {
- InterlockedDecrement(&csect->csFake.lock_idx);
- Sleep(0);
- }
-
- if (csect->csFake.valid
- && csect->csFake.entered_count == 0)
- {
- csect->csFake.valid = 0;
- }
-
- InterlockedDecrement(&csect->csFake.lock_idx);
- }
-}
-
-void
-ptw32_EnterCriticalSection(ptw32_cs_u_t * csect)
- /*
- * ------------------------------------------------------
- *
- * PARAMETERS
- * csect
- * pointer to an instance of ptw32_cs_u_t
- *
- * DESCRIPTION
- * Internal implementation of EnterCriticalSection.
- *
- * ------------------------------------------------------
- */
-{
- if (NULL != ptw32_try_enter_critical_section)
- {
- EnterCriticalSection(&csect->cs);
- }
- else
- {
- pthread_t self = pthread_self();
-
- while (InterlockedIncrement(&csect->csFake.lock_idx) >= 0
- && csect->csFake.valid
- && csect->csFake.owner != NULL
- && csect->csFake.owner != self)
- {
- InterlockedDecrement(&csect->csFake.lock_idx);
- Sleep(0);
- }
-
- if (csect->csFake.valid)
- {
- csect->csFake.entered_count++;
- csect->csFake.owner = self;
- }
-
- InterlockedDecrement(&csect->csFake.lock_idx);
- }
-}
-
-void
-ptw32_LeaveCriticalSection (ptw32_cs_u_t * csect)
- /*
- * ------------------------------------------------------
- *
- * PARAMETERS
- * csect
- * pointer to an instance of ptw32_cs_u_t
- *
- * DESCRIPTION
- * Internal implementation of LeaveCriticalSection.
- *
- * ------------------------------------------------------
- */
-{
- if (NULL != ptw32_try_enter_critical_section)
- {
- LeaveCriticalSection(&csect->cs);
- }
- else
- {
- while (InterlockedIncrement(&csect->csFake.lock_idx) > 0)
- {
- InterlockedDecrement(&csect->csFake.lock_idx);
- Sleep(0);
- }
-
- if (csect->csFake.valid)
- {
- csect->csFake.entered_count--;
- if (csect->csFake.entered_count == 0)
- {
- csect->csFake.owner = NULL;
- }
- }
-
- InterlockedDecrement(&csect->csFake.lock_idx);
- }
-}
-
-BOOL
-ptw32_TryEnterCriticalSection (ptw32_cs_u_t * csect)
- /*
- * ------------------------------------------------------
- *
- * PARAMETERS
- * csect
- * pointer to an instance of ptw32_cs_u_t
- *
- * DESCRIPTION
- * Internal implementation of TryEnterCriticalSection.
- *
- * RETURNS
- * FALSE Current thread doesn't own the
- * lock,
- * TRUE Current thread owns the lock
- * (if the current thread already
- * held the lock then we recursively
- * enter).
- * ------------------------------------------------------
- */
-{
- BOOL result = FALSE;
-
- if (NULL != ptw32_try_enter_critical_section)
- {
- result = (*ptw32_try_enter_critical_section)(&csect->cs);
- }
- else
- {
- pthread_t self;
-
- while (InterlockedIncrement(&csect->csFake.lock_idx) > 0)
- {
- InterlockedDecrement(&csect->csFake.lock_idx);
- Sleep(0);
- }
-
- self = pthread_self();
-
- if (csect->csFake.valid
- && (csect->csFake.owner == NULL || csect->csFake.owner == self))
- {
- /*
- * The semantics of TryEnterCriticalSection
- * (according to the documentation at MS)
- * are that the CS is entered recursively
- * if the thread is the current owner.
- */
- csect->csFake.entered_count++;
- csect->csFake.owner = self;
- result = TRUE;
- }
-
- InterlockedDecrement(&csect->csFake.lock_idx);
- }
-
- return result;
-}
-
-
int
pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
{
@@ -349,16 +103,9 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
goto FAIL0;
}
- mx->cs.csFake.lock_idx = -1;
-
- result = ptw32_InitializeCriticalSection(&mx->cs);
- if (result != 0)
- {
- goto FAIL1;
- }
-
- mx->lockCount = 0;
- mx->ownerThread = NULL;
+ mx->lock_idx = -1;
+ mx->owner = NULL;
+ mx->try_lock = 0;
if (attr != NULL && *attr != NULL)
{
@@ -393,7 +140,11 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
mx->pshared = PTHREAD_PROCESS_PRIVATE;
}
-FAIL1:
+ if (mx->type == PTHREAD_MUTEX_DEFAULT)
+ {
+ mx->type = ptw32_mutex_mapped_default;
+ }
+
if (result != 0 && mx != NULL)
{
free(mx);
@@ -428,7 +179,7 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)
* Check to see if the mutex is held by any thread. We
* can't destroy it if it is. Pthread_mutex_trylock is
* not recursive and will return EBUSY even if the current
- * thread (us) holds the lock.
+ * thread holds the lock.
*/
result = pthread_mutex_trylock(&mx);
@@ -447,7 +198,6 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)
if (result == 0)
{
- ptw32_DeleteCriticalSection(&mx->cs);
free(mx);
}
else
@@ -892,53 +642,66 @@ pthread_mutex_lock(pthread_mutex_t *mutex)
switch (mx->type)
{
- case PTHREAD_MUTEX_NORMAL:
- if (pthread_equal(mx->ownerThread, self))
+ case PTHREAD_MUTEX_DEFAULT:
+ case PTHREAD_MUTEX_RECURSIVE:
+ if (InterlockedIncrement(&mx->lock_idx) > 0)
{
- /*
- * Pretend to be deadlocked but release the
- * mutex if we are [asynchronously] canceled.
- */
- pthread_cleanup_push(pthread_mutex_unlock, (void *) mutex);
- while (TRUE)
+ while (mx->try_lock)
{
Sleep(0);
}
- pthread_cleanup_pop(1);
- /*
- * Never gets beyond here.
- */
+ while (mx->lock_idx > 0 && mx->owner != self)
+ {
+ Sleep(0);
+ }
}
- else
+ mx->owner = self;
+ break;
+ case PTHREAD_MUTEX_NORMAL:
+ /*
+ * If the thread already owns the mutex
+ * then the thread will become deadlocked.
+ */
+ while (InterlockedIncrement(&mx->lock_idx) > 0)
{
- ptw32_EnterCriticalSection(&mx->cs);
+ InterlockedDecrement(&mx->lock_idx);
+ Sleep(0);
}
+ mx->owner = self;
break;
case PTHREAD_MUTEX_ERRORCHECK:
- if (pthread_equal(mx->ownerThread, self))
+ if (0 == InterlockedIncrement(&mx->lock_idx))
{
- result = EDEADLK;
+ mx-owner = self;
}
else
{
- ptw32_EnterCriticalSection(&mx->cs);
+ while (mx->try_lock)
+ {
+ Sleep(0);
+ }
+
+ while (mx->lock_idx > 0 && mx->owner != self)
+ {
+ Sleep(0);
+ }
+
+ if (mx->owner == self)
+ {
+ InterlockedDecrement(&mx->lock_idx);
+ result = EDEADLK;
+ }
+ else
+ {
+ mx->owner = self;
+ }
}
break;
- case PTHREAD_MUTEX_DEFAULT:
- case PTHREAD_MUTEX_RECURSIVE:
- ptw32_EnterCriticalSection(&mx->cs);
- break;
default:
result = EINVAL;
break;
}
-
- if (result == 0)
- {
- mx->ownerThread = self;
- mx->lockCount++;
- }
}
return result;
@@ -964,17 +727,25 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
*/
if (mx != (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
{
- if (pthread_equal(mx->ownerThread, pthread_self()))
+ if (mx->owner == pthread_self())
{
- mx->lockCount--;
-
- if (mx->lockCount == 0)
- {
- mx->ownerThread = NULL;
- }
+ switch (mx->type)
+ {
+ case PTHREAD_MUTEX_NORMAL:
+ case PTHREAD_MUTEX_ERRORCHECK:
+ mx->owner = NULL;
+ break;
+ case PTHREAD_MUTEX_RECURSIVE:
+ default:
+ if (mx->lock_idx == 0)
+ {
+ mx->owner = NULL;
+ }
+ break;
+ }
- ptw32_LeaveCriticalSection(&mx->cs);
- }
+ InterlockedDecrement(&mx->lock_idx);
+ }
else
{
result = EPERM;
@@ -1012,28 +783,34 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
}
mx = *mutex;
- self = pthread_self();
if (result == 0)
{
+ self = pthread_self();
/*
- * TryEnterCriticalSection is a little different to
- * the POSIX trylock semantics. Trylock returns
- * EBUSY even if the calling thread already owns
- * the mutex - it doesn't lock it recursively, even
+ * Trylock returns EBUSY if the mutex is held already,
+ * even if the current thread owns the mutex - ie. it
+ * doesn't lock it recursively, even
* if the mutex type is PTHREAD_MUTEX_RECURSIVE.
*/
- if (ptw32_TryEnterCriticalSection(&mx->cs))
+ if (0 == (mx->lock_idx + 1))
{
- /*
- * We now own the lock, but check that we don't
- * already own the mutex.
- */
- if (pthread_equal(mx->ownerThread, self))
+ mx->try_lock++;
+
+ if (0 == InterlockedIncrement(&mx->lock_idx))
{
- ptw32_LeaveCriticalSection(&mx->cs);
- result = EBUSY;
+ mx->owner = self;
+ }
+ else
+ {
+ InterlockedDecrement(&mx->lock_idx);
+ if (mx->owner == self)
+ {
+ result = EBUSY;
+ }
}
+
+ mx->try_lock--;
}
else
{
@@ -1041,12 +818,6 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
}
}
- if (result == 0)
- {
- mx->ownerThread = self;
- mx->lockCount++;
- }
-
return result;
}
diff --git a/nonportable.c b/nonportable.c
index 17cbc60..27b67df 100644
--- a/nonportable.c
+++ b/nonportable.c
@@ -248,3 +248,59 @@ pthread_win32_thread_detach_np ()
return TRUE;
}
+
+
+/*
+ * pthread_mutex_setdefaulttype_np --
+ *
+ * Sets the default type to be given to all
+ * POSIX mutexes initialised after the function
+ * is called. Any of the following type values
+ * can be made the default type:
+ *
+ * PTHREAD_MUTEX_NORMAL
+ * PTHREAD_MUTEX_ERRORCHECK
+ * PTHREAD_MUTEX_RECURSIVE
+ * PTHREAD_MUTEX_DEFAULT
+ *
+ * Any mutex initialised with type PTHREAD_MUTEX_DEFAULT
+ * will be set to the mapped type instead. Previously
+ * initialised mutexes are not changed.
+ *
+ * When set to PTHREAD_MUTEX_DEFAULT (the initial
+ * value), mutexes will behave as for the
+ * PTHREAD_MUTEX_RECURSIVE type.
+ *
+ * If 'oldtype' is a non-NULL pointer, the previous type is
+ * returned through it.
+ * To get the previous type without setting a new type,
+ * use -1 as the 'newtype' value. Of course, the following:
+ *
+ * pthread_mutex_setdefaulttype_np(-1, NULL);
+ *
+ * is then an extravagant equivalent to the value 0 (zero).
+ */
+int
+pthread_mutex_setdefaulttype_np (int newtype, int * oldtype)
+{
+ int result = 0;
+
+ if (oldtype != NULL)
+ {
+ *oldType = ptw32_mutex_mapped_default;
+ }
+
+ switch (newtype)
+ {
+ case PTHREAD_MUTEX_DEFAULT:
+ case PTHREAD_MUTEX_NORMAL:
+ case PTHREAD_MUTEX_ERRORCHECK:
+ case PTHREAD_MUTEX_RECURSIVE:
+ ptw32_mutex_mapped_default = newtype;
+ break;
+ default:
+ result = EINVAL;
+ }
+
+ return result;
+}
diff --git a/pthread.def b/pthread.def
index 580caf5..b16aba7 100644
--- a/pthread.def
+++ b/pthread.def
@@ -1,5 +1,5 @@
; pthread.def
-; Last updated: $Date: 2001/02/06 05:44:38 $
+; Last updated: $Date: 2001/02/09 06:51:30 $
; Currently unimplemented functions are commented out.
@@ -107,6 +107,7 @@ pthread_rwlock_unlock
;
pthread_getw32threadhandle_np
pthread_delay_np
+pthread_mutex_setdefaulttype_np
pthreadCancelableWait
pthreadCancelableTimedWait
; For use when linking statically
diff --git a/pthread.h b/pthread.h
index d12bc41..e40aaef 100644
--- a/pthread.h
+++ b/pthread.h
@@ -631,10 +631,10 @@ int pthread_attr_setschedparam (pthread_attr_t *attr,
const struct sched_param *param);
int pthread_attr_setscope (pthread_attr_t *,
- int);
+ int);
int pthread_attr_getscope (const pthread_attr_t *,
- int *);
+ int *);
/*
* PThread Functions
@@ -793,10 +793,19 @@ int pthread_rwlock_unlock(pthread_rwlock_t *lock);
* Non-portable functions
*/
-/* Possibly supported by other POSIX threads implimentations */
+/*
+ * Possibly supported by other POSIX threads implimentations
+ */
int pthread_delay_np (struct timespec * interval);
/*
+ * Remaps the default mutex type to any of the
+ * other possible types. Returns the previous type.
+ */
+int pthread_mutex_setdefaulttype_np (int newtype,
+ int * oldtype);
+
+/*
* Returns the Win32 thread HANDLE associated
* with the given POSIX thread.
*/
@@ -828,7 +837,8 @@ int pthread_win32_thread_detach_np(void);
* WaitForMultipleObjects.
*/
int pthreadCancelableWait (HANDLE waitHandle);
-int pthreadCancelableTimedWait (HANDLE waitHandle, DWORD timeout);
+int pthreadCancelableTimedWait (HANDLE waitHandle,
+ DWORD timeout);
/*
* Thread-Safe C Runtime Library Mappings.