comparison gsm-fw/gpf/osl/os_tim_ir.c @ 464:14d2a7f473c3

OSL: os_tim_ir.c reconstruction by Das Signal
author Michael Spacefalcon <msokolov@ivan.Harhan.ORG>
date Thu, 26 Jun 2014 03:23:29 +0000
parents 7017da4978bb
children d5cf423dad3a
comparison
equal deleted inserted replaced
463:aad742029813 464:14d2a7f473c3
30 30
31 void 31 void
32 timer_error(int err) 32 timer_error(int err)
33 { 33 {
34 } 34 }
35
36 /*
37 * The following function reconstructions have been contributed by Das Signal.
38 * The code passes gcc, but some polish is still likely needed.
39 */
40
41 /* FIXME: t_handle is unused?! */
42 void os_Timeout(UNSIGNED t_handle)
43 {
44 UNSIGNED s_ticks;
45 OS_HANDLE task_handle;
46 OS_HANDLE e_handle;
47 int t_index, i, done;
48 T_OS_TIMER_TABLE_ENTRY **t_r4;
49 T_OS_TIMER_TABLE_ENTRY *timer;
50 void (*timeout_func) (OS_HANDLE, OS_HANDLE, USHORT);
51 OS_TIME InitialTime;
52
53 if (t_list_access) {
54 t_start_ticks++;
55 NU_Reset_Timer(&os_timer_cb, os_Timeout, 1, 0,
56 NU_ENABLE_TIMER);
57 return;
58 }
59
60 t_list_access = 1;
61 timer = t_running;
62 if (t_running) {
63 s_ticks = 0;
64 done = 0;
65 i = 0;
66 do {
67 timeout_func = timer->TimeoutProc;
68 if (timer->p_ticks)
69 p_list[i++] = timer;
70 task_handle = timer->task_handle;
71 e_handle = timer->entity_handle;
72 t_index = timer->t_index;
73 timer->status = 1;
74 if (timer->next == timer) {
75 t_running = NULL;
76 done = 1;
77 } else {
78 timer->prev->next = timer->next;
79 timer->next->prev = timer->prev;
80 if (timer->next->r_ticks) {
81 t_running = timer->next;
82 s_ticks = timer->r_ticks;
83 done = 1;
84 } else
85 timer = timer->next;
86 }
87 /* FIXME: IND$CALL() ? */
88 }
89 while (!done);
90
91 if (s_ticks) {
92 t_start_ticks = NU_Retrieve_Clock();
93 NU_Reset_Timer(&os_timer_cb, os_Timeout, s_ticks, 0,
94 NU_ENABLE_TIMER);
95 }
96 }
97 for (t_r4 = p_list; *t_r4; t_r4++) {
98 timer = *t_r4;
99 InitialTime = SYSTEM_TICKS_TO_TIME(timer->p_ticks);
100 os_StartTimer(timer->entity_handle, timer->t_handle,
101 timer->t_index, InitialTime, InitialTime);
102 *t_r4 = NULL;
103 }
104
105 t_list_access = 0;
106 return;
107 }
108
109 static int os_remove_timer_from_list(T_OS_TIMER_TABLE_ENTRY *timer)
110 {
111 OS_TICK c_ticks;
112
113 if (timer != t_running) {
114 if (timer->next != t_running)
115 timer->next->r_ticks += timer->r_ticks;
116 }
117 else {
118 c_ticks = NU_Retrieve_Clock();
119 if (timer->next == timer) {
120 t_running = 0;
121 } else {
122 timer->next->r_ticks =
123 t_start_ticks + timer->r_ticks +
124 timer->next->r_ticks - c_ticks;
125 t_running = timer->next;
126 }
127 NU_Control_Timer(&os_timer_cb, NU_DISABLE_TIMER);
128 if (t_running != NULL) {
129 t_start_ticks = c_ticks;
130 if (t_running->r_ticks != 0)
131 NU_Reset_Timer(&os_timer_cb, os_Timeout,
132 t_running->r_ticks, 0,
133 NU_ENABLE_TIMER);
134 }
135 }
136 if (timer->next != timer) {
137 timer->prev->next = timer->next;
138 timer->next->prev = timer->prev;
139 }
140 timer->next = NULL;
141 timer->prev = NULL;
142 timer->status = 1;
143 return 1;
144 }
145
146 static unsigned os_add_timer_to_list(T_OS_TIMER_TABLE_ENTRY *timer, OS_TICK ticks)
147 {
148 T_OS_TIMER_TABLE_ENTRY *t_list;
149 OS_TICK c_ticks, r1_ticks, return_ticks;
150
151 if (ticks == 0)
152 ticks = 1;
153
154 c_ticks = NU_Retrieve_Clock();
155 t_list = t_running;
156 if (t_list != NULL) {
157 if (t_running->r_ticks >= c_ticks - t_start_ticks) {
158 r1_ticks =
159 t_running->r_ticks - c_ticks + t_start_ticks;
160 t_running->r_ticks = r1_ticks;
161 } else {
162 r1_ticks = 0;
163 t_running->r_ticks = 0;
164 }
165 t_start_ticks = c_ticks;
166 return_ticks = 0;
167 while (ticks >= r1_ticks) {
168 ticks -= r1_ticks;
169 t_list = t_list->next;
170 if (t_list == t_running)
171 goto out;
172 r1_ticks = t_list->r_ticks;
173 }
174 t_list->r_ticks -= ticks;
175 if (t_list == t_running) {
176 t_running = timer;
177 t_start_ticks = c_ticks;
178 NU_Control_Timer(&os_timer_cb, NU_DISABLE_TIMER);
179 return_ticks = ticks;
180 }
181 out:
182 timer->next = t_list;
183 timer->prev = t_list->prev;
184 t_list->prev->next = timer;
185 t_list->prev = timer;
186 timer->r_ticks = ticks;
187 } else {
188 timer->next = timer;
189 timer->prev = timer;
190 timer->r_ticks = ticks;
191 t_start_ticks = c_ticks;
192 t_running = timer;
193 return_ticks = ticks;
194 }
195 timer->status = 2;
196 return return_ticks;
197 }
198
199 GLOBAL LONG os_StartTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle,
200 USHORT Index, OS_TIME InitialTime,
201 OS_TIME RescheduleTime)
202 {
203 T_OS_TIMER_TABLE_ENTRY *timer;
204 OS_TICK ticks;
205 USHORT status;
206 STATUS sts;
207
208 t_list_access = 1;
209 timer = &TimerTable[TimerHandle].entry;
210 if (TimerHandle > MaxSimultaneousTimer || timer->status == 0) {
211 t_list_access = 0;
212 return OS_ERROR;
213 }
214
215 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
216 /* FIXME: not sure about this
217 if (sts != NU_SUCCESS)
218 os_MyHandle(sts);
219 */
220 status = timer->status;
221 if (status == 2)
222 status = os_remove_timer_from_list(timer);
223 timer->t_handle = TimerHandle;
224 timer->task_handle = os_MyHandle();
225 timer->entity_handle = TaskHandle;
226 timer->t_index = Index;
227 timer->p_ticks = TIME_TO_SYSTEM_TICKS(RescheduleTime);
228 ticks = os_add_timer_to_list(timer, TIME_TO_SYSTEM_TICKS(InitialTime));
229 if (ticks)
230 NU_Reset_Timer(&os_timer_cb, os_Timeout, ticks, 0, NU_ENABLE_TIMER);
231 if (sts == NU_SUCCESS)
232 NU_Release_Semaphore(&TimSemCB);
233 t_list_access = 0;
234 return OS_OK;
235 }
236
237 /* FIXME: TaskHandle is unused?! */
238 GLOBAL LONG os_StopTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle)
239 {
240 T_OS_TIMER_ENTRY *timer_e;
241 STATUS sts;
242
243 t_list_access = 1;
244 timer_e = &TimerTable[TimerHandle];
245 if (TimerHandle > MaxSimultaneousTimer || timer_e->entry.status == 0) {
246 t_list_access = 0;
247 return OS_ERROR;
248 }
249 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
250 if (timer_e->entry.status == 2)
251 os_remove_timer_from_list(&timer_e->entry);
252 if (sts == NU_SUCCESS)
253 NU_Release_Semaphore(&TimSemCB);
254 t_list_access = 0;
255 return OS_OK;
256 }
257
258 GLOBAL LONG os_IncrementTick(OS_TICK ticks)
259 {
260 return OS_OK;
261 }
262
263 /* FIXME: TaskHandle is unused?! */
264 GLOBAL LONG os_DestroyTimer(OS_HANDLE TaskHandle, OS_HANDLE TimerHandle)
265 {
266 STATUS sts;
267 T_OS_TIMER_ENTRY *timer_e;
268
269 t_list_access = 1;
270 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
271 timer_e = &TimerTable[TimerHandle];
272 if (TimerHandle > MaxSimultaneousTimer || timer_e->entry.status == 0) {
273 if (sts == NU_SUCCESS)
274 NU_Release_Semaphore(&TimSemCB);
275 t_list_access = 0;
276 return OS_ERROR;
277 }
278 timer_e->next_t_handle = next_t_handle;
279 timer_e->entry.status = 0;
280 used_timers--;
281 t_list_access = 0;
282 if (sts == NU_SUCCESS)
283 NU_Release_Semaphore(&TimSemCB);
284 return OS_OK;
285 }
286
287 /* FIXME: TaskHandle and MemPoolHandle are unused?! */
288 GLOBAL LONG os_CreateTimer(OS_HANDLE TaskHandle,
289 void (*TimeoutProc) (OS_HANDLE, OS_HANDLE, USHORT),
290 OS_HANDLE *TimerHandle, OS_HANDLE MemPoolHandle)
291 {
292 STATUS sts;
293 OS_HANDLE orig_next_t_handle;
294 T_OS_TIMER_ENTRY *timer_e;
295
296 t_list_access = 1;
297 sts = NU_Obtain_Semaphore(&TimSemCB, NU_SUSPEND);
298 orig_next_t_handle = next_t_handle;
299 if (next_t_handle == 0) { /* INVALID_HANDLE */
300 if (sts == NU_SUCCESS)
301 NU_Release_Semaphore(&TimSemCB);
302 t_list_access = 0;
303 return OS_ERROR;
304 }
305
306 timer_e = &TimerTable[next_t_handle];
307 timer_e->entry.status = 1;
308 timer_e->entry.TimeoutProc = TimeoutProc;
309 *TimerHandle = orig_next_t_handle;
310 next_t_handle = timer_e->next_t_handle;
311 used_timers++;
312 if (max_used_timers < used_timers)
313 max_used_timers = used_timers;
314 if (sts == NU_SUCCESS)
315 NU_Release_Semaphore(&TimSemCB);
316 t_list_access = 0;
317 return OS_OK;
318 }