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