diff --git a/common/include/minix/mthread.h b/common/include/minix/mthread.h index 8098db037..a2c525016 100644 --- a/common/include/minix/mthread.h +++ b/common/include/minix/mthread.h @@ -24,31 +24,33 @@ typedef void * mthread_mutexattr_t; 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; @@ -106,12 +108,7 @@ _PROTOTYPE( void mthread_verify_f, (char *f, int l) ); _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) ); diff --git a/lib/libmthread/allocate.c b/lib/libmthread/allocate.c index 0e173ed79..853a86e99 100644 --- a/lib/libmthread/allocate.c +++ b/lib/libmthread/allocate.c @@ -100,11 +100,11 @@ mthread_thread_t detach; 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); @@ -138,7 +138,7 @@ void *value; 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 */ @@ -283,7 +283,7 @@ PUBLIC void mthread_init(void) * 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; @@ -293,7 +293,7 @@ PUBLIC void mthread_init(void) 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; @@ -331,7 +331,7 @@ void **value; 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); } @@ -445,11 +445,11 @@ void *arg; 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; @@ -488,9 +488,10 @@ mthread_thread_t thread; 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; } diff --git a/lib/libmthread/attribute.c b/lib/libmthread/attribute.c index dda0aaf3d..123260617 100644 --- a/lib/libmthread/attribute.c +++ b/lib/libmthread/attribute.c @@ -27,13 +27,13 @@ mthread_attr_t *a; 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; } @@ -89,9 +89,9 @@ mthread_attr_t *attr; /* Attribute */ 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 */ @@ -122,7 +122,7 @@ int *detachstate; return(-1); } - *detachstate = a->a_detachstate; + *detachstate = a->ma_detachstate; return(0); } @@ -155,7 +155,7 @@ int detachstate; return(-1); } - a->a_detachstate = detachstate; + a->ma_detachstate = detachstate; return(0); } @@ -185,8 +185,8 @@ size_t *stacksize; return(-1); } - *stackaddr = a->a_stackaddr; - *stacksize = a->a_stacksize; + *stackaddr = a->ma_stackaddr; + *stacksize = a->ma_stacksize; return(0); } @@ -215,7 +215,7 @@ size_t *stacksize; return(-1); } - *stacksize = a->a_stacksize; + *stacksize = a->ma_stacksize; return(0); } @@ -249,8 +249,8 @@ size_t stacksize; * 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); } @@ -279,7 +279,7 @@ size_t stacksize; return(-1); } - a->a_stacksize = stacksize; + a->ma_stacksize = stacksize; return(0); } @@ -293,15 +293,15 @@ mthread_attr_t *a; { /* 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; } @@ -322,7 +322,7 @@ mthread_attr_t *a; if (loopitem == *a) return(1); - loopitem = loopitem->next; + loopitem = loopitem->ma_next; } return(0); @@ -343,7 +343,7 @@ PUBLIC int mthread_attr_verify(void) loopitem = va_front; while (loopitem != NULL) { - loopitem = loopitem->next; + loopitem = loopitem->ma_next; return(0); } diff --git a/lib/libmthread/condition.c b/lib/libmthread/condition.c index bb8a6e341..a542a56d3 100644 --- a/lib/libmthread/condition.c +++ b/lib/libmthread/condition.c @@ -3,9 +3,15 @@ #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 /*===========================================================================* @@ -21,6 +27,7 @@ PUBLIC void mthread_init_valid_conditions(void) /*===========================================================================* * mthread_cond_add * *===========================================================================*/ +#ifdef MTHREAD_STRICT PRIVATE void mthread_cond_add(c) mthread_cond_t *c; { @@ -28,16 +35,16 @@ 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 * @@ -51,12 +58,10 @@ mthread_cond_t *cond; 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); } @@ -90,9 +95,7 @@ mthread_cond_t *cond; if (cond == NULL) { errno = EINVAL; return(-1); - } - - if (!mthread_cond_valid(cond)) { + } else if (!mthread_cond_valid(cond)) { errno = EINVAL; return(-1); } @@ -106,7 +109,7 @@ mthread_cond_t *cond; 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); } @@ -140,17 +143,19 @@ mthread_condattr_t *cattr; 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); @@ -161,23 +166,24 @@ mthread_condattr_t *cattr; /*===========================================================================* * 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 * @@ -191,12 +197,10 @@ mthread_cond_t *cond; 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); } @@ -207,7 +211,7 @@ mthread_cond_t *cond; 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; } @@ -220,24 +224,27 @@ mthread_cond_t *cond; /*===========================================================================* * 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 * @@ -281,7 +288,7 @@ mthread_mutex_t *mutex; 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); @@ -290,7 +297,7 @@ mthread_mutex_t *mutex; 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); diff --git a/lib/libmthread/global.h b/lib/libmthread/global.h index 195622f50..45773e197 100644 --- a/lib/libmthread/global.h +++ b/lib/libmthread/global.h @@ -12,6 +12,8 @@ #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 diff --git a/lib/libmthread/mutex.c b/lib/libmthread/mutex.c index 06d1afab6..0d427ed5d 100644 --- a/lib/libmthread/mutex.c +++ b/lib/libmthread/mutex.c @@ -3,8 +3,13 @@ #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 * @@ -19,6 +24,7 @@ PUBLIC void mthread_init_valid_mutexes(void) /*===========================================================================* * mthread_mutex_add * *===========================================================================*/ +#ifdef MTHREAD_STRICT PRIVATE void mthread_mutex_add(m) mthread_mutex_t *m; { @@ -26,16 +32,16 @@ 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 * @@ -58,8 +64,7 @@ mthread_mutex_t *mutex; 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); } @@ -68,7 +73,7 @@ mthread_mutex_t *mutex; 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); } @@ -103,16 +108,20 @@ mthread_mutexattr_t *mattr; /* Mutex attribute */ } 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 */ @@ -122,10 +131,8 @@ mthread_mutexattr_t *mattr; /* Mutex attribute */ /*===========================================================================* * 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. */ @@ -143,17 +150,17 @@ int line; 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); } @@ -165,22 +172,23 @@ int line; /*===========================================================================* * 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 * @@ -203,8 +211,8 @@ mthread_mutex_t *mutex; /* Mutex that is to be locked */ 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); } @@ -235,13 +243,13 @@ mthread_mutex_t *mutex; /* Mutex that is to be unlocked */ 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); } @@ -249,6 +257,7 @@ mthread_mutex_t *mutex; /* Mutex that is to be unlocked */ /*===========================================================================* * mthread_mutex_valid * *===========================================================================*/ +#ifdef MTHREAD_STRICT PUBLIC int mthread_mutex_valid(m) mthread_mutex_t *m; { @@ -263,12 +272,12 @@ mthread_mutex_t *m; if (loopitem == *m) return(1); - loopitem = loopitem->next; + loopitem = loopitem->mm_next; } return(0); } - +#endif /*===========================================================================* * mthread_mutex_verify * @@ -285,7 +294,7 @@ PUBLIC int mthread_mutex_verify(void) 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; } diff --git a/lib/libmthread/proto.h b/lib/libmthread/proto.h index 7ef4aa27b..42623da89 100644 --- a/lib/libmthread/proto.h +++ b/lib/libmthread/proto.h @@ -26,7 +26,13 @@ _PROTOTYPE( void mthread_debug_f, (const char *file, int line, /* 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 diff --git a/lib/libmthread/queue.c b/lib/libmthread/queue.c index 032e19f73..1ae68d5d0 100644 --- a/lib/libmthread/queue.c +++ b/lib/libmthread/queue.c @@ -21,10 +21,10 @@ mthread_thread_t thread; 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 */ } } @@ -37,7 +37,7 @@ mthread_queue_t *queue; /* Queue that has to be initialized */ { /* Initialize queue to a known state */ - queue->head = queue->tail = NULL; + queue->mq_head = queue->mq_tail = NULL; } @@ -47,7 +47,7 @@ mthread_queue_t *queue; /* Queue that has to be initialized */ PUBLIC int mthread_queue_isempty(queue) mthread_queue_t *queue; { - return(queue->head == NULL); + return(queue->mq_head == NULL); } @@ -64,8 +64,8 @@ mthread_queue_t *queue; #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 @@ -106,18 +106,18 @@ mthread_queue_t *queue; /* Queue we want a thread from */ 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 */ diff --git a/lib/libmthread/scheduler.c b/lib/libmthread/scheduler.c index 96e91beea..9186c5dba 100644 --- a/lib/libmthread/scheduler.c +++ b/lib/libmthread/scheduler.c @@ -55,11 +55,9 @@ PUBLIC void mthread_schedule(void) /* 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... */ @@ -70,6 +68,9 @@ PUBLIC void mthread_schedule(void) 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"); @@ -156,10 +157,7 @@ PUBLIC int mthread_yield(void) 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); } diff --git a/test/test59.c b/test/test59.c index 1b01638e3..d3583099c 100644 --- a/test/test59.c +++ b/test/test59.c @@ -222,12 +222,16 @@ PRIVATE void mutex_a(void *arg) /* 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) { @@ -235,6 +239,7 @@ PRIVATE void mutex_a(void *arg) 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; @@ -502,8 +507,12 @@ PRIVATE void test_condition(void) 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(); @@ -538,8 +547,11 @@ PRIVATE void test_condition(void) 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();