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 <cfg/depend.h>
00106
00107 #include <cpu/irq.h>
00108 #include <kern/proc.h>
00109 #include <kern/proc_p.h>
00110
00111
00112 #if CONFIG_KERN_SIGNALS
00113
00114
00115 CONFIG_DEPEND(CONFIG_KERN_SIGNALS, CONFIG_KERN);
00116
00122 sigmask_t sig_check(sigmask_t sigs)
00123 {
00124 sigmask_t result;
00125 cpu_flags_t flags;
00126
00127 IRQ_SAVE_DISABLE(flags);
00128 result = CurrentProcess->sig_recv & sigs;
00129 CurrentProcess->sig_recv &= ~sigs;
00130 IRQ_RESTORE(flags);
00131
00132 return result;
00133 }
00134
00135
00140 sigmask_t sig_wait(sigmask_t sigs)
00141 {
00142 sigmask_t result;
00143 cpu_flags_t flags;
00144
00145
00146 IRQ_ASSERT_ENABLED();
00147 ASSERT(proc_allowed());
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 IRQ_SAVE_DISABLE(flags);
00160
00161
00162 while (!(result = CurrentProcess->sig_recv & sigs))
00163 {
00164
00165
00166
00167
00168 CurrentProcess->sig_wait = sigs;
00169
00170
00171
00172
00173
00174
00175
00176 IRQ_RESTORE(flags);
00177 proc_switch();
00178 IRQ_SAVE_DISABLE(flags);
00179
00180
00181
00182
00183
00184
00185
00186 ASSERT(!CurrentProcess->sig_wait);
00187 ASSERT(CurrentProcess->sig_recv & sigs);
00188 }
00189
00190
00191 CurrentProcess->sig_recv &= ~sigs;
00192
00193 IRQ_RESTORE(flags);
00194 return result;
00195 }
00196
00197 #if CONFIG_TIMER_EVENTS
00198
00199 #include <drv/timer.h>
00206 sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout)
00207 {
00208 Timer t;
00209 sigmask_t res;
00210 cpu_flags_t flags;
00211
00212 ASSERT(!sig_check(SIG_TIMEOUT));
00213 ASSERT(!(sigs & SIG_TIMEOUT));
00214
00215 ASSERT(IRQ_ENABLED());
00216
00217 timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT);
00218 timer_setDelay(&t, timeout);
00219 timer_add(&t);
00220 res = sig_wait(SIG_TIMEOUT | sigs);
00221
00222 IRQ_SAVE_DISABLE(flags);
00223
00224 if (!(res & SIG_TIMEOUT) && !sig_check(SIG_TIMEOUT))
00225 timer_abort(&t);
00226 IRQ_RESTORE(flags);
00227 return res;
00228 }
00229
00230 #endif // CONFIG_TIMER_EVENTS
00231
00232
00239 void sig_signal(Process *proc, sigmask_t sigs)
00240 {
00241 cpu_flags_t flags;
00242
00243
00244 IRQ_SAVE_DISABLE(flags);
00245
00246
00247 proc->sig_recv |= sigs;
00248
00249
00250 if (proc->sig_recv & proc->sig_wait)
00251 {
00252
00253 proc->sig_wait = 0;
00254 SCHED_ENQUEUE(proc);
00255 }
00256
00257 IRQ_RESTORE(flags);
00258 }
00259
00260 #endif