signal.c
Go to the documentation of this file.00001
00129 #include "signal.h"
00130
00131 #include "cfg/cfg_timer.h"
00132 #include <cfg/debug.h>
00133 #include <cfg/depend.h>
00134
00135 #include <cpu/irq.h>
00136 #include <kern/proc.h>
00137 #include <kern/proc_p.h>
00138
00139
00140 #if CONFIG_KERN_SIGNALS
00141
00142
00143 CONFIG_DEPEND(CONFIG_KERN_SIGNALS, CONFIG_KERN);
00144
00150 sigmask_t sig_check(sigmask_t sigs)
00151 {
00152 sigmask_t result;
00153 cpu_flags_t flags;
00154
00155 IRQ_SAVE_DISABLE(flags);
00156 result = current_process->sig_recv & sigs;
00157 current_process->sig_recv &= ~sigs;
00158 IRQ_RESTORE(flags);
00159
00160 return result;
00161 }
00162
00163
00168 sigmask_t sig_wait(sigmask_t sigs)
00169 {
00170 sigmask_t result;
00171
00172
00173 IRQ_ASSERT_ENABLED();
00174 ASSERT(proc_preemptAllowed());
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 IRQ_DISABLE;
00186
00187
00188 while (!(result = current_process->sig_recv & sigs))
00189 {
00190
00191
00192
00193
00194 current_process->sig_wait = sigs;
00195
00196
00197 proc_switch();
00198
00199
00200
00201
00202
00203
00204 ASSERT(!current_process->sig_wait);
00205 ASSERT(current_process->sig_recv & sigs);
00206 }
00207
00208
00209 current_process->sig_recv &= ~sigs;
00210
00211 IRQ_ENABLE;
00212 return result;
00213 }
00214
00215 #if CONFIG_TIMER_EVENTS
00216
00217 #include <drv/timer.h>
00224 sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout)
00225 {
00226 Timer t;
00227 sigmask_t res;
00228 cpu_flags_t flags;
00229
00230 ASSERT(!sig_check(SIG_TIMEOUT));
00231 ASSERT(!(sigs & SIG_TIMEOUT));
00232
00233 ASSERT(IRQ_ENABLED());
00234
00235 timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
00236 timer_setDelay(&t, timeout);
00237 timer_add(&t);
00238 res = sig_wait(SIG_TIMEOUT | sigs);
00239
00240 IRQ_SAVE_DISABLE(flags);
00241
00242 if (!(res & SIG_TIMEOUT) && !sig_check(SIG_TIMEOUT))
00243 timer_abort(&t);
00244 IRQ_RESTORE(flags);
00245 return res;
00246 }
00247
00248 #endif // CONFIG_TIMER_EVENTS
00249
00250 INLINE void __sig_signal(Process *proc, sigmask_t sigs, bool wakeup)
00251 {
00252 cpu_flags_t flags;
00253
00254 IRQ_SAVE_DISABLE(flags);
00255
00256
00257 proc->sig_recv |= sigs;
00258
00259
00260 if (proc->sig_recv & proc->sig_wait)
00261 {
00262 ASSERT(proc != current_process);
00263
00264 proc->sig_wait = 0;
00265 if (wakeup)
00266 proc_wakeup(proc);
00267 else
00268 SCHED_ENQUEUE_HEAD(proc);
00269 }
00270 IRQ_RESTORE(flags);
00271 }
00272
00283 void sig_send(Process *proc, sigmask_t sigs)
00284 {
00285 ASSERT_USER_CONTEXT();
00286 IRQ_ASSERT_ENABLED();
00287 ASSERT(proc_preemptAllowed());
00288
00289 __sig_signal(proc, sigs, true);
00290 }
00291
00298 void sig_post(Process *proc, sigmask_t sigs)
00299 {
00300 __sig_signal(proc, sigs, false);
00301 }
00302
00303 #endif