signal.c
Go to the documentation of this file.00001
00101 #include "signal.h"
00102
00103 #include <cfg/cfg_timer.h>
00104 #include <cfg/debug.h>
00105 #include <cpu/irq.h>
00106 #include <kern/proc.h>
00107 #include <kern/proc_p.h>
00108
00109
00110 #if CONFIG_KERN_SIGNALS
00111
00117 sigmask_t sig_check(sigmask_t sigs)
00118 {
00119 sigmask_t result;
00120 cpu_flags_t flags;
00121
00122 IRQ_SAVE_DISABLE(flags);
00123 result = CurrentProcess->sig_recv & sigs;
00124 CurrentProcess->sig_recv &= ~sigs;
00125 IRQ_RESTORE(flags);
00126
00127 return result;
00128 }
00129
00130
00135 sigmask_t sig_wait(sigmask_t sigs)
00136 {
00137 sigmask_t result;
00138 cpu_flags_t flags;
00139
00140
00141 IRQ_ASSERT_ENABLED();
00142 ASSERT(proc_allowed());
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 IRQ_SAVE_DISABLE(flags);
00155
00156
00157 while (!(result = CurrentProcess->sig_recv & sigs))
00158 {
00159
00160
00161
00162
00163 CurrentProcess->sig_wait = sigs;
00164
00165
00166
00167
00168
00169
00170
00171 IRQ_RESTORE(flags);
00172 proc_switch();
00173 IRQ_SAVE_DISABLE(flags);
00174
00175
00176
00177
00178
00179
00180
00181 ASSERT(!CurrentProcess->sig_wait);
00182 ASSERT(CurrentProcess->sig_recv & sigs);
00183 }
00184
00185
00186 CurrentProcess->sig_recv &= ~sigs;
00187
00188 IRQ_RESTORE(flags);
00189 return result;
00190 }
00191
00192 #if CONFIG_TIMER_EVENTS
00193
00194 #include <drv/timer.h>
00201 sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout)
00202 {
00203 Timer t;
00204 sigmask_t res;
00205 cpu_flags_t flags;
00206
00207 ASSERT(!sig_check(SIG_TIMEOUT));
00208 ASSERT(!(sigs & SIG_TIMEOUT));
00209
00210 ASSERT(IRQ_ENABLED());
00211
00212 timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
00213 timer_setDelay(&t, timeout);
00214 timer_add(&t);
00215 res = sig_wait(SIG_TIMEOUT | sigs);
00216
00217 IRQ_SAVE_DISABLE(flags);
00218
00219 if (!(res & SIG_TIMEOUT) && !sig_check(SIG_TIMEOUT))
00220 timer_abort(&t);
00221 IRQ_RESTORE(flags);
00222 return res;
00223 }
00224
00225 #endif // CONFIG_TIMER_EVENTS
00226
00227
00234 void sig_signal(Process *proc, sigmask_t sigs)
00235 {
00236 cpu_flags_t flags;
00237
00238
00239 IRQ_SAVE_DISABLE(flags);
00240
00241
00242 proc->sig_recv |= sigs;
00243
00244
00245 if (proc->sig_recv & proc->sig_wait)
00246 {
00247
00248 proc->sig_wait = 0;
00249 SCHED_ENQUEUE(proc);
00250 }
00251
00252 IRQ_RESTORE(flags);
00253 }
00254
00255 #endif