event.c
Go to the documentation of this file.00001
00040 #include "event.h"
00041 #include "cfg/cfg_signal.h"
00042 #include "cfg/cfg_timer.h"
00043
00044 #include <drv/timer.h>
00045
00046 void event_hook_ignore(UNUSED_ARG(Event *, e))
00047 {
00048 }
00049
00050 void event_hook_softint(Event *e)
00051 {
00052 e->Ev.Int.func(e->Ev.Int.user_data);
00053 }
00054
00055 void event_hook_generic(Event *e)
00056 {
00057 e->Ev.Gen.completed = true;
00058 MEMORY_BARRIER;
00059 }
00060
00061 #if CONFIG_KERN && CONFIG_KERN_SIGNALS
00062 void event_hook_signal(Event *e)
00063 {
00064 sig_post((e)->Ev.Sig.sig_proc, (e)->Ev.Sig.sig_bit);
00065 }
00066
00067 void event_hook_generic_signal(Event *e)
00068 {
00069 sig_postSignal(&e->Ev.Sig.sig, e->Ev.Sig.sig_proc, e->Ev.Sig.sig_bit);
00070 }
00071
00072
00073
00074
00075
00076 static void event_hook_generic_multiple_signal(Event *e)
00077 {
00078 sig_post(e->Ev.Sig.sig_proc, e->Ev.Sig.sig_bit);
00079 }
00080
00081
00082
00083
00084 static void event_hook_generic_timeout_signal(void *arg)
00085 {
00086 Event *e = (Event *)arg;
00087
00088 sig_postSignal(&e->Ev.Sig.sig, e->Ev.Sig.sig_proc, SIG_TIMEOUT);
00089 }
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103 static NOINLINE bool event_waitTimeoutSlowPath(Event *e, ticks_t timeout)
00104 {
00105 bool ret;
00106
00107 e->Ev.Sig.sig_proc = proc_current();
00108 ret = (sig_waitTimeoutSignal(&e->Ev.Sig.sig,
00109 EVENT_GENERIC_SIGNAL, timeout,
00110 event_hook_generic_timeout_signal, e) & SIG_TIMEOUT) ?
00111 false : true;
00112 return ret;
00113 }
00114
00115 bool event_waitTimeout(Event *e, ticks_t timeout)
00116 {
00117
00118
00119
00120
00121 if (sig_checkSignal(&e->Ev.Sig.sig,
00122 EVENT_GENERIC_SIGNAL) == EVENT_GENERIC_SIGNAL)
00123 return true;
00124 return event_waitTimeoutSlowPath(e, timeout);
00125 }
00126
00127
00128
00129
00130
00131
00132
00133 static NOINLINE int event_selectSlowPath(Event **evs, int n, ticks_t timeout)
00134 {
00135 sigmask_t mask = (1 << n) - 1;
00136 int i;
00137
00138 for (i = 0; i < n; i++)
00139 {
00140 Event *e = evs[i];
00141
00142
00143 e->Ev.Sig.sig_proc = proc_current();
00144 e->Ev.Sig.sig_bit = 1 << i;
00145 e->action = event_hook_generic_multiple_signal;
00146 }
00147 IRQ_ENABLE;
00148
00149 mask = timeout ? sig_waitTimeout(mask, timeout) : sig_wait(mask);
00150 if (mask & SIG_TIMEOUT)
00151 return -1;
00152 return UINT8_LOG2(mask);
00153 }
00154
00155 int event_select(Event **evs, int n, ticks_t timeout)
00156 {
00157 int i;
00158
00159 ASSERT(n <= SIG_USER_MAX);
00160
00161 IRQ_DISABLE;
00162
00163 for (i = 0; i < n; i++)
00164 {
00165 Event *e = evs[i];
00166
00167 if (__sig_checkSignal(&e->Ev.Sig.sig,
00168 EVENT_GENERIC_SIGNAL) == EVENT_GENERIC_SIGNAL)
00169 {
00170 IRQ_ENABLE;
00171 return i;
00172 }
00173 }
00174
00175 return event_selectSlowPath(evs, n, timeout);
00176 }
00177 #else
00178 bool event_waitTimeout(Event *e, ticks_t timeout)
00179 {
00180 ticks_t end = timer_clock() + timeout;
00181 bool ret;
00182
00183 while ((ACCESS_SAFE(e->Ev.Gen.completed) == false) ||
00184 TIMER_AFTER(timer_clock(), end))
00185 cpu_relax();
00186 ret = e->Ev.Gen.completed;
00187 e->Ev.Gen.completed = false;
00188 MEMORY_BARRIER;
00189
00190 return ret;
00191 }
00192
00193 int event_select(Event **evs, int n, ticks_t timeout)
00194 {
00195 ticks_t end = timer_clock() + timeout;
00196 int i;
00197
00198 while (1)
00199 {
00200 for (i = 0; i < n; i++)
00201 {
00202 Event *e = evs[i];
00203 if (ACCESS_SAFE(e->Ev.Gen.completed) == true)
00204 {
00205 e->Ev.Gen.completed = false;
00206 MEMORY_BARRIER;
00207 return i;
00208 }
00209 }
00210 if (timeout && TIMER_AFTER(timer_clock(), end))
00211 break;
00212 cpu_relax();
00213 }
00214 return -1;
00215 }
00216 #endif