signal.c
Go to the documentation of this file.00001 00103 #include "signal.h" 00104 00105 #include <cfg/debug.h> 00106 #include <drv/timer.h> 00107 #include <kern/proc.h> 00108 #include <kern/proc_p.h> 00109 00110 00111 #if CONFIG_KERN_SIGNALS 00112 00117 sigmask_t sig_check(sigmask_t sigs) 00118 { 00119 sigmask_t result; 00120 cpuflags_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 cpuflags_t flags; 00139 00140 IRQ_SAVE_DISABLE(flags); 00141 00142 /* Loop until we get at least one of the signals */ 00143 while (!(result = CurrentProcess->sig_recv & sigs)) 00144 { 00145 /* go to sleep and proc_schedule() another process */ 00146 CurrentProcess->sig_wait = sigs; 00147 proc_schedule(); 00148 00149 /* When we come back here, a signal must be arrived */ 00150 ASSERT(!CurrentProcess->sig_wait); 00151 ASSERT(CurrentProcess->sig_recv); 00152 } 00153 00154 /* Signals found: clear them and return */ 00155 CurrentProcess->sig_recv &= ~sigs; 00156 00157 IRQ_RESTORE(flags); 00158 return result; 00159 } 00160 00167 sigmask_t sig_waitTimeout(sigmask_t sigs, ticks_t timeout) 00168 { 00169 Timer t; 00170 sigmask_t res; 00171 cpuflags_t flags; 00172 00173 ASSERT(!sig_check(SIG_TIMEOUT)); 00174 ASSERT(!(sigs & SIG_TIMEOUT)); 00175 /* IRQ are needed to run timer */ 00176 ASSERT(IRQ_ENABLED()); 00177 00178 timer_set_event_signal(&t, proc_current(), SIG_TIMEOUT); 00179 timer_setDelay(&t, timeout); 00180 timer_add(&t); 00181 res = sig_wait(SIG_TIMEOUT | sigs); 00182 00183 IRQ_SAVE_DISABLE(flags); 00184 /* Remove timer if sigs occur before timer signal */ 00185 if (!(res & SIG_TIMEOUT) && !sig_check(SIG_TIMEOUT)) 00186 timer_abort(&t); 00187 IRQ_RESTORE(flags); 00188 return res; 00189 } 00190 00191 00198 void sig_signal(Process *proc, sigmask_t sigs) 00199 { 00200 cpuflags_t flags; 00201 IRQ_SAVE_DISABLE(flags); 00202 00203 /* Set the signals */ 00204 proc->sig_recv |= sigs; 00205 00206 /* Check if process needs to be awoken */ 00207 if (proc->sig_recv & proc->sig_wait) 00208 { 00209 /* Wake up process and enqueue in ready list */ 00210 proc->sig_wait = 0; 00211 SCHED_ENQUEUE(proc); 00212 } 00213 00214 IRQ_RESTORE(flags); 00215 } 00216 00217 #endif /* CONFIG_KERN_SIGNALS */ 00218
