diff --git a/common/include/minix/mthread.h b/common/include/minix/mthread.h index 19012dfbe..dfefbda88 100644 --- a/common/include/minix/mthread.h +++ b/common/include/minix/mthread.h @@ -9,9 +9,6 @@ #include #include #include -#ifndef __NBSD_LIBC -#include -#endif #include #ifdef __NBSD_LIBC #include @@ -32,16 +29,20 @@ typedef struct { struct __mthread_mutex { mthread_queue_t mm_queue; /* Queue of threads blocked on this mutex */ mthread_thread_t mm_owner; /* Thread ID that currently owns mutex */ +#ifdef MTHREAD_STRICT struct __mthread_mutex *mm_prev; struct __mthread_mutex *mm_next; +#endif unsigned int mm_magic; }; typedef struct __mthread_mutex *mthread_mutex_t; struct __mthread_cond { struct __mthread_mutex *mc_mutex; /* Associate mutex with condition */ +#ifdef MTHREAD_STRICT struct __mthread_cond *mc_prev; struct __mthread_cond *mc_next; +#endif unsigned int mc_magic; }; typedef struct __mthread_cond *mthread_cond_t; @@ -64,7 +65,7 @@ typedef struct __mthread_attr *mthread_attr_t; /* allocate.c */ _PROTOTYPE( int mthread_create, (mthread_thread_t *thread, mthread_attr_t *tattr, - void (*proc)(void *), void *arg) ); + void *(*proc)(void *), void *arg) ); _PROTOTYPE( int mthread_detach, (mthread_thread_t thread) ); _PROTOTYPE( int mthread_equal, (mthread_thread_t l, mthread_thread_t r) ); _PROTOTYPE( void mthread_exit, (void *value) ); diff --git a/lib/libmthread/allocate.c b/lib/libmthread/allocate.c index 854ef96b6..c16fe40e3 100644 --- a/lib/libmthread/allocate.c +++ b/lib/libmthread/allocate.c @@ -5,13 +5,10 @@ #include "global.h" #include "proto.h" -#define FALLBACK_CTX (&(fallback.m_context)) - -FORWARD _PROTOTYPE( void mthread_fallback, (void) ); FORWARD _PROTOTYPE( int mthread_increase_thread_pool, (void) ); FORWARD _PROTOTYPE( void mthread_thread_init, (mthread_thread_t thread, mthread_attr_t *tattr, - void (*proc)(void *), + void *(*proc)(void *), void *arg) ); FORWARD _PROTOTYPE( void mthread_thread_reset, (mthread_thread_t thread)); @@ -45,7 +42,7 @@ mthread_thread_t r; PUBLIC int mthread_create(threadid, tattr, proc, arg) mthread_thread_t *threadid; mthread_attr_t *tattr; -void (*proc)(void *); +void *(*proc)(void *); void *arg; { /* Register procedure proc for execution in a thread. */ @@ -111,7 +108,6 @@ PUBLIC void mthread_exit(value) void *value; { /* Make a thread stop running and store the result value. */ - int fallback_exit = 0; mthread_tcb_t *tcb; mthread_init(); /* Make sure libmthread is initialized */ @@ -123,13 +119,6 @@ void *value; mthread_cleanup_values(); - /* When we're called from the fallback thread, the fallback thread - * will invoke the scheduler. However, if the thread itself called - * mthread_exit, _we_ will have to wake up the scheduler. - */ - if (tcb->m_state == MS_FALLBACK_EXITING) - fallback_exit = 1; - tcb->m_result = value; tcb->m_state = MS_EXITING; @@ -145,42 +134,9 @@ void *value; */ } - /* The fallback thread does a mthread_schedule. If we're not running from - * that thread, we have to do it ourselves. - */ - if (!fallback_exit) - mthread_schedule(); - -} - - -/*===========================================================================* - * mthread_fallback * - *===========================================================================*/ -PRIVATE void mthread_fallback(void) -{ -/* The libmthread fallback thread. The idea is that every thread calls - * mthread_exit(...) to stop running when it has nothing to do anymore. - * However, in case a thread forgets to do that, the whole process exit()s and - * that might be a bit problematic. Therefore, all threads will run this - * fallback thread when they exit, giving the scheduler a chance to fix the - * situation. - */ - mthread_tcb_t *tcb; - - tcb = mthread_find_tcb(current_thread); - - tcb->m_state = MS_FALLBACK_EXITING; - mthread_exit(NULL); - - /* Reconstruct fallback context for next invocation */ - makecontext(FALLBACK_CTX, (void (*) (void)) mthread_fallback, 0); - - /* Let another thread run */ mthread_schedule(); } - /*===========================================================================* * mthread_find_tcb * *===========================================================================*/ @@ -288,15 +244,6 @@ PUBLIC void mthread_init(void) mthread_init_keys(); mthread_init_scheduler(); - /* Initialize the fallback thread */ - 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; - FALLBACK_CTX->uc_stack.ss_size = STACKSZ; - memset(fallback_stack, '\0', STACKSZ); - makecontext(FALLBACK_CTX, (void (*) (void)) mthread_fallback, 0); - initialized = 1; } } @@ -399,7 +346,7 @@ PUBLIC mthread_thread_t mthread_self(void) PRIVATE void mthread_thread_init(thread, tattr, proc, arg) mthread_thread_t thread; mthread_attr_t *tattr; -void (*proc)(void *); +void *(*proc)(void *); void *arg; { /* Initialize a thread so that it, when unsuspended, will run the given @@ -414,7 +361,7 @@ void *arg; tcb = mthread_find_tcb(thread); tcb->m_next = NULL; tcb->m_state = MS_DEAD; - tcb->m_proc = (void *(*)(void *)) proc; /* Yikes */ + tcb->m_proc = proc; tcb->m_arg = arg; /* Threads use a copy of the provided attributes. This way, if another * thread modifies the attributes (such as detach state), already running @@ -429,10 +376,9 @@ void *arg; if (mthread_cond_init(&(tcb->m_exited), NULL) != 0) mthread_panic("Could not initialize thread"); - /* First set the fallback thread, */ - tcb->m_context.uc_link = FALLBACK_CTX; + tcb->m_context.uc_link = NULL; - /* then construct this thread's context to run procedure proc. */ + /* Construct this thread's context to run procedure proc. */ if (mthread_getcontext(&(tcb->m_context)) == -1) mthread_panic("Failed to initialize context state"); diff --git a/lib/libmthread/condition.c b/lib/libmthread/condition.c index 3a2b48d04..c65f0fdf5 100644 --- a/lib/libmthread/condition.c +++ b/lib/libmthread/condition.c @@ -2,8 +2,8 @@ #include "global.h" #include "proto.h" -PRIVATE struct __mthread_cond *vc_front, *vc_rear; #ifdef MTHREAD_STRICT +PRIVATE struct __mthread_cond *vc_front, *vc_rear; 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) ); @@ -19,8 +19,10 @@ FORWARD _PROTOTYPE( int mthread_cond_valid, (mthread_cond_t *c) ); *===========================================================================*/ PUBLIC void mthread_init_valid_conditions(void) { +#ifdef MTHREAD_STRICT /* Initialize condition variable list */ vc_front = vc_rear = NULL; +#endif } diff --git a/lib/libmthread/global.h b/lib/libmthread/global.h index 30e480e28..acd80cac2 100644 --- a/lib/libmthread/global.h +++ b/lib/libmthread/global.h @@ -16,7 +16,7 @@ #define MTHREAD_NOT_INUSE 0xdefec7 typedef enum { - MS_CONDITION, MS_DEAD, MS_EXITING, MS_FALLBACK_EXITING, MS_MUTEX, MS_RUNNABLE + MS_CONDITION, MS_DEAD, MS_EXITING, MS_MUTEX, MS_RUNNABLE } mthread_state_t; struct __mthread_tcb { @@ -40,10 +40,8 @@ EXTERN mthread_thread_t current_thread; EXTERN mthread_queue_t free_threads; EXTERN mthread_queue_t run_queue; /* FIFO of runnable threads */ EXTERN mthread_tcb_t **threads; -EXTERN mthread_tcb_t fallback; EXTERN mthread_tcb_t mainthread; EXTERN int no_threads; EXTERN int used_threads; EXTERN int running_main_thread; -EXTERN char fallback_stack[STACKSZ]; diff --git a/lib/libmthread/key.c b/lib/libmthread/key.c index 5ad11494d..01c6b84b0 100644 --- a/lib/libmthread/key.c +++ b/lib/libmthread/key.c @@ -3,6 +3,7 @@ #include "global.h" #include "proto.h" +PRIVATE int keys_used = 0; PRIVATE struct { int used; int nvalues; @@ -34,6 +35,7 @@ PUBLIC int mthread_key_create(mthread_key_t *key, void (*destructor)(void *)) mthread_key_t k; mthread_init(); /* Make sure libmthread is initialized */ + keys_used = 1; /* We do not yet allocate storage space for the values here, because we can * not estimate how many threads will be created in the common case that the @@ -150,6 +152,8 @@ PUBLIC void mthread_cleanup_values(void) void *value; int found; + if (!keys_used) return; /* Only clean up if we used any keys at all */ + /* Any of the destructors may set a new value on any key, so we may have to * loop over the table of keys multiple times. This implementation has no * protection against infinite loops in this case. diff --git a/lib/libmthread/misc.c b/lib/libmthread/misc.c index 57e94bb39..e90ac40b3 100644 --- a/lib/libmthread/misc.c +++ b/lib/libmthread/misc.c @@ -6,18 +6,18 @@ /*===========================================================================* * mthread_debug_f * *===========================================================================*/ +#ifdef MDEBUG PUBLIC void mthread_debug_f(const char *file, int line, const char *msg) { /* Print debug message */ -#ifdef MDEBUG printf("MTH (%s:%d): %s\n", file, line, msg); -#endif } - +#endif /*===========================================================================* * mthread_panic_f * *===========================================================================*/ +#ifdef MDEBUG PUBLIC void mthread_panic_f(const char *file, int line, const char *msg) { /* Print panic message to stdout and exit */ @@ -32,6 +32,17 @@ PUBLIC void mthread_panic_f(const char *file, int line, const char *msg) *((int *) sf ) = 1; /* Cause segfault to generate trace */ exit(1); } +#else +PUBLIC void mthread_panic_s(void) +{ + /* Silent panic */ + volatile int *sf; + + sf = NULL; + *((int *) sf ) = 1; /* Cause segfault to generate trace */ + exit(1); +} +#endif /*===========================================================================* @@ -68,9 +79,6 @@ PUBLIC void mthread_verify_f(char *file, int line) if(!threads_ok || !conditions_ok || !mutexes_ok) mthread_panic("Library state corrupt\n"); } -#else -PUBLIC void mthread_verify_f(char *f, int l) { ; } -#endif /*===========================================================================* @@ -80,8 +88,8 @@ PUBLIC void mthread_stats(void) { mthread_thread_t t; mthread_tcb_t *tcb; - int st_run, st_dead, st_cond, st_mutex, st_exit, st_fbexit; - st_run = st_dead = st_cond = st_mutex = st_exit = st_fbexit = 0; + int st_run, st_dead, st_cond, st_mutex, st_exit; + st_run = st_dead = st_cond = st_mutex = st_exit = 0; for (t = (mthread_thread_t) 0; t < no_threads; t++) { tcb = mthread_find_tcb(t); @@ -91,13 +99,13 @@ PUBLIC void mthread_stats(void) case MS_MUTEX: st_mutex++; break; case MS_CONDITION: st_cond++; break; case MS_EXITING: st_exit++; break; - case MS_FALLBACK_EXITING: st_fbexit++; break; default: mthread_panic("Unknown state"); } } - printf("Pool: %-5d In use: %-5d R: %-5d D: %-5d M: %-5d C: %-5d E: %-5d" - "F: %-5d\n", + printf("Pool: %-5d In use: %-5d R: %-5d D: %-5d M: %-5d C: %-5d E: %-5d\n", no_threads, used_threads, st_run, st_dead, st_mutex, st_cond, - st_exit, st_fbexit); + st_exit); } + +#endif diff --git a/lib/libmthread/mutex.c b/lib/libmthread/mutex.c index 0515556b9..80dec87de 100644 --- a/lib/libmthread/mutex.c +++ b/lib/libmthread/mutex.c @@ -2,8 +2,8 @@ #include "global.h" #include "proto.h" -PRIVATE struct __mthread_mutex *vm_front, *vm_rear; #ifdef MTHREAD_STRICT +PRIVATE struct __mthread_mutex *vm_front, *vm_rear; FORWARD _PROTOTYPE( void mthread_mutex_add, (mthread_mutex_t *m) ); FORWARD _PROTOTYPE( void mthread_mutex_remove, (mthread_mutex_t *m) ); #else @@ -16,8 +16,10 @@ FORWARD _PROTOTYPE( void mthread_mutex_remove, (mthread_mutex_t *m) ); *===========================================================================*/ PUBLIC void mthread_init_valid_mutexes(void) { +#ifdef MTHREAD_STRICT /* Initialize list of valid mutexes */ vm_front = vm_rear = NULL; +#endif } @@ -135,14 +137,10 @@ mthread_mutex_t *mutex; /* Mutex that is to be locked */ return(EINVAL); 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->mm_owner == current_thread) { return(EDEADLK); } else { mthread_queue_add(&m->mm_queue, current_thread); - if (m->mm_owner == MAIN_THREAD) - mthread_dump_queue(&m->mm_queue); mthread_suspend(MS_MUTEX); } @@ -244,10 +242,10 @@ mthread_mutex_t *m; loopitem = vm_front; while (loopitem != NULL) { - if (loopitem == *m) - return(1); + if (loopitem == *m) + return(1); - loopitem = loopitem->mm_next; + loopitem = loopitem->mm_next; } return(0); @@ -266,13 +264,15 @@ PUBLIC int mthread_mutex_verify(void) mthread_init(); /* Make sure mthreads is initialized */ +#ifdef MTHREAD_STRICT loopitem = vm_front; while (loopitem != NULL) { printf("mutex corruption: owner: %d\n", loopitem->mm_owner); - loopitem = loopitem->next; + loopitem = loopitem->mm_next; r = 0; } +#endif return(r); } diff --git a/lib/libmthread/proto.h b/lib/libmthread/proto.h index 2212c2fa5..19619ea50 100644 --- a/lib/libmthread/proto.h +++ b/lib/libmthread/proto.h @@ -21,12 +21,18 @@ _PROTOTYPE( void mthread_init_keys, (void) ); _PROTOTYPE( void mthread_cleanup_values, (void) ); /* misc.c */ +#ifdef MDEBUG #define mthread_panic(m) mthread_panic_f(__FILE__, __LINE__, (m)) _PROTOTYPE( void mthread_panic_f, (const char *file, int line, const char *msg) ); #define mthread_debug(m) mthread_debug_f(__FILE__, __LINE__, (m)) _PROTOTYPE( void mthread_debug_f, (const char *file, int line, const char *msg) ); +#else +_PROTOTYPE( void mthread_panic_s, (void) ); +# define mthread_panic(m) mthread_panic_s() +# define mthread_debug(m) +#endif /* mutex.c */ _PROTOTYPE( void mthread_init_valid_mutexes, (void) ); @@ -49,7 +55,9 @@ _PROTOTYPE( void mthread_suspend, (mthread_state_t state) ); _PROTOTYPE( void mthread_unsuspend, (mthread_thread_t thread) ); /* queue.c */ +#ifdef MDEBUG _PROTOTYPE( void mthread_dump_queue, (mthread_queue_t *queue) ); +#endif _PROTOTYPE( void mthread_queue_init, (mthread_queue_t *queue) ); _PROTOTYPE( void mthread_queue_add, (mthread_queue_t *queue, mthread_thread_t thread) ); diff --git a/lib/libmthread/queue.c b/lib/libmthread/queue.c index 1ae68d5d0..266c69677 100644 --- a/lib/libmthread/queue.c +++ b/lib/libmthread/queue.c @@ -54,6 +54,7 @@ mthread_queue_t *queue; /*===========================================================================* * mthread_dump_queue * *===========================================================================*/ +#ifdef MDEBUG PUBLIC void mthread_dump_queue(queue) mthread_queue_t *queue; { @@ -61,39 +62,30 @@ mthread_queue_t *queue; mthread_tcb_t *t; mthread_thread_t tid; threshold = no_threads; -#ifdef MDEBUG printf("Dumping queue: "); -#endif + if(queue->mq_head != NULL) { t = queue->mq_head; if (t == &mainthread) tid = MAIN_THREAD; else tid = t->m_tid; -#ifdef MDEBUG printf("%d ", tid); -#endif count++; t = t->m_next; while (t != NULL) { if (t == &mainthread) tid = MAIN_THREAD; else tid = t->m_tid; -#ifdef MDEBUG printf("%d ", tid); -#endif t = t->m_next; count++; if (count > threshold) break; } } else { -#ifdef MDEBUG printf("[empty]"); -#endif } -#ifdef MDEBUG printf("\n"); -#endif } - +#endif /*===========================================================================* * mthread_queue_remove * diff --git a/test/test59.c b/test/test59.c index 844e8d4b4..57b3c771f 100644 --- a/test/test59.c +++ b/test/test59.c @@ -3,6 +3,7 @@ * lets you check the internal integrity of the library. */ #include #include +#include #define thread_t mthread_thread_t #define mutex_t mthread_mutex_t @@ -38,16 +39,18 @@ PRIVATE int first; #define THRESH1 3 #define THRESH2 8 #define MEG 1024*1024 -#define MAGIC 0xb4a3f1c2 +#define MAGIC ((signed) 0xb4a3f1c2) -FORWARD _PROTOTYPE( void thread_a, (void *arg) ); -FORWARD _PROTOTYPE( void thread_b, (void *arg) ); -FORWARD _PROTOTYPE( void thread_c, (void *arg) ); -FORWARD _PROTOTYPE( void thread_d, (void *arg) ); +FORWARD _PROTOTYPE( void destr_a, (void *arg) ); +FORWARD _PROTOTYPE( void destr_b, (void *arg) ); +FORWARD _PROTOTYPE( void *thread_a, (void *arg) ); +FORWARD _PROTOTYPE( void *thread_b, (void *arg) ); +FORWARD _PROTOTYPE( void *thread_c, (void *arg) ); +FORWARD _PROTOTYPE( void *thread_d, (void *arg) ); FORWARD _PROTOTYPE( void thread_e, (void) ); -FORWARD _PROTOTYPE( void thread_f, (void *arg) ); -FORWARD _PROTOTYPE( void thread_g, (void *arg) ); -FORWARD _PROTOTYPE( void thread_h, (void *arg) ); +FORWARD _PROTOTYPE( void *thread_f, (void *arg) ); +FORWARD _PROTOTYPE( void *thread_g, (void *arg) ); +FORWARD _PROTOTYPE( void *thread_h, (void *arg) ); FORWARD _PROTOTYPE( void test_scheduling, (void) ); FORWARD _PROTOTYPE( void test_mutex, (void) ); FORWARD _PROTOTYPE( void test_condition, (void) ); @@ -58,34 +61,38 @@ FORWARD _PROTOTYPE( void err, (int subtest, int error) ); /*===========================================================================* * thread_a * *===========================================================================*/ -PRIVATE void thread_a(void *arg) { +PRIVATE void *thread_a(void *arg) { th_a++; + return(NULL); } /*===========================================================================* * thread_b * *===========================================================================*/ -PRIVATE void thread_b(void *arg) { +PRIVATE void *thread_b(void *arg) { th_b++; if (mthread_once(&once, thread_e) != 0) err(10, 1); + return(NULL); } /*===========================================================================* * thread_c * *===========================================================================*/ -PRIVATE void thread_c(void *arg) { +PRIVATE void *thread_c(void *arg) { th_c++; + return(NULL); } /*===========================================================================* * thread_d * *===========================================================================*/ -PRIVATE void thread_d(void *arg) { +PRIVATE void *thread_d(void *arg) { th_d++; mthread_exit(NULL); /* Thread wants to stop running */ + return(NULL); } @@ -100,31 +107,33 @@ PRIVATE void thread_e(void) { /*===========================================================================* * thread_f * *===========================================================================*/ -PRIVATE void thread_f(void *arg) { +PRIVATE void *thread_f(void *arg) { if (mthread_mutex_lock(condition_mutex) != 0) err(12, 1); th_f++; if (mthread_cond_signal(&condition) != 0) err(12, 2); if (mthread_mutex_unlock(condition_mutex) != 0) err(12, 3); + return(NULL); } /*===========================================================================* * thread_g * *===========================================================================*/ -PRIVATE void thread_g(void *arg) { +PRIVATE void *thread_g(void *arg) { char bigarray[MTHREAD_STACK_MIN + 1]; if (mthread_mutex_lock(condition_mutex) != 0) err(13, 1); memset(bigarray, '\0', MTHREAD_STACK_MIN + 1); /* Actually allocate it */ th_g++; if (mthread_cond_signal(&condition) != 0) err(13, 2); if (mthread_mutex_unlock(condition_mutex) != 0) err(13, 3); + return(NULL); } /*===========================================================================* * thread_h * *===========================================================================*/ -PRIVATE void thread_h(void *arg) { +PRIVATE void *thread_h(void *arg) { char bigarray[2 * MEG]; int reply; if (mthread_mutex_lock(condition_mutex) != 0) err(14, 1); @@ -134,6 +143,7 @@ PRIVATE void thread_h(void *arg) { if (mthread_mutex_unlock(condition_mutex) != 0) err(14, 3); reply = *((int *) arg); mthread_exit((void *) reply); + return(NULL); } @@ -154,7 +164,7 @@ PRIVATE void err(int sub, int error) { *===========================================================================*/ PRIVATE void test_scheduling(void) { - int i; + unsigned int i; thread_t t[7]; #ifdef MDEBUG @@ -217,10 +227,9 @@ PRIVATE void test_scheduling(void) /*===========================================================================* * mutex_a * *===========================================================================*/ -PRIVATE void mutex_a(void *arg) +PRIVATE void *mutex_a(void *arg) { mutex_t *mu = (mutex_t *) arg; - mutex_t mu2; VERIFY_MUTEX(0, 0, 0, 3, 1); if (mthread_mutex_lock(&mu[0]) != 0) err(3, 2); @@ -267,13 +276,14 @@ PRIVATE void mutex_a(void *arg) if (mthread_mutex_unlock(NULL) == 0) err(3, 19); if (mthread_mutex_unlock(&mu[2]) != 0) err(3, 20); + return(NULL); } /*===========================================================================* * mutex_b * *===========================================================================*/ -PRIVATE void mutex_b(void *arg) +PRIVATE void *mutex_b(void *arg) { mutex_t *mu = (mutex_t *) arg; @@ -302,13 +312,14 @@ PRIVATE void mutex_b(void *arg) if (mthread_mutex_unlock(&mu[1]) != 0) err(4, 8); mutex_b_step = 4; + return(NULL); } /*===========================================================================* * mutex_c * *===========================================================================*/ -PRIVATE void mutex_c(void *arg) +PRIVATE void *mutex_c(void *arg) { mutex_t *mu = (mutex_t *) arg; @@ -329,6 +340,7 @@ PRIVATE void mutex_c(void *arg) if (mthread_mutex_unlock(&mu[0]) != 0) err(5, 9); mutex_c_step = 4; + return(NULL); } @@ -337,7 +349,7 @@ PRIVATE void mutex_c(void *arg) *===========================================================================*/ PRIVATE void test_mutex(void) { - int i; + unsigned int i; thread_t t[3]; #ifdef MDEBUG mthread_verify(); @@ -381,7 +393,7 @@ PRIVATE void test_mutex(void) /*===========================================================================* * cond_a * *===========================================================================*/ -PRIVATE void cond_a(void *arg) +PRIVATE void *cond_a(void *arg) { cond_t c; int did_count = 0; @@ -406,6 +418,7 @@ PRIVATE void cond_a(void *arg) /* Try faulty addresses */ if (mthread_mutex_lock(condition_mutex) != 0) err(6, 7); +#ifdef MTHREAD_STRICT /* Condition c is not initialized, so whatever we do with it should fail. */ if (mthread_cond_wait(&c, condition_mutex) == 0) err(6, 8); if (mthread_cond_wait(NULL, condition_mutex) == 0) err(6, 9); @@ -415,19 +428,21 @@ PRIVATE void cond_a(void *arg) /* Try again with an unlocked mutex */ if (mthread_cond_wait(&c, condition_mutex) == 0) err(6, 12); if (mthread_cond_signal(&c) == 0) err(6, 13); +#endif /* And again with an unlocked mutex, but initialized c */ if (mthread_cond_init(&c, NULL) != 0) err(6, 14); if (mthread_cond_wait(&c, condition_mutex) == 0) err(6, 15); if (mthread_cond_signal(&c) != 0) err(6, 16);/*c.f., 6.10 this should work!*/ if (mthread_cond_destroy(&c) != 0) err(6, 17); + return(NULL); } /*===========================================================================* * cond_b * *===========================================================================*/ -PRIVATE void cond_b(void *arg) +PRIVATE void *cond_b(void *arg) { int did_count = 0; while(1) { @@ -448,14 +463,14 @@ PRIVATE void cond_b(void *arg) if (!(did_count >= count - (THRESH2 - THRESH1 + 1))) err(7, 6); + return(NULL); } /*===========================================================================* * cond_broadcast * *===========================================================================*/ -PRIVATE void cond_broadcast(void *arg) +PRIVATE void *cond_broadcast(void *arg) { - int rounds = 0; if (mthread_mutex_lock(condition_mutex) != 0) err(9, 1); while(!condition_met) @@ -466,6 +481,7 @@ PRIVATE void cond_broadcast(void *arg) if (mthread_mutex_lock(count_mutex) != 0) err(9, 4); count++; if (mthread_mutex_unlock(count_mutex) != 0) err(9, 5); + return(NULL); } /*===========================================================================* @@ -474,7 +490,7 @@ PRIVATE void cond_broadcast(void *arg) PRIVATE void test_condition(void) { #define NTHREADS 10 - int i, r; + int i; thread_t t[2], s[NTHREADS]; count_mutex = &mu[0]; condition_mutex = &mu[1]; @@ -498,7 +514,7 @@ PRIVATE void test_condition(void) if (mthread_create(&t[0], NULL, cond_a, NULL) != 0) err(8, 4); if (mthread_create(&t[1], NULL, cond_b, NULL) != 0) err(8, 5); - for (i = 0; i < (sizeof(t) / sizeof(thread_t)); i++) + for (i = 0; i < (sizeof(t) / sizeof(thread_t)); i++) if (mthread_join(t[i], NULL) != 0) err(8, 6); if (mthread_mutex_destroy(count_mutex) != 0) err(8, 7); @@ -564,7 +580,7 @@ PRIVATE void test_attributes(void) attr_t tattr; thread_t tid; int detachstate = -1, status = 0; - int i, no_ints, stack_untouched = 1; + unsigned int i, no_ints, stack_untouched = 1; void *stackaddr, *newstackaddr; int *stackp; size_t stacksize, newstacksize; @@ -720,7 +736,7 @@ PRIVATE void test_attributes(void) #endif if (mthread_join(tid, (void *) &status) != 0) err(11, 69); - if (status != stacksize) err(11, 70); + if ((size_t) status != stacksize) err(11, 70); if (mthread_attr_destroy(&tattr) != 0) err(11, 71); if (mthread_mutex_destroy(condition_mutex) != 0) err(11, 72); if (mthread_cond_destroy(&condition) != 0) err(11, 73); @@ -759,7 +775,7 @@ PRIVATE void destr_b(void *value) /*===========================================================================* * key_a * *===========================================================================*/ -PRIVATE void key_a(void *arg) +PRIVATE void *key_a(void *arg) { int i; @@ -785,12 +801,13 @@ PRIVATE void key_a(void *arg) /* If a key's value is set to NULL, its destructor must not be called. */ if (mthread_setspecific(key[4], NULL) != 0) err(17, 5); + return(NULL); } /*===========================================================================* * key_b * *===========================================================================*/ -PRIVATE void key_b(void *arg) +PRIVATE void *key_b(void *arg) { int i; @@ -810,12 +827,13 @@ PRIVATE void key_b(void *arg) if (mthread_key_delete(key[3]) != 0) err(18, 3); mthread_exit(NULL); + return(NULL); } /*===========================================================================* * key_c * *===========================================================================*/ -PRIVATE void key_c(void *arg) +PRIVATE void *key_c(void *arg) { /* The only thing that this thread should do, is set a value. */ if (mthread_setspecific(key[0], (void *) mthread_self()) != 0) err(19, 1); @@ -824,6 +842,7 @@ PRIVATE void key_c(void *arg) if (!mthread_equal((thread_t) mthread_getspecific(key[0]), mthread_self())) err(19, 2); + return(NULL); } /*===========================================================================* @@ -919,5 +938,6 @@ int main(void) test_attributes(); test_keys(); quit(); + return(0); /* Not reachable */ }