* - Do not call system functions that may implicitly sleep, such as
* timer_delayTicks().
*
- * \version $Id$
* \author Bernie Innocenti <bernie@codewiz.org>
*/
// Check config dependencies
CONFIG_DEPEND(CONFIG_KERN_SIGNALS, CONFIG_KERN);
-/**
- * Check if any of the signals in \a sigs has occurred and clear them.
- *
- * \return the signals that have occurred.
- */
-sigmask_t sig_check(sigmask_t sigs)
-{
- sigmask_t result;
- cpu_flags_t flags;
-
- IRQ_SAVE_DISABLE(flags);
- result = current_process->sig_recv & sigs;
- current_process->sig_recv &= ~sigs;
- IRQ_RESTORE(flags);
-
- return result;
-}
-
-
-/**
- * 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 sig_waitSignal(Signal *s, sigmask_t sigs)
{
sigmask_t result;
IRQ_DISABLE;
/* Loop until we get at least one of the signals */
- while (!(result = current_process->sig_recv & sigs))
+ while (!(result = s->recv & sigs))
{
/*
* Tell "them" that we want to be awaken when any of these
* signals arrives.
*/
- current_process->sig_wait = sigs;
+ s->wait = sigs;
/* Go to sleep and proc_switch() to another process. */
proc_switch();
* 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);
+ ASSERT(!s->wait);
+ ASSERT(s->recv & sigs);
}
/* Signals found: clear them and return */
- current_process->sig_recv &= ~sigs;
+ s->recv &= ~sigs;
IRQ_ENABLE;
return result;
#if CONFIG_TIMER_EVENTS
#include <drv/timer.h>
-/**
- * Sleep until any of the signals in \a sigs or \a timeout ticks elapse.
- * If the timeout elapse a SIG_TIMEOUT is added to the received signal(s).
- * \return the signal(s) that have awoken the process.
- * \note Caller must check return value to check which signal awoke the process.
- */
-sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout)
+
+sigmask_t sig_waitTimeoutSignal(Signal *s, sigmask_t sigs, ticks_t timeout,
+ Hook func, iptr_t data)
{
Timer t;
sigmask_t res;
cpu_flags_t flags;
- ASSERT(!sig_check(SIG_TIMEOUT));
+ ASSERT(!sig_checkSignal(s, SIG_TIMEOUT));
ASSERT(!(sigs & SIG_TIMEOUT));
/* IRQ are needed to run timer */
ASSERT(IRQ_ENABLED());
- timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
+ if (func)
+ timer_setSoftint(&t, func, data);
+ else
+ timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
timer_setDelay(&t, timeout);
timer_add(&t);
- res = sig_wait(SIG_TIMEOUT | sigs);
+ res = sig_waitSignal(s, SIG_TIMEOUT | sigs);
IRQ_SAVE_DISABLE(flags);
/* Remove timer if sigs occur before timer signal */
- if (!(res & SIG_TIMEOUT) && !sig_check(SIG_TIMEOUT))
+ if (!(res & SIG_TIMEOUT) && !sig_checkSignal(s, SIG_TIMEOUT))
timer_abort(&t);
IRQ_RESTORE(flags);
return res;
#endif // CONFIG_TIMER_EVENTS
-INLINE void __sig_signal(Process *proc, sigmask_t sigs, bool wakeup)
+INLINE void __sig_signal(Signal *s, Process *proc, sigmask_t sigs, bool wakeup)
{
cpu_flags_t flags;
- if (UNLIKELY(proc == current_process))
- return;
-
IRQ_SAVE_DISABLE(flags);
/* Set the signals */
- proc->sig_recv |= sigs;
+ s->recv |= sigs;
/* Check if process needs to be awoken */
- if (proc->sig_recv & proc->sig_wait)
+ if (s->recv & s->wait)
{
- proc->sig_wait = 0;
+ ASSERT(proc != current_process);
+
+ s->wait = 0;
if (wakeup)
proc_wakeup(proc);
else
IRQ_RESTORE(flags);
}
-/**
- * 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)
+void sig_sendSignal(Signal *s, Process *proc, sigmask_t sigs)
{
ASSERT_USER_CONTEXT();
IRQ_ASSERT_ENABLED();
ASSERT(proc_preemptAllowed());
- __sig_signal(proc, sigs, true);
+ __sig_signal(s, proc, sigs, true);
}
-/**
- * Send the signals \a sigs to the process \a proc.
- * The process will be awoken if it was waiting for any of them.
- *
- * \note This call is interrupt safe.
- */
-void sig_post(Process *proc, sigmask_t sigs)
+void sig_postSignal(Signal *s, Process *proc, sigmask_t sigs)
{
- __sig_signal(proc, sigs, false);
+ __sig_signal(s, proc, sigs, false);
}
#endif /* CONFIG_KERN_SIGNALS */