struct __mthread_tcb;
typedef struct {
- struct __mthread_tcb *head;
- struct __mthread_tcb *tail;
+ struct __mthread_tcb *mq_head;
+ struct __mthread_tcb *mq_tail;
} mthread_queue_t;
struct __mthread_mutex {
- mthread_queue_t queue; /* Queue of threads blocked on this mutex */
- mthread_thread_t owner; /* Thread ID that currently owns mutex */
- struct __mthread_mutex *prev;
- struct __mthread_mutex *next;
+ mthread_queue_t mm_queue; /* Queue of threads blocked on this mutex */
+ mthread_thread_t mm_owner; /* Thread ID that currently owns mutex */
+ struct __mthread_mutex *mm_prev;
+ struct __mthread_mutex *mm_next;
+ unsigned int mm_magic;
};
typedef struct __mthread_mutex *mthread_mutex_t;
struct __mthread_cond {
- struct __mthread_mutex *mutex; /* Associate mutex with condition */
- struct __mthread_cond *prev;
- struct __mthread_cond *next;
+ struct __mthread_mutex *mc_mutex; /* Associate mutex with condition */
+ struct __mthread_cond *mc_prev;
+ struct __mthread_cond *mc_next;
+ unsigned int mc_magic;
};
typedef struct __mthread_cond *mthread_cond_t;
struct __mthread_attr {
- size_t a_stacksize;
- char *a_stackaddr;
- int a_detachstate;
- struct __mthread_attr *prev;
- struct __mthread_attr *next;
+ size_t ma_stacksize;
+ char *ma_stackaddr;
+ int ma_detachstate;
+ struct __mthread_attr *ma_prev;
+ struct __mthread_attr *ma_next;
};
typedef struct __mthread_attr *mthread_attr_t;
_PROTOTYPE( int mthread_mutex_destroy, (mthread_mutex_t *mutex) );
_PROTOTYPE( int mthread_mutex_init, (mthread_mutex_t *mutex,
mthread_mutexattr_t *mattr) );
-#if 0
_PROTOTYPE( int mthread_mutex_lock, (mthread_mutex_t *mutex) );
-#endif
-_PROTOTYPE( int mthread_mutex_lock_f, (mthread_mutex_t *mutex,
- char *file, int line) );
-#define mthread_mutex_lock(x) mthread_mutex_lock_f(x, __FILE__, __LINE__)
_PROTOTYPE( int mthread_mutex_trylock, (mthread_mutex_t *mutex) );
_PROTOTYPE( int mthread_mutex_unlock, (mthread_mutex_t *mutex) );
if (tcb->m_state == MS_DEAD) {
errno = ESRCH;
return(-1);
- } else if (tcb->m_attr.a_detachstate != MTHREAD_CREATE_DETACHED) {
+ } else if (tcb->m_attr.ma_detachstate != MTHREAD_CREATE_DETACHED) {
if (tcb->m_state == MS_EXITING)
mthread_thread_stop(detach);
else
- tcb->m_attr.a_detachstate = MTHREAD_CREATE_DETACHED;
+ tcb->m_attr.ma_detachstate = MTHREAD_CREATE_DETACHED;
}
return(0);
tcb->m_result = value;
tcb->m_state = MS_EXITING;
- if (tcb->m_attr.a_detachstate == MTHREAD_CREATE_DETACHED) {
+ if (tcb->m_attr.ma_detachstate == MTHREAD_CREATE_DETACHED) {
mthread_thread_stop(current_thread);
} else {
/* Joinable thread; notify possibly waiting thread */
* not enter this clause.
*/
- if (getcontext(&(mainthread.m_context)) == -1)
+ if (mthread_getcontext(&(mainthread.m_context)) == -1)
mthread_panic("Couldn't save state for main thread");
current_thread = MAIN_THREAD;
mthread_init_scheduler();
/* Initialize the fallback thread */
- if (getcontext(FALLBACK_CTX) == -1)
+ if (mthread_getcontext(FALLBACK_CTX) == -1)
mthread_panic("Could not initialize fallback thread");
FALLBACK_CTX->uc_link = &(mainthread.m_context);
FALLBACK_CTX->uc_stack.ss_sp = fallback_stack;
if (tcb->m_state == MS_DEAD) {
errno = ESRCH;
return(-1);
- } else if (tcb->m_attr.a_detachstate == MTHREAD_CREATE_DETACHED) {
+ } else if (tcb->m_attr.ma_detachstate == MTHREAD_CREATE_DETACHED) {
errno = EINVAL;
return(-1);
}
tcb->m_context.uc_link = FALLBACK_CTX;
/* then construct this thread's context to run procedure proc. */
- if (getcontext(&(tcb->m_context)) == -1)
+ if (mthread_getcontext(&(tcb->m_context)) == -1)
mthread_panic("Failed to initialize context state");
- stacksize = tcb->m_attr.a_stacksize;
- stackaddr = tcb->m_attr.a_stackaddr;
+ stacksize = tcb->m_attr.ma_stacksize;
+ stackaddr = tcb->m_attr.ma_stackaddr;
if (stacksize == (size_t) 0)
stacksize = (size_t) MTHREAD_STACK_MIN;
rt->m_arg = NULL;
rt->m_result = NULL;
rt->m_cond = NULL;
- if (rt->m_context.uc_stack.ss_sp)
+ if (rt->m_context.uc_stack.ss_sp) {
free(rt->m_context.uc_stack.ss_sp); /* Free allocated stack */
- rt->m_context.uc_stack.ss_sp = NULL;
+ rt->m_context.uc_stack.ss_sp = NULL;
+ }
rt->m_context.uc_stack.ss_size = 0;
rt->m_context.uc_link = NULL;
}
if (va_front == NULL) { /* Empty list */
va_front = *a;
- (*a)->prev = NULL;
+ (*a)->ma_prev = NULL;
} else {
- va_rear->next = *a;
- (*a)->prev = va_rear;
+ va_rear->ma_next = *a;
+ (*a)->ma_prev = va_rear;
}
- (*a)->next = NULL;
+ (*a)->ma_next = NULL;
va_rear = *a;
}
if ((a = malloc(sizeof(struct __mthread_attr))) == NULL)
return(-1);
- a->a_detachstate = MTHREAD_CREATE_JOINABLE;
- a->a_stackaddr = NULL;
- a->a_stacksize = (size_t) 0;
+ a->ma_detachstate = MTHREAD_CREATE_JOINABLE;
+ a->ma_stackaddr = NULL;
+ a->ma_stacksize = (size_t) 0;
*attr = (mthread_attr_t) a;
mthread_attr_add(attr); /* Validate attribute: attribute now in use */
return(-1);
}
- *detachstate = a->a_detachstate;
+ *detachstate = a->ma_detachstate;
return(0);
}
return(-1);
}
- a->a_detachstate = detachstate;
+ a->ma_detachstate = detachstate;
return(0);
}
return(-1);
}
- *stackaddr = a->a_stackaddr;
- *stacksize = a->a_stacksize;
+ *stackaddr = a->ma_stackaddr;
+ *stacksize = a->ma_stacksize;
return(0);
}
return(-1);
}
- *stacksize = a->a_stacksize;
+ *stacksize = a->ma_stacksize;
return(0);
}
* the cost of some memory if needed).
*/
- a->a_stackaddr = stackaddr;
- a->a_stacksize = stacksize;
+ a->ma_stackaddr = stackaddr;
+ a->ma_stacksize = stacksize;
return(0);
}
return(-1);
}
- a->a_stacksize = stacksize;
+ a->ma_stacksize = stacksize;
return(0);
}
{
/* Remove attribute from list of valid, initialized attributes */
- if ((*a)->prev == NULL)
- va_front = (*a)->next;
+ if ((*a)->ma_prev == NULL)
+ va_front = (*a)->ma_next;
else
- (*a)->prev->next = (*a)->next;
+ (*a)->ma_prev->ma_next = (*a)->ma_next;
- if ((*a)->next == NULL)
- va_rear = (*a)->prev;
+ if ((*a)->ma_next == NULL)
+ va_rear = (*a)->ma_prev;
else
- (*a)->next->prev = (*a)->prev;
+ (*a)->ma_next->ma_prev = (*a)->ma_prev;
}
if (loopitem == *a)
return(1);
- loopitem = loopitem->next;
+ loopitem = loopitem->ma_next;
}
return(0);
loopitem = va_front;
while (loopitem != NULL) {
- loopitem = loopitem->next;
+ loopitem = loopitem->ma_next;
return(0);
}
#include "proto.h"
PRIVATE struct __mthread_cond *vc_front, *vc_rear;
+#ifdef MTHREAD_STRICT
FORWARD _PROTOTYPE( void mthread_cond_add, (mthread_cond_t *c) );
FORWARD _PROTOTYPE( void mthread_cond_remove, (mthread_cond_t *c) );
FORWARD _PROTOTYPE( int mthread_cond_valid, (mthread_cond_t *c) );
+#else
+# define mthread_cond_add(c) ((*c)->mc_magic = MTHREAD_INIT_MAGIC)
+# define mthread_cond_remove(c) ((*c)->mc_magic = MTHREAD_NOT_INUSE)
+# define mthread_cond_valid(c) ((*c)->mc_magic == MTHREAD_INIT_MAGIC)
+#endif
#define MAIN_COND mainthread.m_cond
/*===========================================================================*
/*===========================================================================*
* mthread_cond_add *
*===========================================================================*/
+#ifdef MTHREAD_STRICT
PRIVATE void mthread_cond_add(c)
mthread_cond_t *c;
{
if (vc_front == NULL) { /* Empty list */
vc_front = *c;
- (*c)->prev = NULL;
+ (*c)->mc_prev = NULL;
} else {
- vc_rear->next = *c;
- (*c)->prev = vc_rear;
+ vc_rear->mc_next = *c;
+ (*c)->mc_prev = vc_rear;
}
- (*c)->next = NULL;
+ (*c)->mc_next = NULL;
vc_rear = *c;
}
-
+#endif
/*===========================================================================*
* mthread_cond_broadcast *
mthread_init(); /* Make sure libmthread is initialized */
- if(cond == NULL) {
+ if (cond == NULL) {
errno = EINVAL;
return(-1);
- }
-
- if (!mthread_cond_valid(cond)) {
+ } else if (!mthread_cond_valid(cond)) {
errno = EINVAL;
return(-1);
}
if (cond == NULL) {
errno = EINVAL;
return(-1);
- }
-
- if (!mthread_cond_valid(cond)) {
+ } else if (!mthread_cond_valid(cond)) {
errno = EINVAL;
return(-1);
}
for (t = (mthread_thread_t) 0; t < no_threads; t++) {
tcb = mthread_find_tcb(t);
- if(tcb->m_state == MS_CONDITION && tcb->m_cond == *cond){
+ if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond){
errno = EBUSY;
return(-1);
}
errno = ENOSYS;
return(-1);
}
-
- if (mthread_cond_valid(cond)) {
+#ifdef MTHREAD_STRICT
+ else if (mthread_cond_valid(cond)) {
/* Already initialized */
errno = EBUSY;
return(-1);
- }
-
- if ((c = malloc(sizeof(struct __mthread_cond))) == NULL)
+ }
+#endif
+ else if ((c = malloc(sizeof(struct __mthread_cond))) == NULL) {
+ errno = ENOMEM;
return(-1);
+ }
- c->mutex = NULL;
+ c->mc_mutex = NULL;
*cond = (mthread_cond_t) c;
mthread_cond_add(cond);
/*===========================================================================*
* mthread_cond_remove *
*===========================================================================*/
+#ifdef MTHREAD_STRICT
PRIVATE void mthread_cond_remove(c)
mthread_cond_t *c;
{
/* Remove condition from list of valid, initialized conditions */
- if ((*c)->prev == NULL)
- vc_front = (*c)->next;
+ if ((*c)->mc_prev == NULL)
+ vc_front = (*c)->mc_next;
else
- (*c)->prev->next = (*c)->next;
+ (*c)->mc_prev->mc_next = (*c)->mc_next;
- if ((*c)->next == NULL)
- vc_rear = (*c)->prev;
+ if ((*c)->mc_next == NULL)
+ vc_rear = (*c)->mc_prev;
else
- (*c)->next->prev = (*c)->prev;
+ (*c)->mc_next->mc_prev = (*c)->mc_prev;
}
-
+#endif
/*===========================================================================*
* mthread_cond_signal *
mthread_init(); /* Make sure libmthread is initialized */
- if(cond == NULL) {
+ if (cond == NULL) {
errno = EINVAL;
return(-1);
- }
-
- if (!mthread_cond_valid(cond)) {
+ } else if (!mthread_cond_valid(cond)) {
errno = EINVAL;
return(-1);
}
for (t = (mthread_thread_t) 0; t < no_threads; t++) {
tcb = mthread_find_tcb(t);
- if(tcb->m_state == MS_CONDITION && tcb->m_cond == *cond){
+ if (tcb->m_state == MS_CONDITION && tcb->m_cond == *cond){
mthread_unsuspend(t);
break;
}
/*===========================================================================*
* mthread_cond_valid *
*===========================================================================*/
+#ifdef MTHREAD_STRICT
PRIVATE int mthread_cond_valid(c)
mthread_cond_t *c;
{
/* Check to see if cond is on the list of valid conditions */
struct __mthread_cond *loopitem;
+ mthread_init();
+
loopitem = vc_front;
while (loopitem != NULL) {
if (loopitem == *c)
return(1);
- loopitem = loopitem->next;
+ loopitem = loopitem->mc_next;
}
return(0);
}
-
+#endif
/*===========================================================================*
* mthread_cond_verify *
return(-1);
}
- c->mutex = m; /* Remember we're using this mutex in a cond_wait */
+ c->mc_mutex = m; /* Remember we're using this mutex in a cond_wait */
if (mthread_mutex_unlock(mutex) != 0) /* Fails when we're not the owner */
return(-1);
mthread_suspend(MS_CONDITION);
/* When execution returns here, the condition was met. Lock mutex again. */
- c->mutex = NULL; /* Forget about this mutex */
+ c->mc_mutex = NULL; /* Forget about this mutex */
tcb->m_cond = NULL; /* ... and condition var */
if (mthread_mutex_lock(mutex) != 0)
return(-1);
#define MAIN_THREAD -1
#define NO_THREAD -2
#define isokthreadid(i) (i == MAIN_THREAD || (i >= 0 && i < no_threads))
+#define MTHREAD_INIT_MAGIC 0xca11ab1e
+#define MTHREAD_NOT_INUSE 0xdefec7
typedef enum {
MS_CONDITION, MS_DEAD, MS_EXITING, MS_FALLBACK_EXITING, MS_MUTEX, MS_RUNNABLE
#include "proto.h"
PRIVATE struct __mthread_mutex *vm_front, *vm_rear;
+#ifdef MTHREAD_STRICT
FORWARD _PROTOTYPE( void mthread_mutex_add, (mthread_mutex_t *m) );
FORWARD _PROTOTYPE( void mthread_mutex_remove, (mthread_mutex_t *m) );
+#else
+# define mthread_mutex_add(m) ((*m)->mm_magic = MTHREAD_INIT_MAGIC)
+# define mthread_mutex_remove(m) ((*m)->mm_magic = MTHREAD_NOT_INUSE)
+#endif
/*===========================================================================*
* mthread_init_valid_mutexes *
/*===========================================================================*
* mthread_mutex_add *
*===========================================================================*/
+#ifdef MTHREAD_STRICT
PRIVATE void mthread_mutex_add(m)
mthread_mutex_t *m;
{
if (vm_front == NULL) { /* Empty list */
vm_front = *m;
- (*m)->prev = NULL;
+ (*m)->mm_prev = NULL;
} else {
- vm_rear->next = *m;
- (*m)->prev = vm_rear;
+ vm_rear->mm_next = *m;
+ (*m)->mm_prev = vm_rear;
}
- (*m)->next = NULL;
+ (*m)->mm_next = NULL;
vm_rear = *m;
}
-
+#endif
/*===========================================================================*
* mthread_mutex_destroy *
if (!mthread_mutex_valid(mutex)) {
errno = EINVAL;
return(-1);
- } else if ((*mutex)->owner != NO_THREAD) {
- printf("mutex owner is %d, so not destroying\n", (*mutex)->owner);
+ } else if ((*mutex)->mm_owner != NO_THREAD) {
errno = EBUSY;
return(-1);
}
for (t = (mthread_thread_t) 0; t < no_threads; t++) {
tcb = mthread_find_tcb(t);
if (tcb->m_state == MS_CONDITION) {
- if (tcb->m_cond != NULL && tcb->m_cond->mutex == *mutex) {
+ if (tcb->m_cond != NULL && tcb->m_cond->mc_mutex == *mutex) {
errno = EBUSY;
return(-1);
}
} else if (mattr != NULL) {
errno = ENOSYS;
return(-1);
- } else if (mthread_mutex_valid(mutex)) {
+ }
+#ifdef MTHREAD_STRICT
+ else if (mthread_mutex_valid(mutex)) {
errno = EBUSY;
return(-1);
}
-
- if ((m = malloc(sizeof(struct __mthread_mutex))) == NULL)
+#endif
+ else if ((m = malloc(sizeof(struct __mthread_mutex))) == NULL) {
+ errno = ENOMEM;
return(-1);
+ }
- mthread_queue_init( &(m->queue) );
- m->owner = NO_THREAD;
+ mthread_queue_init(&m->mm_queue);
+ m->mm_owner = NO_THREAD;
*mutex = (mthread_mutex_t) m;
mthread_mutex_add(mutex); /* Validate mutex; mutex now in use */
/*===========================================================================*
* mthread_mutex_lock *
*===========================================================================*/
-PUBLIC int mthread_mutex_lock_f(mutex, file, line)
+PUBLIC int mthread_mutex_lock(mutex)
mthread_mutex_t *mutex; /* Mutex that is to be locked */
-char file[NAME_MAX + 1];
-int line;
{
/* Try to lock this mutex. If already locked, append the current thread to
* FIFO queue associated with this mutex and suspend the thread. */
if (!mthread_mutex_valid(&m)) {
errno = EINVAL;
return(-1);
- } else if (m->owner == NO_THREAD) { /* Not locked */
- m->owner = current_thread;
+ } else if (m->mm_owner == NO_THREAD) { /* Not locked */
+ m->mm_owner = current_thread;
if (current_thread == MAIN_THREAD)
mthread_debug("MAIN_THREAD now mutex owner\n");
- } else if (m->owner == current_thread) {
+ } else if (m->mm_owner == current_thread) {
errno = EDEADLK;
return(-1);
} else {
- mthread_queue_add( &(m->queue), current_thread);
- if (m->owner == MAIN_THREAD)
- mthread_dump_queue(&(m->queue));
+ mthread_queue_add(&m->mm_queue, current_thread);
+ if (m->mm_owner == MAIN_THREAD)
+ mthread_dump_queue(&m->mm_queue);
mthread_suspend(MS_MUTEX);
}
/*===========================================================================*
* mthread_mutex_remove *
*===========================================================================*/
+#ifdef MTHREAD_STRICT
PRIVATE void mthread_mutex_remove(m)
mthread_mutex_t *m;
{
/* Remove mutex from list of valid, initialized mutexes */
- if ((*m)->prev == NULL)
- vm_front = (*m)->next;
+ if ((*m)->mm_prev == NULL)
+ vm_front = (*m)->mm_next;
else
- (*m)->prev->next = (*m)->next;
+ (*m)->mm_prev->mm_next = (*m)->mm_next;
- if ((*m)->next == NULL)
- vm_rear = (*m)->prev;
+ if ((*m)->mm_next == NULL)
+ vm_rear = (*m)->mm_prev;
else
- (*m)->next->prev = (*m)->prev;
+ (*m)->mm_next->mm_prev = (*m)->mm_prev;
}
-
+#endif
/*===========================================================================*
* mthread_mutex_trylock *
if (!mthread_mutex_valid(&m)) {
errno = EINVAL;
return(-1);
- } else if (m->owner == NO_THREAD) {
- m->owner = current_thread;
+ } else if (m->mm_owner == NO_THREAD) {
+ m->mm_owner = current_thread;
return(0);
}
if (!mthread_mutex_valid(&m)) {
errno = EINVAL;
return(-1);
- } else if (m->owner != current_thread) {
+ } else if (m->mm_owner != current_thread) {
errno = EPERM;
return(-1); /* Can't unlock a mutex locked by another thread. */
}
- m->owner = mthread_queue_remove( &(m->queue) );
- if (m->owner != NO_THREAD) mthread_unsuspend(m->owner);
+ m->mm_owner = mthread_queue_remove(&m->mm_queue);
+ if (m->mm_owner != NO_THREAD) mthread_unsuspend(m->mm_owner);
return(0);
}
/*===========================================================================*
* mthread_mutex_valid *
*===========================================================================*/
+#ifdef MTHREAD_STRICT
PUBLIC int mthread_mutex_valid(m)
mthread_mutex_t *m;
{
if (loopitem == *m)
return(1);
- loopitem = loopitem->next;
+ loopitem = loopitem->mm_next;
}
return(0);
}
-
+#endif
/*===========================================================================*
* mthread_mutex_verify *
loopitem = vm_front;
while (loopitem != NULL) {
- printf("mutex corruption: owner: %d\n", loopitem->owner);
+ printf("mutex corruption: owner: %d\n", loopitem->mm_owner);
loopitem = loopitem->next;
r = 0;
}
/* mutex.c */
_PROTOTYPE( void mthread_init_valid_mutexes, (void) );
+
+#ifdef MTHREAD_STRICT
_PROTOTYPE( int mthread_mutex_valid, (mthread_mutex_t *mutex) );
+#else
+# define mthread_mutex_valid(x) ((*x)->mm_magic == MTHREAD_INIT_MAGIC)
+#endif
+
#ifdef MDEBUG
_PROTOTYPE( int mthread_mutex_verify, (void) );
#endif
last = mthread_find_tcb(thread);
if (mthread_queue_isempty(queue)) {
- queue->head = queue->tail = last;
+ queue->mq_head = queue->mq_tail = last;
} else {
- queue->tail->m_next = last;
- queue->tail = last; /* 'last' is the new last in line */
+ queue->mq_tail->m_next = last;
+ queue->mq_tail = last; /* 'last' is the new last in line */
}
}
{
/* Initialize queue to a known state */
- queue->head = queue->tail = NULL;
+ queue->mq_head = queue->mq_tail = NULL;
}
PUBLIC int mthread_queue_isempty(queue)
mthread_queue_t *queue;
{
- return(queue->head == NULL);
+ return(queue->mq_head == NULL);
}
#ifdef MDEBUG
printf("Dumping queue: ");
#endif
- if(queue->head != NULL) {
- t = queue->head;
+ if(queue->mq_head != NULL) {
+ t = queue->mq_head;
if (t == &mainthread) tid = MAIN_THREAD;
else tid = t->m_tid;
#ifdef MDEBUG
mthread_tcb_t *tcb;
/* Calculate thread id from queue head */
- if (queue->head == NULL) thread = NO_THREAD;
- else if (queue->head == &mainthread) thread = MAIN_THREAD;
- else thread = (queue->head->m_tid);
+ if (queue->mq_head == NULL) thread = NO_THREAD;
+ else if (queue->mq_head == &mainthread) thread = MAIN_THREAD;
+ else thread = (queue->mq_head->m_tid);
if (thread != NO_THREAD) { /* i.e., this queue is not empty */
- tcb = queue->head;
- if (queue->head == queue->tail) {
+ tcb = queue->mq_head;
+ if (queue->mq_head == queue->mq_tail) {
/* Queue holds only one thread */
- queue->head = queue->tail = NULL; /* So mark thread empty */
+ queue->mq_head = queue->mq_tail = NULL; /* So mark thread empty */
} else {
/* Second thread in line is the new first */
- queue->head = queue->head->m_next;
+ queue->mq_head = queue->mq_head->m_next;
}
tcb->m_next = NULL; /* This thread is no longer part of a queue */
/* We're running the last runnable spawned thread. Return to main
* thread as there is no work left.
*/
- running_main_thread = 1;
current_thread = MAIN_THREAD;
} else {
current_thread = mthread_queue_remove(&run_queue);
- running_main_thread = 0; /* Running thread after swap */
}
/* Find thread entries in tcb... */
new_ctx = &(new_tcb->m_context);
old_ctx = &(old_tcb->m_context);
+ /* Are we running the 'main' thread after swap? */
+ running_main_thread = (current_thread == MAIN_THREAD);
+
if (swapcontext(old_ctx, new_ctx) == -1)
mthread_panic("Could not swap context");
if (mthread_queue_isempty(&run_queue)) { /* No point in yielding. */
return(-1);
} else if (current_thread == NO_THREAD) {
- /* Can't yield this thread, but still give other threads a chance to
- * run.
- */
- mthread_schedule();
+ /* Can't yield this thread */
return(-1);
}
/* Trying to acquire lock again should fail with EDEADLK */
if (mthread_mutex_lock(&mu[0]) != -1) err(3, 2);
if (errno != EDEADLK) err(3, 3);
-
+
+#ifdef MTHREAD_STRICT
/* Try to acquire lock on uninitialized mutex; should fail with EINVAL */
+ /* Note: this check only works when libmthread is compiled with
+ * MTHREAD_STRICT turned on. In POSIX this situation is a MAY fail if... */
if (mthread_mutex_lock(&mu2) != -1) {
err(3, 4);
mthread_mutex_unlock(&mu2);
}
+
if (errno != EINVAL) err(3, 5);
errno = 0;
if (mthread_mutex_trylock(&mu2) != -1) {
mthread_mutex_unlock(&mu2);
}
if (errno != EINVAL) err(3, 7);
+#endif
if (mthread_mutex_trylock(&mu[1]) != 0) err(3, 8);
mutex_a_step = 1;
if (mthread_mutex_destroy(condition_mutex) != 0) err(8, 8);
if (mthread_cond_destroy(&condition) != 0) err(8, 9);
+#ifdef MTHREAD_STRICT
/* Let's try to destroy it again. Should fails as it's uninitialized. */
+ /* Note: this only works when libmthread is compiled with MTHREAD_STRICT. In
+ * POSIX this situation is a MAY fail if... */
if (mthread_cond_destroy(&condition) == 0) err(8, 10);
+#endif
#ifdef MDEBUG
mthread_verify();
if (mthread_mutex_destroy(condition_mutex) != 0) err(8, 21);
if (mthread_cond_destroy(&condition) != 0) err(8, 22);
+#ifdef MTHREAD_STRICT
/* Again, destroying the condition variable twice shouldn't work */
+ /* See previous note about MTHREAD_STRICT */
if (mthread_cond_destroy(&condition) == 0) err(8, 23);
+#endif
#ifdef MDEBUG
mthread_verify();