Esempio n. 1
0
/**
 * 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);
}
Esempio n. 2
0
/**
 * 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;
}
Esempio n. 3
0
/**
 * 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);
}