void sched_broadcast_on(ktqueue_t *q) { /*----Kernel1:PROCS:sched_broadcast_on:Begins---*/ KASSERT(q != NULL); while ( sched_wakeup_on(q) ) { /*everything is done in the condition*/ } /*----Ends----*/ }
void sched_broadcast_on(ktqueue_t *q) { kthread_t *thr; while(q->tq_size > 0) { sched_wakeup_on(q); dbg(DBG_PRINT, "(GRADING1C 4)\n"); } dbg(DBG_PRINT, "(GRADING1B)\n"); /*NOT_YET_IMPLEMENTED("PROCS: sched_broadcast_on"); */ }
/* * If there are any threads waiting to take a lock on the mutex, one * should be woken up and given the lock. * * Note: This should _NOT_ be a blocking operation! * * Note: Don't forget to add the new owner of the mutex back to the * run queue. * * Note: Make sure that the thread on the head of the mutex's wait * queue becomes the new owner of the mutex. * * @param mtx the mutex to unlock */ void kmutex_unlock(kmutex_t *mtx) { /*NOT_YET_IMPLEMENTED("PROCS: kmutex_unlock");*/ if(sched_queue_empty(&mtx->km_waitq)) { mtx->km_holder=NULL; } else { mtx->km_holder=sched_wakeup_on(&mtx->km_waitq); /*sched_switch();*/ } }
void sched_broadcast_on(queue_t *q) { while (sched_wakeup_on(q)); }
int fthread_cond_signal(fthread_cond_t *cond) { sched_wakeup_on(&cond->__waitq); return 0; }
/* The core testproc code */ void *testproc(int arg1, void *arg2) { proc_thread_t pt; pid_t pid = -1; int rv = 0; int i = 0; #if CS402TESTS > 0 dbg_print("waitpid any test"); start_proc(&pt, "waitpid any test", waitpid_test, 23); wait_for_any(); dbg_print("waitpid test"); start_proc(&pt, "waitpid test", waitpid_test, 32); pid = do_waitpid(2323, 0, &rv); if ( pid != -ECHILD ) dbg_print("Allowed wait on non-existent pid\n"); wait_for_proc(pt.p); /* dbg_print("kthread exit test"); start_proc(&pt, "kthread exit test", kthread_exit_test, 0); wait_for_proc(pt.p); */ /* dbg_print("many test"); for (i = 0; i < 10; i++) start_proc(NULL, "many test", waitpid_test, i); wait_for_all();a */ #endif #if CS402TESTS > 1 dbg_print("Context switch test"); start_proc(&pt, "Context switch", racer_test, 0); wait_for_proc(pt.p); #endif #if CS402TESTS > 2 sched_queue_init(&wake_me_q); dbg_print("wake me test"); wake_me_len = 0; start_proc(&pt, "wake me test", wakeme_test, 0); /* Make sure p has blocked */ stop_until_queued(1, &wake_me_len); sched_wakeup_on(&wake_me_q); wait_for_proc(pt.p); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); dbg_print("broadcast me test"); for (i = 0; i < 10; i++ ) start_proc(NULL, "broadcast me test", wakeme_test, 0); stop_until_queued(10, &wake_me_len); /* Make sure the processes have blocked */ sched_broadcast_on(&wake_me_q); wait_for_all(); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); #endif #if CS402TESTS > 3 dbg_print("wake me uncancellable test"); start_proc(&pt, "wake me uncancellable test", wakeme_uncancellable_test, 0); /* Make sure p has blocked */ stop_until_queued(1, &wake_me_len); sched_wakeup_on(&wake_me_q); wait_for_proc(pt.p); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); dbg_print("broadcast me uncancellable test"); for (i = 0; i < 10; i++ ) start_proc(NULL, "broadcast me uncancellable test", wakeme_uncancellable_test, 0); /* Make sure the processes have blocked */ stop_until_queued(10, &wake_me_len); sched_broadcast_on(&wake_me_q); wait_for_all(); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); #endif #if CS402TESTS > 4 dbg_print("cancel me test"); start_proc(&pt, "cancel me test", cancelme_test, 0); /* Make sure p has blocked */ stop_until_queued(1, &wake_me_len); sched_cancel(pt.t); wait_for_proc(pt.p); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); dbg_print("prior cancel me test"); start_proc(&pt, "prior cancel me test", cancelme_test, 0); /* Cancel before sleep */ sched_cancel(pt.t); wait_for_proc(pt.p); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); dbg_print("cancel me head test"); start_proc(&pt, "cancel me head test", cancelme_test, 0); start_proc(NULL, "cancel me head test", wakeme_test, 0); stop_until_queued(2, &wake_me_len); sched_cancel(pt.t); sched_wakeup_on(&wake_me_q); wait_for_all(); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); dbg_print("cancel me tail test"); start_proc(NULL, "cancel me tail test", wakeme_test, 0); start_proc(&pt, "cancel me tail test", cancelme_test, 0); stop_until_queued(2, &wake_me_len); sched_cancel(pt.t); sched_wakeup_on(&wake_me_q); wait_for_all(); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); #endif #if CS402TESTS > 5 dbg_print("Reparenting test"); start_proc(NULL, "Reparenting test", reparent_test, 1); stop_until_queued(1, &wake_me_len); sched_wakeup_on(&wake_me_q); wait_for_all(); stop_until_zero(&wake_me_len); dbg_print("Reparenting stress test"); start_proc(NULL, "Reparenting stress test", reparent_test, 10); stop_until_queued(10, &wake_me_len); sched_broadcast_on(&wake_me_q); wait_for_all(); stop_until_zero(&wake_me_len); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); #endif #if CS402TESTS > 6 kmutex_init(&mutex); dbg_print("show race test"); race = 0; for (i = 0; i < 10; i++ ) start_proc(NULL, "show race test", racer_test, 0); wait_for_all(); dbg_print("fix race test"); race = 0; for (i = 0; i < 10; i++ ) start_proc(NULL, "fix race test", mutex_uncancellable_test, 0); wait_for_all(); dbg_print("fix race test w/cancel"); race = 0; for (i = 0; i < 10; i++ ) { if ( i % 2 == 0) { start_proc(NULL, "fix race test w/cancel", mutex_test, 0); } else { start_proc(&pt, "fix race test w/cancel", mutex_test_cancelme, 0); sched_cancel(pt.t); } } wait_for_all(); #endif #if CS402TESTS > 7 dbg_print("kill all test"); for ( i=0 ; i < 10; i++ ) start_proc(NULL, "kill all test", cancelme_test, 0); stop_until_queued(10, &wake_me_len); proc_kill_all(); wait_for_all(); KASSERT(wake_me_len == 0 && "Error on wakeme bookkeeping"); #endif #if CS402TESTS > 8 student_tests(arg1, arg2); #endif dbg_print("All tests completed\n\n"); return NULL; }
/* * The tty subsystem calls this when the tty driver has received a * character. Now, the line discipline needs to store it in its read * buffer and move the read tail forward. * * Special cases to watch out for: backspaces (both ASCII characters * 0x08 and 0x7F should be treated as backspaces), newlines ('\r' or * '\n'), and full buffers. * * Return a null terminated string containing the characters which * need to be echoed to the screen. For a normal, printable character, * just the character to be echoed. */ const char * n_tty_receive_char(tty_ldisc_t *ldisc, char c) { /* DRIVERS{{{ */ static const char echo_newline[] = {CR, LF, '\0'}; static const char echo_bs[] = {BS, SPACE, BS, '\0'}; static const char echo_esc[] = { '^', '\0' }; static const char echo_null[] = { '\0' }; static char echo_char[] = { ' ', '\0' }; n_tty_t *ntty; KASSERT(NULL != ldisc); ntty = ldisc_to_ntty(ldisc); N_TTY_ASSERT_VALID(ntty); switch (c) { case BS: case DEL: dprintf("Received backspace\n"); if (!n_tty_rawbuf_empty(ntty)) { n_tty_rawbuf_remove_last(ntty); return echo_bs; } return echo_null; case ESC: dprintf("Received escape\n"); if (n_tty_rawbuf_almost_full(ntty)) return echo_null; n_tty_rawbuf_enqueue(ntty, c); return echo_esc; case CR: c = LF; case LF: dprintf("Received newline\n"); if (n_tty_rawbuf_full(ntty)) return echo_null; n_tty_rawbuf_enqueue(ntty, c); n_tty_rawbuf_cook(ntty); if (!sched_queue_empty(&ntty->ntty_rwaitq)) { kthread_t *thr = sched_wakeup_on(&ntty->ntty_rwaitq); KASSERT(NULL != thr); } return echo_newline; case EOT: dprintf("Received EOT\n"); n_tty_rawbuf_cook(ntty); if (!sched_queue_empty(&ntty->ntty_rwaitq)) { kthread_t *thr = sched_wakeup_on(&ntty->ntty_rwaitq); KASSERT(NULL != thr); } return echo_null; default: dprintf("Receiving printable character\n"); if (n_tty_rawbuf_almost_full(ntty)) return echo_null; n_tty_rawbuf_enqueue(ntty, c); echo_char[0] = c; return echo_char; } panic("Should never get here\n"); /* DRIVERS }}} */ return NULL; }