/** * Send the signals \a sigs to the process \a proc and immeditaly dispatch it * for execution. * * The process will be awoken if it was waiting for any of them and immediately * dispatched for execution. * * \note This function can't be called from IRQ context, use sig_post() * instead. */ void sig_send(Process *proc, sigmask_t sigs) { ASSERT_USER_CONTEXT(); IRQ_ASSERT_ENABLED(); ASSERT(proc_preemptAllowed()); __sig_signal(proc, sigs, true); }
/** * Sleep until any of the signals in \a sigs occurs. * \return the signal(s) that have awoken the process. */ sigmask_t sig_wait(sigmask_t sigs) { sigmask_t result; /* Sleeping with IRQs disabled or preemption forbidden is illegal */ IRQ_ASSERT_ENABLED(); ASSERT(proc_preemptAllowed()); /* * This is subtle: there's a race condition where a concurrent process * or an interrupt may call sig_send()/sig_post() to set a bit in * Process.sig_recv just after we have checked for it, but before we've * set Process.sig_wait to let them know we want to be awaken. * * In this case, we'd deadlock with the signal bit already set and the * process never being reinserted into the ready list. */ IRQ_DISABLE; /* Loop until we get at least one of the signals */ while (!(result = current_process->sig_recv & sigs)) { /* * Tell "them" that we want to be awaken when any of these * signals arrives. */ current_process->sig_wait = sigs; /* Go to sleep and proc_switch() to another process. */ proc_switch(); /* * When we come back here, the wait mask must have been * cleared by someone through sig_send()/sig_post(), and at * least one of the signals we were expecting must have been * delivered to us. */ ASSERT(!current_process->sig_wait); ASSERT(current_process->sig_recv & sigs); } /* Signals found: clear them and return */ current_process->sig_recv &= ~sigs; IRQ_ENABLE; return result; }
/** * Start an ADC convertion. * If a kernel is present, preempt until convertion is complete, otherwise * a busy wait on ADCS bit is done. */ uint16_t adc_hw_read(void) { // Ensure another convertion is not running. ASSERT(!(ADCSRA & BV(ADSC))); // Start convertion ADCSRA |= BV(ADSC); #if CONFIG_KERN // Ensure IRQs enabled. IRQ_ASSERT_ENABLED(); adc_process = proc_current(); sig_wait(SIG_ADC_COMPLETE); #else //Wait in polling until is done while (ADCSRA & BV(ADSC)) ; #endif return(ADC); }