summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--implement.h24
-rw-r--r--mutex.c125
-rw-r--r--tests/mutex1.c2
3 files changed, 69 insertions, 82 deletions
diff --git a/implement.h b/implement.h
index 41c220d..1addce6 100644
--- a/implement.h
+++ b/implement.h
@@ -119,27 +119,27 @@ struct pthread_attr_t_ {
*/
/*
- * The following macros provide exclusive access to an object's pointer.
+ * The following macros are used to serialise access to an object,
+ * including possibly before it is initialised.
* See mutex.c:pthread_mutex_lock() for an example.
*/
-#define PTW32_OBJECT_GET(type, ppObject, pDest) \
- while (((pDest) = (type) InterlockedCompareExchangePointer((PVOID *)(ppObject), \
- (PVOID)PTW32_OBJECT_IN_USE, \
- (PVOID)PTW32_OBJECT_IN_USE)) \
+#define PTW32_OBJECT_GET(type, pObject, Dest) \
+ while (((Dest) = (type) InterlockedExchange((LPLONG)(pObject), \
+ (LONG)PTW32_OBJECT_IN_USE)) \
== (type)PTW32_OBJECT_IN_USE) \
{ \
Sleep(0); \
}
-#define PTW32_OBJECT_SET(ppObject, value) \
- (void) InterlockedExchangePointer((PVOID *)(ppObject), (PVOID)(value))
+#define PTW32_OBJECT_SET(pObject, value) \
+ (void) InterlockedExchange((LPLONG)(pObject), (LONG)(value))
-#define PTW32_OBJECT_TRYGET(type, ppObject, pDest) \
- ((((pDest) = (type) InterlockedExchangePointer((PVOID *)(ppObject), \
- (PVOID)PTW32_OBJECT_IN_USE)) \
- == (type)PTW32_OBJECT_IN_USE) ? ((void) InterlockedExchangePointer((PVOID *)(ppObject), \
- (PVOID)(pDest)) , 0) \
+#define PTW32_OBJECT_TRYGET(type, pObject, Dest) \
+ ((((Dest) = (type) InterlockedExchange((LPLONG)(pObject), \
+ (LONG)PTW32_OBJECT_IN_USE)) \
+ == (type)PTW32_OBJECT_IN_USE) ? ((void) InterlockedExchange((LPLONG)(pObject), \
+ (LONG)(Dest)) , 0) \
: 1)
#define PTW32_OBJECT_IN_USE ((void *) -2)
diff --git a/mutex.c b/mutex.c
index 4d0e2bb..ff84e2a 100644
--- a/mutex.c
+++ b/mutex.c
@@ -67,6 +67,12 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
return EINVAL;
}
+ if (attr != NULL && *attr != NULL && (*attr)->pshared == PTHREAD_PROCESS_SHARED)
+ {
+ return ENOSYS;
+ }
+
+
/*
* We need to prevent us from being canceled
* unexpectedly leaving the mutex in a corrupted state.
@@ -85,12 +91,6 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
*/
PTW32_OBJECT_GET(pthread_mutex_t, mutex, mx);
- if (mx == NULL)
- {
- result = EINVAL;
- goto FAIL0;
- }
-
/*
* We now have exclusive access to the mutex pointer
* and structure, whether initialised or not.
@@ -100,71 +100,44 @@ pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
if (mx == NULL)
{
result = ENOMEM;
- goto FAIL1;
+ goto FAIL0;
}
- mx->lock_idx = -1;
- mx->try_lock = 0;
- mx->owner = NULL;
- mx->waiters = 0;
- mx->lastOwner = NULL;
- mx->lastWaiter = NULL;
-
if (attr != NULL && *attr != NULL)
{
- mx->type = (*attr)->type;
mx->pshared = (*attr)->pshared;
-
- if (mx->pshared == PTHREAD_PROCESS_SHARED)
+ if ((*attr)->type == PTHREAD_MUTEX_DEFAULT)
{
- /*
- * Creating mutex that can be shared between
- * processes.
- */
-
-#if _POSIX_THREAD_PROCESS_SHARED
-
- /*
- * Not implemented yet.
- */
-
-#error ERROR [__FILE__, line __LINE__]: Process shared mutexes are not supported yet.
-
-#else
-
- result = ENOSYS;
-
-#endif /* _POSIX_THREAD_PROCESS_SHARED */
+ mx->type = ptw32_mutex_mapped_default;
+ }
+ else
+ {
+ mx->type = (*attr)->type;
}
}
else
{
- mx->type = PTHREAD_MUTEX_DEFAULT;
- mx->pshared = PTHREAD_PROCESS_PRIVATE;
- }
-
- if (mx->type == PTHREAD_MUTEX_DEFAULT)
- {
mx->type = ptw32_mutex_mapped_default;
+ mx->pshared = PTHREAD_PROCESS_PRIVATE;
}
- if (result != 0 && mx != NULL)
- {
- free(mx);
- mx = NULL;
- }
+ mx->lock_idx = -1;
+ mx->try_lock = 0;
+ mx->owner = NULL;
+ mx->waiters = 0;
+ mx->lastOwner = NULL;
+ mx->lastWaiter = NULL;
- FAIL1:
+ FAIL0:
PTW32_OBJECT_SET(mutex, mx);
- FAIL0:
- (void) pthread_mutex_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
}
- return(result);
+ return result;
}
int
@@ -259,12 +232,12 @@ pthread_mutex_destroy(pthread_mutex_t *mutex)
mx = NULL;
}
+ FAIL0:
PTW32_OBJECT_SET(mutex, mx);
- FAIL0:
- (void) pthread_mutex_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
}
@@ -711,7 +684,7 @@ pthread_mutex_lock(pthread_mutex_t *mutex)
if (mx == (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
{
- result = pthread_mutex_init(&mx);
+ result = pthread_mutex_init(&mx, NULL);
}
if (result == 0)
@@ -774,13 +747,17 @@ WAIT_RECURSIVE:
mx->lastWaiter = self;
mx->lock_idx--;
PTW32_OBJECT_SET(mutex, mx);
- (void) pthread_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
+ Sleep(0);
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+ }
+ else
+ {
+ Sleep(0);
}
- Sleep(0);
- (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
PTW32_OBJECT_GET(pthread_mutex_t, mutex, mx);
/*
* Thread priorities may have tricked another
@@ -846,13 +823,17 @@ WAIT_NORMAL:
mx->lastWaiter = self;
mx->lock_idx--;
PTW32_OBJECT_SET(mutex, mx);
- (void) pthread_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
+ Sleep(0);
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+ }
+ else
+ {
+ Sleep(0);
}
- Sleep(0);
- (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
PTW32_OBJECT_GET(pthread_mutex_t, mutex, mx);
/*
* Thread priorities may have tricked another
@@ -920,13 +901,17 @@ WAIT_ERRORCHECK:
mx->lastWaiter = self;
mx->lock_idx--;
PTW32_OBJECT_SET(mutex, mx);
- (void) pthread_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
+ Sleep(0);
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
+ }
+ else
+ {
+ Sleep(0);
}
- Sleep(0);
- (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
PTW32_OBJECT_GET(pthread_mutex_t, mutex, mx);
/*
* Thread priorities may have tricked another
@@ -947,12 +932,12 @@ WAIT_ERRORCHECK:
}
}
+ FAIL0:
PTW32_OBJECT_SET(mutex, mx);
- FAIL0:
- (void) pthread_mutex_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
}
@@ -1007,7 +992,7 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
* asynch cancelation then we also check if we've
* been canceled at the same time.
*/
- (void) pthread_mutex_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldCancelType);
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldCancelType);
/*
* This waits until no other thread is looking at the
@@ -1052,12 +1037,12 @@ pthread_mutex_unlock(pthread_mutex_t *mutex)
result = EPERM;
}
+ FAIL0:
PTW32_OBJECT_SET(mutex, mx);
- FAIL0:
- (void) pthread_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
}
@@ -1116,7 +1101,7 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
* asynch cancelation then we also check if we've
* been canceled at the same time.
*/
- (void) pthread_mutex_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldCancelType);
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldCancelType);
/*
* If no other thread is looking at the
@@ -1142,7 +1127,7 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
if (mx == (pthread_mutex_t) PTW32_OBJECT_AUTO_INIT)
{
- result = pthread_mutex_init(&mx);
+ result = pthread_mutex_init(&mx, NULL);
}
if (result == 0)
@@ -1181,9 +1166,9 @@ pthread_mutex_trylock(pthread_mutex_t *mutex)
PTW32_OBJECT_SET(mutex, mx);
FAIL0:
- (void) pthread_setcanceltype(oldCancelType, NULL);
if (oldCancelType == PTHREAD_CANCEL_ASYNCHRONOUS)
{
+ (void) pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, NULL);
pthread_testcancel();
}
diff --git a/tests/mutex1.c b/tests/mutex1.c
index c997963..2d11867 100644
--- a/tests/mutex1.c
+++ b/tests/mutex1.c
@@ -11,6 +11,8 @@
* pthread_mutex_destroy()
*/
+#define ASSERT_TRACE
+
#include "test.h"
pthread_mutex_t mutex = NULL;