static void * sleep_function(int arg1, void *arg2){ dbg(DBG_TEST, "going to sleep...\n"); sched_cancellable_sleep_on((ktqueue_t *) arg2); dbg(DBG_TEST, "awoken from sleep!\n"); return NULL; }
/* * A thread function that waits on wake_me_q and exist when released. If it is * not cancelled, it prints an error message. */ void *cancelme_test(int arg1, void *arg2) { wake_me_len++; if (sched_cancellable_sleep_on(&wake_me_q) != -EINTR ) { dbg_print("Wakeme returned?! pid (%d)\n", curproc->p_pid); wake_me_len--; do_exit(-1); } wake_me_len--; do_exit(arg1); return NULL; }
/* * Read a maximum of len bytes from the line discipline into buf. If * the buffer is empty, sleep until some characters appear. This might * be a long wait, so it's best to let the thread be cancellable. * * Then, read from the head of the buffer up to the tail, stopping at * len bytes or a newline character, and leaving the buffer partially * full if necessary. Return the number of bytes you read into the * buf. * In this function, you will be accessing the input buffer, which * could be modified by other threads. Make sure to make the * appropriate calls to ensure that no one else will modify the input * buffer when we are not expecting it. * * Remember to handle newline characters and CTRL-D, or ASCII 0x04, * properly. */ int n_tty_read(tty_ldisc_t *ldisc, void *buf, int len) { /* DRIVERS {{{ */ int i; char *cbuf = (char *)buf; n_tty_t *ntty; KASSERT(TTY_BUF_SIZE < PAGE_SIZE); KASSERT(NULL != ldisc); ntty = ldisc_to_ntty(ldisc); N_TTY_ASSERT_VALID(ntty); KASSERT(NULL != buf); KASSERT(len >= 0); kmutex_lock(&ntty->ntty_rlock); if (n_tty_ckdbuf_empty(ntty)) { dprintf("Cooked buffer is empty. Sleeping\n"); if (sched_cancellable_sleep_on(&ntty->ntty_rwaitq) == -EINTR) { dprintf("Sleep cancelled. Returning -EINTR\n"); kmutex_unlock(&ntty->ntty_rlock); return -EINTR; } dprintf("Woken up from sleep\n"); } for (i = 0; i < len && !n_tty_ckdbuf_empty(ntty); ++i) { cbuf[i] = n_tty_ckdbuf_dequeue(ntty); if (cbuf[i] == LF) { ++i; break; } else if (cbuf[i] == EOT) { break; } } kmutex_unlock(&ntty->ntty_rlock); return i; /* DRIVERS }}} */ return 0; }
/* * This should do the same as kmutex_lock, but use a cancellable sleep * instead. ************************************************************************ * Locks the specified mutex, but puts the current thread into a * cancellable sleep if the function blocks. * * Note: This function may block. * * Note: These locks are not re-entrant. * * @param mtx the mutex to lock * @return 0 if the current thread now holds the mutex and -EINTR if * the sleep was cancelled and this thread does not hold the mutex */ int kmutex_lock_cancellable(kmutex_t *mtx) { /*NOT_YET_IMPLEMENTED("PROCS: kmutex_lock_cancellable"); return 0;*/ if(mtx->km_holder!=NULL) { int temp=sched_cancellable_sleep_on(&mtx->km_waitq); return -EINTR; } else { KASSERT(curthr!=mtx->km_holder && "the current thread already has the mutex"); mtx->km_holder=curthr; return 0; } }