signal.c
Go to the documentation of this file.00001
00128 #include "signal.h"
00129
00130 #include "cfg/cfg_timer.h"
00131 #include <cfg/debug.h>
00132 #include <cfg/depend.h>
00133
00134 #include <cpu/irq.h>
00135 #include <kern/proc.h>
00136 #include <kern/proc_p.h>
00137
00138
00139 #if CONFIG_KERN_SIGNALS
00140
00141
00142 CONFIG_DEPEND(CONFIG_KERN_SIGNALS, CONFIG_KERN);
00143
00144 sigmask_t sig_waitSignal(Signal *s, sigmask_t sigs)
00145 {
00146 sigmask_t result;
00147
00148
00149 IRQ_ASSERT_ENABLED();
00150 ASSERT(proc_preemptAllowed());
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161 IRQ_DISABLE;
00162
00163
00164 while (!(result = s->recv & sigs))
00165 {
00166
00167
00168
00169
00170 s->wait = sigs;
00171
00172
00173 proc_switch();
00174
00175
00176
00177
00178
00179
00180 ASSERT(!s->wait);
00181 ASSERT(s->recv & sigs);
00182 }
00183
00184
00185 s->recv &= ~sigs;
00186
00187 IRQ_ENABLE;
00188 return result;
00189 }
00190
00191 #if CONFIG_TIMER_EVENTS
00192
00193 #include <drv/timer.h>
00194
00195 sigmask_t sig_waitTimeoutSignal(Signal *s, sigmask_t sigs, ticks_t timeout,
00196 Hook func, iptr_t data)
00197 {
00198 Timer t;
00199 sigmask_t res;
00200 cpu_flags_t flags;
00201
00202 ASSERT(!sig_checkSignal(s, SIG_TIMEOUT));
00203 ASSERT(!(sigs & SIG_TIMEOUT));
00204
00205 ASSERT(IRQ_ENABLED());
00206
00207 if (func)
00208 timer_setSoftint(&t, func, data);
00209 else
00210 timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
00211 timer_setDelay(&t, timeout);
00212 timer_add(&t);
00213 res = sig_waitSignal(s, SIG_TIMEOUT | sigs);
00214
00215 IRQ_SAVE_DISABLE(flags);
00216
00217 if (!(res & SIG_TIMEOUT) && !sig_checkSignal(s, SIG_TIMEOUT))
00218 timer_abort(&t);
00219 IRQ_RESTORE(flags);
00220 return res;
00221 }
00222
00223 #endif // CONFIG_TIMER_EVENTS
00224
00225 INLINE void __sig_signal(Signal *s, Process *proc, sigmask_t sigs, bool wakeup)
00226 {
00227 cpu_flags_t flags;
00228
00229 IRQ_SAVE_DISABLE(flags);
00230
00231
00232 s->recv |= sigs;
00233
00234
00235 if (s->recv & s->wait)
00236 {
00237 ASSERT(proc != current_process);
00238
00239 s->wait = 0;
00240 if (wakeup)
00241 proc_wakeup(proc);
00242 else
00243 SCHED_ENQUEUE_HEAD(proc);
00244 }
00245 IRQ_RESTORE(flags);
00246 }
00247
00248 void sig_sendSignal(Signal *s, Process *proc, sigmask_t sigs)
00249 {
00250 ASSERT_USER_CONTEXT();
00251 IRQ_ASSERT_ENABLED();
00252 ASSERT(proc_preemptAllowed());
00253
00254 __sig_signal(s, proc, sigs, true);
00255 }
00256
00257 void sig_postSignal(Signal *s, Process *proc, sigmask_t sigs)
00258 {
00259 __sig_signal(s, proc, sigs, false);
00260 }
00261
00262 #endif