/** Softirq thread function. * * Once started, a softirq thread waits for tasklets to be scheduled * and executes them. * * \param arg # of this softirq thread so that it grabs the correct lock * if multiple softirq threads are running. */ void l4dde26_softirq_thread(void *arg) { printk("Softirq daemon starting\n"); l4dde26_process_add_worker(); /* This thread will always be in a softirq, so set the * corresponding flag right now. */ preempt_count() |= SOFTIRQ_MASK; while(1) { ddekit_sem_down(dde_softirq_sem); do_softirq(); } }
/***************************************************************************** * ddekit_minix_rcv * ****************************************************************************/ void ddekit_minix_rcv(struct ddekit_minix_msg_q *mq, message *m) { DDEBUG_MSG_VERBOSE("waiting for message"); ddekit_sem_down(mq->msg_r_sem); memcpy(m, &mq->messages[mq->msg_r_pos], sizeof(message)); if (++mq->msg_r_pos == MESSAGE_QUEUE_SIZE) { mq->msg_r_pos = 0; } DDEBUG_MSG_VERBOSE("unqueing message"); ddekit_sem_up(mq->msg_w_sem); }
/* Our version of scheduler invocation. * * Scheduling is performed by Fiasco, so we don't care about it as long as * a thread is running. If a task becomes TASK_INTERRUPTIBLE or * TASK_UNINTERRUPTIBLE, we make sure that the task does not become * scheduled by locking the task's sleep lock. */ asmlinkage void schedule(void) { dde26_thread_data *t = lxtask_to_ddethread(current); switch (current->state) { case TASK_RUNNING: ddekit_thread_schedule(); break; case TASK_INTERRUPTIBLE: case TASK_UNINTERRUPTIBLE: ddekit_sem_down(SLEEP_LOCK(t)); break; default: panic("current->state = %d --- unknown state\n", current->state); } }
/***************************************************************************** * ddekit_timer_thread * ****************************************************************************/ static void ddekit_timer_thread(void * data) { struct ddekit_timer_s * l; /* rock around the clock! */ for ( ; ; ) { /* wait for timer interrupts */ ddekit_sem_down(pending_timer_ints); DDEBUG_MSG_VERBOSE("handling timer interrupt"); /* execute all expired timers */ while( (l = get_next(jiffies)) != 0 ) { DDEBUG_MSG_TIMER(l); if (l->fn) { l->fn(l->args); } ddekit_simple_free(l); } } }
/*===========================================================================* * blocking_urb_submit * *===========================================================================*/ int blocking_urb_submit(struct ddekit_usb_urb * urb, ddekit_sem_t * sem, int check_len) { HUB_DEBUG_DUMP; assert(NULL != urb); assert(NULL != sem); assert((check_len == URB_SUBMIT_CHECK_LEN) || (check_len == URB_SUBMIT_ALLOW_MISMATCH)); /* Submit and block until semaphore gets up */ if (ddekit_usb_submit_urb(urb)) { HUB_MSG("Submitting DDEKit URB failed"); return EXIT_FAILURE; } else { /* Submitting succeeded so block and wait for reply */ ddekit_sem_down(sem); /* Check for DDEKit status first */ if (urb->status) { HUB_MSG("Invalid DDEKit URB status"); return EXIT_FAILURE; } else { if (URB_SUBMIT_CHECK_LEN == check_len) { /* Compare lengths */ if (urb->actual_length != urb->size) { HUB_MSG("URB different than expected"); return EXIT_FAILURE; } } return EXIT_SUCCESS; } } }
void ddekit_minix_wait_exit(void) { ddekit_sem_down(exit_sem); }