/* * Initialize the fields of the n_tty_t struct, allocate any memory * you will need later, and set the tty_ldisc field of the tty. */ void n_tty_attach(tty_ldisc_t *ldisc, tty_device_t *tty) { /* DRIVERS {{{ */ n_tty_t *ntty; KASSERT(NULL != ldisc); KASSERT(NULL != tty); KASSERT(NULL == tty->tty_ldisc); ntty = ldisc_to_ntty(ldisc); dprintf("Attaching n_tty line discipline to tty %u\n", tty->tty_id); kmutex_init(&ntty->ntty_rlock); sched_queue_init(&ntty->ntty_rwaitq); ntty->ntty_inbuf = (char *)kmalloc(sizeof(char) * TTY_BUF_SIZE); if (NULL == ntty->ntty_inbuf) panic("Not enough memory for n_tty input buffer\n"); KASSERT(NULL != ntty->ntty_inbuf); ntty->ntty_rhead = 0; ntty->ntty_rawtail = 0; ntty->ntty_ckdtail = 0; tty->tty_ldisc = ldisc; KASSERT(n_tty_rawbuf_empty(ntty)); KASSERT(!n_tty_rawbuf_full(ntty)); KASSERT(n_tty_rawbuf_size(ntty) == 0); KASSERT(n_tty_ckdbuf_empty(ntty)); KASSERT(n_tty_ckdbuf_size(ntty) == 0); /* DRIVERS }}} */ }
void kmutex_init(kmutex_t *mtx) { /*NOT_YET_IMPLEMENTED("PROCS: kmutex_init");*/ dbg_print("\nInitializing the Mutex\n"); sched_queue_init(&mtx->km_waitq); /* wait queue */ mtx->km_holder=NULL; }
void * sunghan_test(int arg1, void *arg2) { int status; int proc_count = 0; pid_t proc_pid[3]; int i; dbg(DBG_TEST, ">>> Start running sunghan_test()...\n"); mynode.length = 0; kmutex_init(&mynode.my_mutex); sched_queue_init(&mynode.my_queue); proc_t *p1 = proc_create("add_node"); KASSERT(NULL != p1); kthread_t *thr1 = kthread_create(p1, add_my_node, 0, NULL); KASSERT(NULL != thr1); sched_make_runnable(thr1); proc_pid[proc_count++] = p1->p_pid; proc_t *p2 = proc_create("remove_node"); KASSERT(NULL != p2); kthread_t *thr2 = kthread_create(p2, remove_my_node, 0, NULL); KASSERT(NULL != thr2); sched_make_runnable(thr2); proc_pid[proc_count++] = p2->p_pid; proc_t *p3 = proc_create("watch_dog"); KASSERT(NULL != p3); kthread_t *thr3 = kthread_create(p3, watch_dog, 0, NULL); KASSERT(NULL != thr3); sched_make_runnable(thr3); proc_pid[proc_count++] = p3->p_pid; for (i=0; i<2; ++i) { do_waitpid(proc_pid[i], 0, &status); } sched_broadcast_on(&mynode.my_queue); do_waitpid(proc_pid[2], 0, &status); while (!do_waitpid(p2->p_pid, 0, &status)); dbg(DBG_TEST, "sunghan_test() terminated\n"); return NULL; }
void sched_broadcast_on(ktqueue_t *q) { kthread_t *temp; while(!list_empty(&(q->tq_list))) { temp = ktqueue_dequeue(q); temp->kt_state = KT_RUN; ktqueue_enqueue(&kt_runq, temp); } sched_queue_init(q); return; }
void * sunghan_deadlock_test(int arg1, void *arg2) { int status; int proc_count = 0; pid_t proc_pid[3]; int i; dbg(DBG_TEST, ">>> Start running sunghan_deadlock_test()...\n"); mynode.length = 0; kmutex_init(&mynode.my_mutex); sched_queue_init(&mynode.my_queue); proc_t *p1 = proc_create("add_node"); KASSERT(NULL != p1); kthread_t *thr1 = kthread_create(p1, add_my_node, 0, NULL); KASSERT(NULL != thr1); sched_make_runnable(thr1); proc_pid[proc_count++] = p1->p_pid; proc_t *p2 = proc_create("remove_node"); KASSERT(NULL != p2); kthread_t *thr2 = kthread_create(p2, remove_my_node, 0, NULL); KASSERT(NULL != thr2); sched_make_runnable(thr2); proc_pid[proc_count++] = p2->p_pid; for (i=0; i<2; ++i) { do_waitpid(proc_pid[i], 0, &status); } sched_broadcast_on(&mynode.my_queue); dbg(DBG_TEST, "Shouldn't have gotten here in sunghan_deadlock_test(). Did NOT deadlock.\n"); return NULL; }
void sched_make_runnable(kthread_t *thr) { KASSERT(&kt_runq != thr->kt_wchan); static int i = 1; if(thr->kt_proc->p_pid == 0 && i == 1) { sched_queue_init(&kt_runq); i = i+1; } dbg(DBG_THR,"ADDING PROCESS: %s, ON RUN_QUEUE\n", thr->kt_proc->p_comm); uint8_t curr_intr_level = apic_getipl(); apic_setipl(IPL_HIGH); thr->kt_state = KT_RUN; ktqueue_enqueue(&kt_runq,thr); apic_setipl(curr_intr_level); }
static __attribute__((unused)) void sched_init(void) { sched_queue_init(&kt_runq); }
/* 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; }