Rev 837 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 837 | Rev 859 | ||
---|---|---|---|
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;; |
4 | ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
4 | ;; Copyright (C) MenuetOS 2000-2004 Ville Mikael Turjanmaa ;; |
5 | ;; Distributed under terms of the GNU General Public License ;; |
5 | ;; Distributed under terms of the GNU General Public License ;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
6 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
7 | 7 | ||
8 | $Revision: 802 $ |
8 | $Revision: 859 $ |
9 | 9 | ||
10 | 10 | ||
11 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
11 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
12 | ;; IRQ0 HANDLER (TIMER INTERRUPT) ;; |
12 | ;; IRQ0 HANDLER (TIMER INTERRUPT) ;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
13 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
14 | 14 | ||
15 | 15 | ||
16 | align 32 |
16 | align 32 |
17 | irq0: |
17 | irq0: |
18 | pushad |
18 | pushad |
19 | mov ax, app_data ; |
19 | mov ax, app_data ; |
20 | mov ds, ax |
20 | mov ds, ax |
21 | mov es, ax |
21 | mov es, ax |
22 | 22 | ||
23 | inc dword [timer_ticks] |
23 | inc dword [timer_ticks] |
24 | 24 | ||
25 | mov eax, [timer_ticks] |
25 | mov eax, [timer_ticks] |
26 | call playNote ; <<<--- Speaker driver |
26 | call playNote ; <<<--- Speaker driver |
27 | 27 | ||
28 | cmp eax,[next_usage_update] |
28 | cmp eax,[next_usage_update] |
29 | jb .nocounter |
29 | jb .nocounter |
30 | add eax,100 |
30 | add eax,100 |
31 | mov [next_usage_update],eax |
31 | mov [next_usage_update],eax |
32 | call updatecputimes |
32 | call updatecputimes |
33 | .nocounter: |
33 | .nocounter: |
34 | cmp [DONT_SWITCH], byte 1 |
34 | cmp [DONT_SWITCH], byte 1 |
35 | jne .change_task |
35 | jne .change_task |
36 | 36 | ||
37 | mov al,0x20 ; send End Of Interrupt signal |
37 | mov al,0x20 ; send End Of Interrupt signal |
38 | mov dx,0x20 |
38 | mov dx,0x20 |
39 | out dx,al |
39 | out dx,al |
40 | 40 | ||
41 | mov [DONT_SWITCH], byte 0 |
41 | mov [DONT_SWITCH], byte 0 |
42 | 42 | ||
43 | popad |
43 | popad |
44 | iretd |
44 | iretd |
45 | 45 | ||
46 | .change_task: |
46 | .change_task: |
47 | call update_counters |
47 | call update_counters |
48 | 48 | ||
49 | call find_next_task |
49 | call find_next_task |
50 | mov ecx, eax |
50 | mov ecx, eax |
51 | 51 | ||
52 | mov al,0x20 ; send End Of Interrupt signal |
52 | mov al,0x20 ; send End Of Interrupt signal |
53 | mov dx,0x20 |
53 | mov dx,0x20 |
54 | out dx,al |
54 | out dx,al |
55 | 55 | ||
56 | test ecx, ecx ; if there is only one running process |
56 | test ecx, ecx ; if there is only one running process |
57 | jnz .return |
57 | jnz .return |
58 | 58 | ||
59 | call do_change_task |
59 | call do_change_task |
60 | 60 | ||
61 | .return: |
61 | .return: |
62 | popad |
62 | popad |
63 | ; popfd |
63 | ; popfd |
64 | iretd |
64 | iretd |
65 | 65 | ||
66 | 66 | ||
67 | align 4 |
67 | align 4 |
68 | change_task: |
68 | change_task: |
69 | 69 | ||
70 | pushfd |
70 | pushfd |
71 | cli |
71 | cli |
72 | pushad |
72 | pushad |
73 | 73 | ||
74 | call update_counters |
74 | call update_counters |
75 | 75 | ||
76 | if 0 |
76 | if 0 |
77 | 77 | ||
78 | ; \begin{Mario79} |
78 | ; \begin{Mario79} |
79 | cmp [dma_task_switched], 1 |
79 | cmp [dma_task_switched], 1 |
80 | jne .find_next_task |
80 | jne .find_next_task |
81 | mov [dma_task_switched], 0 |
81 | mov [dma_task_switched], 0 |
82 | mov ebx, [dma_process] |
82 | mov ebx, [dma_process] |
83 | cmp [CURRENT_TASK], ebx |
83 | cmp [CURRENT_TASK], ebx |
84 | je .return |
84 | je .return |
85 | mov edi, [dma_slot_ptr] |
85 | mov edi, [dma_slot_ptr] |
86 | mov [CURRENT_TASK], ebx |
86 | mov [CURRENT_TASK], ebx |
87 | mov [TASK_BASE], edi |
87 | mov [TASK_BASE], edi |
88 | jmp @f |
88 | jmp @f |
89 | .find_next_task: |
89 | .find_next_task: |
90 | ; \end{Mario79} |
90 | ; \end{Mario79} |
91 | 91 | ||
92 | end if |
92 | end if |
93 | 93 | ||
94 | call find_next_task |
94 | call find_next_task |
95 | test eax, eax ; the same task -> skip switch |
95 | test eax, eax ; the same task -> skip switch |
96 | jnz .return |
96 | jnz .return |
97 | @@: |
97 | @@: |
98 | mov [DONT_SWITCH],byte 1 |
98 | mov [DONT_SWITCH],byte 1 |
99 | call do_change_task |
99 | call do_change_task |
100 | 100 | ||
101 | .return: |
101 | .return: |
102 | popad |
102 | popad |
103 | popfd |
103 | popfd |
104 | ret |
104 | ret |
105 | 105 | ||
106 | 106 | ||
107 | uglobal |
107 | uglobal |
108 | align 4 |
108 | align 4 |
109 | far_jump: |
109 | far_jump: |
110 | .offs dd ? |
110 | .offs dd ? |
111 | .sel dw ? |
111 | .sel dw ? |
112 | context_counter dd ? ;noname & halyavin |
112 | context_counter dd ? ;noname & halyavin |
113 | next_usage_update dd ? |
113 | next_usage_update dd ? |
114 | timer_ticks dd ? |
114 | timer_ticks dd ? |
115 | prev_slot dd ? |
115 | prev_slot dd ? |
116 | event_sched dd ? |
116 | event_sched dd ? |
117 | endg |
117 | endg |
118 | 118 | ||
119 | 119 | ||
120 | update_counters: |
120 | update_counters: |
121 | mov edi, [TASK_BASE] |
121 | mov edi, [TASK_BASE] |
122 | mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add |
122 | mov ebx, [edi+TASKDATA.counter_add] ; time stamp counter add |
123 | rdtsc |
123 | rdtsc |
124 | sub eax, ebx |
124 | sub eax, ebx |
125 | add eax, [edi+TASKDATA.counter_sum] ; counter sum |
125 | add eax, [edi+TASKDATA.counter_sum] ; counter sum |
126 | mov [edi+TASKDATA.counter_sum], eax |
126 | mov [edi+TASKDATA.counter_sum], eax |
127 | ret |
127 | ret |
128 | 128 | ||
129 | 129 | ||
130 | ; Find next task to execute |
130 | ; Find next task to execute |
131 | ; result: ebx = number of the selected task |
131 | ; result: ebx = number of the selected task |
132 | ; eax = 1 if the task is the same |
132 | ; eax = 1 if the task is the same |
133 | ; edi = address of the data for the task in ebx |
133 | ; edi = address of the data for the task in ebx |
134 | ; [0x3000] = ebx and [0x3010] = edi |
134 | ; [0x3000] = ebx and [0x3010] = edi |
135 | ; corrupts other regs |
135 | ; corrupts other regs |
136 | find_next_task: |
136 | find_next_task: |
137 | mov ebx, [CURRENT_TASK] |
137 | mov ebx, [CURRENT_TASK] |
138 | mov edi, [TASK_BASE] |
138 | mov edi, [TASK_BASE] |
139 | mov [prev_slot], ebx |
139 | mov [prev_slot], ebx |
140 | 140 | ||
141 | .waiting_for_termination: |
141 | .waiting_for_termination: |
142 | .waiting_for_reuse: |
142 | .waiting_for_reuse: |
143 | .waiting_for_event: |
143 | .waiting_for_event: |
144 | .suspended: |
144 | .suspended: |
145 | cmp ebx, [TASK_COUNT] |
145 | cmp ebx, [TASK_COUNT] |
146 | jb @f |
146 | jb @f |
147 | mov edi, CURRENT_TASK |
147 | mov edi, CURRENT_TASK |
148 | xor ebx, ebx |
148 | xor ebx, ebx |
149 | @@: |
149 | @@: |
150 | 150 | ||
151 | add edi,0x20 |
151 | add edi,0x20 |
152 | inc ebx |
152 | inc ebx |
153 | 153 | ||
154 | mov al, byte [edi+TASKDATA.state] |
154 | mov al, byte [edi+TASKDATA.state] |
155 | test al, al |
155 | test al, al |
156 | jz .found |
156 | jz .found |
157 | cmp al, 1 |
157 | cmp al, 1 |
158 | jz .suspended |
158 | jz .suspended |
159 | cmp al, 2 |
159 | cmp al, 2 |
160 | jz .suspended |
160 | jz .suspended |
161 | cmp al, 3 |
161 | cmp al, 3 |
162 | je .waiting_for_termination |
162 | je .waiting_for_termination |
163 | cmp al, 4 |
163 | cmp al, 4 |
164 | je .waiting_for_termination |
164 | je .waiting_for_termination |
165 | cmp al, 9 |
165 | cmp al, 9 |
166 | je .waiting_for_reuse |
166 | je .waiting_for_reuse |
167 | 167 | ||
168 | mov [CURRENT_TASK],ebx |
168 | mov [CURRENT_TASK],ebx |
169 | mov [TASK_BASE],edi |
169 | mov [TASK_BASE],edi |
170 | 170 | ||
171 | cmp al, 5 |
171 | cmp al, 5 |
172 | jne .noevents |
172 | jne .noevents |
173 | call get_event_for_app |
173 | call get_event_for_app |
174 | test eax, eax |
174 | test eax, eax |
175 | jnz @f |
175 | jnz @f |
176 | mov eax, ebx |
176 | mov eax, ebx |
177 | shl eax, 8 |
177 | shl eax, 8 |
178 | mov eax, [SLOT_BASE + APPDATA.wait_timeout + eax] |
178 | mov eax, [SLOT_BASE + APPDATA.wait_timeout + eax] |
179 | cmp eax, [timer_ticks] |
179 | cmp eax, [timer_ticks] |
180 | jae .waiting_for_event |
180 | jae .waiting_for_event |
181 | xor eax, eax |
181 | xor eax, eax |
182 | @@: |
182 | @@: |
183 | mov [event_sched], eax |
183 | mov [event_sched], eax |
184 | mov [edi+TASKDATA.state], byte 0 |
184 | mov [edi+TASKDATA.state], byte 0 |
185 | .noevents: |
185 | .noevents: |
186 | .found: |
186 | .found: |
187 | mov [CURRENT_TASK],ebx |
187 | mov [CURRENT_TASK],ebx |
188 | mov [TASK_BASE],edi |
188 | mov [TASK_BASE],edi |
189 | rdtsc ;call _rdtsc |
189 | rdtsc ;call _rdtsc |
190 | mov [edi+TASKDATA.counter_add],eax |
190 | mov [edi+TASKDATA.counter_add],eax |
191 | 191 | ||
192 | mov esi, [prev_slot] |
192 | mov esi, [prev_slot] |
193 | xor eax, eax |
193 | xor eax, eax |
194 | cmp ebx, esi |
194 | cmp ebx, esi |
195 | sete al |
195 | sete al |
196 | ret |
196 | ret |
197 | 197 | ||
198 | ; param |
198 | ; param |
199 | ; ebx = incoming task |
199 | ; ebx = incoming task |
200 | ; esi = outcomig task |
200 | ; esi = outcomig task |
201 | 201 | ||
202 | do_change_task: |
202 | do_change_task: |
203 | 203 | ||
204 | shl ebx, 8 |
204 | shl ebx, 8 |
205 | add ebx, SLOT_BASE |
205 | add ebx, SLOT_BASE |
206 | mov [current_slot], ebx |
206 | mov [current_slot], ebx |
207 | 207 | ||
208 | shl esi, 8 |
208 | shl esi, 8 |
209 | add esi, SLOT_BASE |
209 | add esi, SLOT_BASE |
210 | 210 | ||
211 | mov [esi+APPDATA.saved_esp], esp |
211 | mov [esi+APPDATA.saved_esp], esp |
212 | mov esp, [ebx+APPDATA.saved_esp] |
212 | mov esp, [ebx+APPDATA.saved_esp] |
213 | 213 | ||
214 | ; set thread io map |
214 | ; set thread io map |
215 | 215 | ||
216 | mov ecx, [ebx+APPDATA.io_map] |
216 | ; mov ecx, [ebx+APPDATA.io_map] |
217 | mov edx, [ebx+APPDATA.io_map+4] |
217 | ; mov edx, [ebx+APPDATA.io_map+4] |
218 | mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx |
218 | ; mov dword [page_tabs+((tss._io_map_0 and -4096) shr 10)], ecx |
219 | mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx |
219 | ; mov dword [page_tabs+((tss._io_map_1 and -4096) shr 10)], edx |
220 | 220 | ||
221 | mov eax, [ebx+APPDATA.dir_table] |
221 | mov eax, [ebx+APPDATA.dir_table] |
222 | cmp eax, [esi+APPDATA.dir_table] |
222 | cmp eax, [esi+APPDATA.dir_table] |
223 | je @F |
223 | je @F |
224 | mov cr3, eax |
224 | mov cr3, eax |
225 | @@: |
225 | @@: |
226 | mov eax, [ebx+APPDATA.saved_esp0] |
226 | mov eax, [ebx+APPDATA.saved_esp0] |
227 | mov [tss._esp0], eax |
227 | mov [tss._esp0], eax |
228 | mov ax, graph_data |
228 | mov ax, graph_data |
229 | mov gs, ax |
229 | mov gs, ax |
230 | 230 | ||
231 | mov eax, [CURRENT_TASK] |
231 | mov eax, [CURRENT_TASK] |
232 | cmp eax, [fpu_owner] |
232 | cmp eax, [fpu_owner] |
233 | clts ;clear a task switch flag |
233 | clts ;clear a task switch flag |
234 | je @F |
234 | je @F |
235 | ;and set it again if the owner |
235 | ;and set it again if the owner |
236 | mov ecx, cr0 ;of a fpu has changed |
236 | mov ecx, cr0 ;of a fpu has changed |
237 | or ecx, CR0_TS |
237 | or ecx, CR0_TS |
238 | mov cr0, ecx |
238 | mov cr0, ecx |
239 | @@: |
239 | @@: |
240 | inc [context_counter] ;noname & halyavin |
240 | inc [context_counter] ;noname & halyavin |
241 | test [ebx+APPDATA.dbg_state], 1 |
241 | test [ebx+APPDATA.dbg_state], 1 |
242 | jnz @F |
242 | jnz @F |
243 | ret |
243 | ret |
244 | @@: |
244 | @@: |
245 | mov eax, [ebx+APPDATA.dbg_regs.dr0] |
245 | mov eax, [ebx+APPDATA.dbg_regs.dr0] |
246 | mov dr0, eax |
246 | mov dr0, eax |
247 | mov eax, [ebx+APPDATA.dbg_regs.dr1] |
247 | mov eax, [ebx+APPDATA.dbg_regs.dr1] |
248 | mov dr1, eax |
248 | mov dr1, eax |
249 | mov eax, [ebx+APPDATA.dbg_regs.dr2] |
249 | mov eax, [ebx+APPDATA.dbg_regs.dr2] |
250 | mov dr2, eax |
250 | mov dr2, eax |
251 | mov eax, [ebx+APPDATA.dbg_regs.dr3] |
251 | mov eax, [ebx+APPDATA.dbg_regs.dr3] |
252 | mov dr3, eax |
252 | mov dr3, eax |
253 | xor eax, eax |
253 | xor eax, eax |
254 | mov dr6, eax |
254 | mov dr6, eax |
255 | mov eax, [ebx+APPDATA.dbg_regs.dr7] |
255 | mov eax, [ebx+APPDATA.dbg_regs.dr7] |
256 | mov dr7, eax |
256 | mov dr7, eax |
257 | ret |
257 | ret |
258 | 258 | ||
259 | align 4 |
259 | align 4 |
260 | updatecputimes: |
260 | updatecputimes: |
261 | 261 | ||
262 | mov eax,[idleuse] |
262 | mov eax,[idleuse] |
263 | mov [idleusesec],eax |
263 | mov [idleusesec],eax |
264 | mov [idleuse],dword 0 |
264 | mov [idleuse],dword 0 |
265 | mov ecx, [TASK_COUNT] |
265 | mov ecx, [TASK_COUNT] |
266 | mov edi, TASK_DATA |
266 | mov edi, TASK_DATA |
267 | .newupdate: |
267 | .newupdate: |
268 | mov ebx,[edi+TASKDATA.counter_sum] |
268 | mov ebx,[edi+TASKDATA.counter_sum] |
269 | mov [edi+TASKDATA.cpu_usage],ebx |
269 | mov [edi+TASKDATA.cpu_usage],ebx |
270 | mov [edi+TASKDATA.counter_sum],dword 0 |
270 | mov [edi+TASKDATA.counter_sum],dword 0 |
271 | add edi,0x20 |
271 | add edi,0x20 |
272 | dec ecx |
272 | dec ecx |
273 | jnz .newupdate |
273 | jnz .newupdate |
274 | 274 | ||
275 | ret |
275 | ret |
276 | 276 | ||
277 | if 0 |
277 | if 0 |
278 | 278 | ||
279 | 279 | ||
280 | struc TIMER |
280 | struc TIMER |
281 | { |
281 | { |
282 | .next dd ? |
282 | .next dd ? |
283 | .exp_time dd ? |
283 | .exp_time dd ? |
284 | .func dd ? |
284 | .func dd ? |
285 | .arg dd ? |
285 | .arg dd ? |
286 | } |
286 | } |
287 | 287 | ||
288 | 288 | ||
289 | 289 | ||
290 | 290 | ||
291 | 291 | ||
292 | 292 | ||
293 | 293 | ||
294 | 294 | ||
295 | 295 | ||
296 | MAX_PROIRITY 0 ; highest, used for kernel tasks |
296 | MAX_PROIRITY 0 ; highest, used for kernel tasks |
297 | MAX_USER_PRIORITY 0 ; highest priority for user processes |
297 | MAX_USER_PRIORITY 0 ; highest priority for user processes |
298 | USER_PRIORITY 7 ; default (should correspond to nice 0) |
298 | USER_PRIORITY 7 ; default (should correspond to nice 0) |
299 | MIN_USER_PRIORITY 14 ; minimum priority for user processes |
299 | MIN_USER_PRIORITY 14 ; minimum priority for user processes |
300 | IDLE_PRIORITY 15 ; lowest, only IDLE process goes here |
300 | IDLE_PRIORITY 15 ; lowest, only IDLE process goes here |
301 | NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1 |
301 | NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1 |
302 | 302 | ||
303 | rdy_head rd 16 |
303 | rdy_head rd 16 |
304 | 304 | ||
305 | 305 | ||
306 | align 4 |
306 | align 4 |
307 | pick_task: |
307 | pick_task: |
308 | 308 | ||
309 | xor eax, eax |
309 | xor eax, eax |
310 | .pick: |
310 | .pick: |
311 | mov ebx, [rdy_head+eax*4] |
311 | mov ebx, [rdy_head+eax*4] |
312 | test ebx, ebx |
312 | test ebx, ebx |
313 | jz .next |
313 | jz .next |
314 | 314 | ||
315 | mov [next_task], ebx |
315 | mov [next_task], ebx |
316 | test [ebx+flags.billable] |
316 | test [ebx+flags.billable] |
317 | jz @F |
317 | jz @F |
318 | mov [bill_task], ebx |
318 | mov [bill_task], ebx |
319 | @@: |
319 | @@: |
320 | ret |
320 | ret |
321 | .next: |
321 | .next: |
322 | inc eax |
322 | inc eax |
323 | jmp .pick |
323 | jmp .pick |
324 | 324 | ||
325 | 325 | ||
326 | ; param |
326 | ; param |
327 | ; eax= task |
327 | ; eax= task |
328 | ; |
328 | ; |
329 | ; retval |
329 | ; retval |
330 | ; eax= task |
330 | ; eax= task |
331 | ; ebx= queue |
331 | ; ebx= queue |
332 | ; ecx= front if 1 or back if 0 |
332 | ; ecx= front if 1 or back if 0 |
333 | 333 | ||
334 | align 4 |
334 | align 4 |
335 | shed: |
335 | shed: |
336 | cmp [eax+.tics_left], 0 ;signed compare |
336 | cmp [eax+.tics_left], 0 ;signed compare |
337 | mov ebx, [eax+.priority] |
337 | mov ebx, [eax+.priority] |
338 | setg ecx |
338 | setg ecx |
339 | jg @F |
339 | jg @F |
340 | 340 | ||
341 | mov edx, [eax+.tics_quantum] |
341 | mov edx, [eax+.tics_quantum] |
342 | mov [eax+.ticks_left], edx |
342 | mov [eax+.ticks_left], edx |
343 | cmp ebx, (IDLE_PRIORITY-1) |
343 | cmp ebx, (IDLE_PRIORITY-1) |
344 | je @F |
344 | je @F |
345 | inc ebx |
345 | inc ebx |
346 | @@: |
346 | @@: |
347 | ret |
347 | ret |
348 | 348 | ||
349 | ; param |
349 | ; param |
350 | ; eax= task |
350 | ; eax= task |
351 | 351 | ||
352 | align 4 |
352 | align 4 |
353 | enqueue: |
353 | enqueue: |
354 | call shed ;eax |
354 | call shed ;eax |
355 | cmp [rdy_head+ebx*4],0 |
355 | cmp [rdy_head+ebx*4],0 |
356 | jnz @F |
356 | jnz @F |
357 | 357 | ||
358 | mov [rdy_head+ebx*4], eax |
358 | mov [rdy_head+ebx*4], eax |
359 | mov [rdy_tail+ebx*4], eax |
359 | mov [rdy_tail+ebx*4], eax |
360 | mov [eax+.next_ready], 0 |
360 | mov [eax+.next_ready], 0 |
361 | jmp .pick |
361 | jmp .pick |
362 | @@: |
362 | @@: |
363 | test ecx, ecx |
363 | test ecx, ecx |
364 | jz .back |
364 | jz .back |
365 | 365 | ||
366 | mov ecx, [rdy_head+ebx*4] |
366 | mov ecx, [rdy_head+ebx*4] |
367 | mov [eax+.next_ready], ecx |
367 | mov [eax+.next_ready], ecx |
368 | mov [rdy_head+ebx*4], eax |
368 | mov [rdy_head+ebx*4], eax |
369 | jmp .pick |
369 | jmp .pick |
370 | .back: |
370 | .back: |
371 | mov ecx, [rdy_tail+ebx*4] |
371 | mov ecx, [rdy_tail+ebx*4] |
372 | mov [ecx+.next_ready], eax |
372 | mov [ecx+.next_ready], eax |
373 | mov [rdy_tail+ebx*4], eax |
373 | mov [rdy_tail+ebx*4], eax |
374 | mov [eax+.next_ready], 0 |
374 | mov [eax+.next_ready], 0 |
375 | .pick: |
375 | .pick: |
376 | call pick_proc ;select next task |
376 | call pick_proc ;select next task |
377 | ret |
377 | ret |
378 | 378 | ||
379 | end if---><---><<---> |
379 | end if---><---><<---> |