/* The thread executing this MUST be cancelled before it succesfully * obtains the mutex. Otherwise, bad things will happen */ static void * cancellable_lock_kmutex(int arg1, void *arg2){ kmutex_t *m = (kmutex_t *) arg2; int lock_result = kmutex_lock_cancellable(m); KASSERT(lock_result == -EINTR); KASSERT(m->km_holder == NULL); KASSERT(sched_queue_empty(&m->km_waitq)); return NULL; }
/* This test checks to make sure that when you sleep * threads, and broadcast later, they are popped in the * right order */ void *broadcast_order(int arg1, void *arg2) { int local,local2; if ( kmutex_lock_cancellable(&mutex) ) { dbg_print("Mutex cancelled? %d", curproc->p_pid); do_exit(-1); } local = race2; local++; race2 = local; kmutex_unlock(&mutex); wake_me_len2++; sched_sleep_on(&wake_me_q); wake_me_len2--; if ( kmutex_lock_cancellable(&mutex) ) { dbg_print("Mutex cancelled? %d", curproc->p_pid); do_exit(-1); } local2 = race2; local2++; race2 = local2; kmutex_unlock(&mutex); dbg_print("broadcast_order: Local: %i ", local); dbg_print("Local2: %i\n", local2); KASSERT(local == local2 && "Error on broadcast_order"); do_exit(local); /*dbg_print("mutex_test: Local: %i\n", local);*/ return NULL; }
/* * A Thread function that exhibits a race condition on the race global being * removed by a mutex. It loads increments and stores race, context switching * between each line of C after acquiring mutex. The mutex acquire can * be cancelled, but will print an error message if the mutex acquire succeeds * - it expects to be cancelled. */ void *mutex_test_cancelme(int arg1, void *arg2) { int local; if ( kmutex_lock_cancellable(&mutex) ) do_exit(0); dbg_print("Mutex not cancelled? %d", curproc->p_pid); sched_switch(); local = race; sched_switch(); local++; sched_switch(); race = local; sched_switch(); kmutex_unlock(&mutex); do_exit(race); return NULL; }
/* * A Thread function that exhibits a race condition on the race global being * removed by a mutex. It loads increments and stores race, context switching * between each line of C after acquiring mutex. The mutex acquire can * be cancelled, but will print an error message if this happens. */ void *mutex_test(int arg1, void *arg2) { int local; if ( kmutex_lock_cancellable(&mutex) ) { dbg_print("Mutex cancelled? %d", curproc->p_pid); do_exit(-1); } sched_make_runnable(curthr); sched_switch(); local = race; sched_make_runnable(curthr); sched_switch(); local++; sched_make_runnable(curthr); sched_switch(); race = local; sched_make_runnable(curthr); sched_switch(); kmutex_unlock(&mutex); do_exit(race); return NULL; }