From: Thomas Veerman Date: Fri, 18 Mar 2011 10:29:54 +0000 (+0000) Subject: - Refactor mthread structure fields to prevent name clashes X-Git-Tag: v3.2.0~611 X-Git-Url: http://zhaoyanbai.com/repos/%22../static/icons/man.7.txt?a=commitdiff_plain;h=c8d0edc06a5649b75de5321fd16b51f0e0467be4;p=minix.git - Refactor mthread structure fields to prevent name clashes - Remove sanity checks for initialized mutexes and condition variables. This significantly boosts performance. The checks can be turned back on by compiling libmthread with MTHREAD_STRICT. According to POSIX operations on uninitialized variables are a MAY fail if, therefore allowing this optimization. - Test59 has to be accommodated to the lack of sanity checks on uninitialized variables in the library. It specifically tests for them and will run into segfaults when the checks are absent in the library. - Fix a few bugs related to the scheduler - Do some general code cleanups --- 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();