Rev 2465 | Rev 3626 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 2465 | Rev 3555 | ||
---|---|---|---|
Line 3... | Line 3... | ||
3 | ;; Copyright (C) KolibriOS team 2004-2012. All rights reserved. ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2012. 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 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 7... | Line 7... | ||
7 | 7 | ||
Line 8... | Line 8... | ||
8 | $Revision: 2465 $ |
8 | $Revision: 3555 $ |
9 | 9 | ||
10 | 10 | ||
Line 27... | Line 27... | ||
27 | add [next_usage_update], 100 |
27 | add [next_usage_update], 100 |
28 | call updatecputimes |
28 | call updatecputimes |
29 | .nocounter: |
29 | .nocounter: |
30 | xor ecx, ecx ; send End Of Interrupt signal |
30 | xor ecx, ecx ; send End Of Interrupt signal |
31 | call irq_eoi |
31 | call irq_eoi |
32 | btr dword[DONT_SWITCH], 0 |
32 | ; btr dword[DONT_SWITCH], 0 |
33 | jc .return |
33 | ; jc .return |
34 | call find_next_task |
34 | call find_next_task |
35 | jz .return ; if there is only one running process |
35 | jz .return ; if there is only one running process |
36 | call do_change_task |
36 | call do_change_task |
37 | .return: |
37 | .return: |
38 | popad |
38 | popad |
Line 59... | Line 59... | ||
59 | ; \end{Mario79} |
59 | ; \end{Mario79} |
60 | end if |
60 | end if |
61 | call find_next_task |
61 | call find_next_task |
62 | jz .return ; the same task -> skip switch |
62 | jz .return ; the same task -> skip switch |
63 | @@: |
63 | @@: |
64 | mov byte[DONT_SWITCH], 1 |
64 | ; mov byte[DONT_SWITCH], 1 |
65 | call do_change_task |
65 | call do_change_task |
66 | .return: |
66 | .return: |
67 | popad |
67 | popad |
68 | popfd |
68 | popfd |
69 | ret |
69 | ret |
Line 87... | Line 87... | ||
87 | sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add |
87 | sub eax, [edi+TASKDATA.counter_add] ; time stamp counter add |
88 | add [edi+TASKDATA.counter_sum], eax ; counter sum |
88 | add [edi+TASKDATA.counter_sum], eax ; counter sum |
89 | ret |
89 | ret |
90 | align 4 |
90 | align 4 |
91 | updatecputimes: |
91 | updatecputimes: |
92 | xor eax, eax |
- | |
93 | xchg eax, [idleuse] |
- | |
94 | mov [idleusesec], eax |
- | |
95 | mov ecx, [TASK_COUNT] |
92 | mov ecx, [TASK_COUNT] |
96 | mov edi, TASK_DATA |
93 | mov edi, TASK_DATA |
97 | .newupdate: |
94 | .newupdate: |
98 | xor eax, eax |
95 | xor eax, eax |
99 | xchg eax, [edi+TASKDATA.counter_sum] |
96 | xchg eax, [edi+TASKDATA.counter_sum] |
100 | mov [edi+TASKDATA.cpu_usage], eax |
97 | mov [edi+TASKDATA.cpu_usage], eax |
101 | add edi, 0x20 |
98 | add edi, 0x20 |
102 | loop .newupdate |
99 | loop .newupdate |
103 | ret |
100 | ret |
Line 104... | Line -... | ||
104 | - | ||
105 | align 4 |
- | |
106 | find_next_task: |
- | |
107 | ;info: |
- | |
108 | ; Find next task to execute |
- | |
109 | ;retval: |
- | |
110 | ; ebx = address of the APPDATA for the selected task (slot-base) |
- | |
111 | ; esi = previous slot-base ([current_slot] at the begin) |
- | |
112 | ; edi = address of the TASKDATA for the selected task |
- | |
113 | ; ZF = 1 if the task is the same |
- | |
114 | ;warning: |
- | |
115 | ; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result |
- | |
116 | ; [current_slot] is not set to new value (ebx)!!! |
- | |
117 | ;scratched: eax,ecx |
- | |
118 | call update_counters ; edi := [TASK_BASE] |
- | |
119 | Mov esi, ebx, [current_slot] |
- | |
120 | .loop: |
- | |
121 | cmp bh, [TASK_COUNT] |
- | |
122 | jb @f |
- | |
123 | xor bh, bh |
- | |
124 | mov edi, CURRENT_TASK |
- | |
125 | @@: |
- | |
126 | inc bh ; ebx += APPDATA.size |
- | |
127 | add edi, 0x20; edi += TASKDATA.size |
- | |
128 | mov al, [edi+TASKDATA.state] |
- | |
129 | test al, al |
- | |
130 | jz .found ; state == 0 |
- | |
131 | cmp al, 5 |
- | |
132 | jne .loop ; state == 1,2,3,4,9 |
- | |
133 | ; state == 5 |
- | |
134 | pushad ; more freedom for [APPDATA.wait_test] |
- | |
135 | call [ebx+APPDATA.wait_test] |
- | |
136 | mov [esp+28], eax |
- | |
137 | popad |
- | |
138 | or eax, eax |
- | |
139 | jnz @f |
- | |
140 | ; testing for timeout |
- | |
141 | mov ecx, [timer_ticks] |
- | |
142 | sub ecx, [ebx+APPDATA.wait_begin] |
- | |
143 | cmp ecx, [ebx+APPDATA.wait_timeout] |
- | |
144 | jb .loop |
- | |
145 | @@: |
- | |
146 | mov [ebx+APPDATA.wait_param], eax ; retval for wait |
- | |
147 | mov [edi+TASKDATA.state], 0 |
- | |
148 | .found: |
- | |
149 | mov [CURRENT_TASK], bh |
- | |
150 | mov [TASK_BASE], edi |
- | |
151 | rdtsc ;call _rdtsc |
- | |
152 | mov [edi+TASKDATA.counter_add], eax; for next using update_counters |
- | |
153 | cmp ebx, esi ;esi - previous slot-base |
- | |
154 | ret |
101 | |
155 | ;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86... |
102 | ;TODO: Надо бы убрать использование do_change_task из V86... |
Line 156... | Line 103... | ||
156 | ; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task |
103 | ; и после этого перенести обработку TASKDATA.counter_add/sum в do_change_task |
157 | 104 | ||
158 | align 4 |
105 | align 4 |
159 | do_change_task: |
106 | do_change_task: |
Line 303... | Line 250... | ||
303 | ret |
250 | ret |
Line 304... | Line 251... | ||
304 | 251 | ||
Line -... | Line 252... | ||
- | 252 | ||
- | 253 | purge MUTEX_WAITER |
|
- | 254 | ||
- | 255 | MAX_PRIORITY = 0 ; highest, used for kernel tasks |
|
- | 256 | USER_PRIORITY = 1 ; default |
|
- | 257 | IDLE_PRIORITY = 2 ; lowest, only IDLE thread goes here |
|
- | 258 | NR_SCHED_QUEUES = 3 ; MUST equal IDLE_PRIORYTY + 1 |
|
- | 259 | ||
- | 260 | uglobal |
|
- | 261 | ; [scheduler_current + i*4] = zero if there are no threads with priority i, |
|
- | 262 | ; pointer to APPDATA of the current thread with priority i otherwise. |
|
- | 263 | align 4 |
|
- | 264 | scheduler_current rd NR_SCHED_QUEUES |
|
- | 265 | endg |
|
- | 266 | ||
- | 267 | ; Add the given thread to the given priority list for the scheduler. |
|
- | 268 | ; in: edx -> APPDATA, ecx = priority |
|
- | 269 | proc scheduler_add_thread |
|
- | 270 | ; 1. Acquire the lock. |
|
- | 271 | spin_lock_irqsave SchedulerLock |
|
- | 272 | ; 2. Store the priority in APPDATA structure. |
|
- | 273 | mov [edx+APPDATA.priority], ecx |
|
- | 274 | ; 3. There are two different cases: the given list is empty or not empty. |
|
- | 275 | ; In first case, go to 6. Otherwise, advance to 4. |
|
- | 276 | mov eax, [scheduler_current+ecx*4] |
|
- | 277 | test eax, eax |
|
- | 278 | jz .new_list |
|
- | 279 | ; 4. Insert the new item immediately before the current item. |
|
- | 280 | mov ecx, [eax+APPDATA.in_schedule.prev] |
|
- | 281 | mov [edx+APPDATA.in_schedule.next], eax |
|
- | 282 | mov [edx+APPDATA.in_schedule.prev], ecx |
|
- | 283 | mov [eax+APPDATA.in_schedule.prev], edx |
|
- | 284 | mov [ecx+APPDATA.in_schedule.next], edx |
|
- | 285 | ; 5. Release the lock and return. |
|
- | 286 | spin_unlock_irqrestore SchedulerLock |
|
- | 287 | ret |
|
- | 288 | .new_list: |
|
- | 289 | ; 6. Initialize the list with one item and make it the current item. |
|
- | 290 | mov [edx+APPDATA.in_schedule.next], edx |
|
- | 291 | mov [edx+APPDATA.in_schedule.prev], edx |
|
- | 292 | mov [scheduler_current+ecx*4], edx |
|
- | 293 | ; 7. Release the lock and return. |
|
- | 294 | spin_unlock_irqrestore SchedulerLock |
|
- | 295 | ret |
|
- | 296 | endp |
|
- | 297 | ||
- | 298 | ; Remove the given thread from the corresponding priority list for the scheduler. |
|
- | 299 | ; in: edx -> APPDATA |
|
- | 300 | proc scheduler_remove_thread |
|
- | 301 | ; 1. Acquire the lock. |
|
- | 302 | spin_lock_irqsave SchedulerLock |
|
- | 303 | ; 2. Remove the item from the corresponding list. |
|
- | 304 | mov eax, [edx+APPDATA.in_schedule.next] |
|
- | 305 | mov ecx, [edx+APPDATA.in_schedule.prev] |
|
- | 306 | mov [eax+APPDATA.in_schedule.prev], ecx |
|
- | 307 | mov [ecx+APPDATA.in_schedule.next], eax |
|
- | 308 | ; 3. If the given thread is the current item in the list, |
|
- | 309 | ; advance the current item. |
|
- | 310 | ; 3a. Check whether the given thread is the current item; |
|
- | 311 | ; if no, skip the rest of this step. |
|
- | 312 | mov ecx, [edx+APPDATA.priority] |
|
- | 313 | cmp [scheduler_current+ecx*4], edx |
|
- | 314 | jnz .return |
|
- | 315 | ; 3b. Set the current item to eax; step 2 has set eax = next item. |
|
- | 316 | mov [scheduler_current+ecx*4], eax |
|
- | 317 | ; 3c. If there were only one item in the list, zero the current item. |
|
- | 318 | cmp eax, edx |
|
- | 319 | jnz .return |
|
- | 320 | mov [scheduler_current+ecx*4], 0 |
|
- | 321 | .return: |
|
- | 322 | ; 4. Release the lock and return. |
|
- | 323 | spin_unlock_irqrestore SchedulerLock |
|
- | 324 | ret |
|
- | 325 | endp |
|
- | 326 | ||
- | 327 | ;info: |
|
- | 328 | ; Find next task to execute |
|
- | 329 | ;retval: |
|
- | 330 | ; ebx = address of the APPDATA for the selected task (slot-base) |
|
- | 331 | ; edi = address of the TASKDATA for the selected task |
|
- | 332 | ; ZF = 1 if the task is the same |
|
- | 333 | ;warning: |
|
- | 334 | ; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result |
|
- | 335 | ; [current_slot] is not set to new value (ebx)!!! |
|
- | 336 | ;scratched: eax,ecx |
|
- | 337 | proc find_next_task |
|
- | 338 | call update_counters |
|
- | 339 | spin_lock_irqsave SchedulerLock |
|
- | 340 | xor ecx, ecx |
|
- | 341 | .priority_loop: |
|
- | 342 | mov ebx, [scheduler_current+ecx*4] |
|
- | 343 | test ebx, ebx |
|
- | 344 | jz .priority_next |
|
- | 345 | .task_loop: |
|
- | 346 | mov ebx, [ebx+APPDATA.in_schedule.next] |
|
- | 347 | mov edi, ebx |
|
- | 348 | shr edi, 3 |
|
- | 349 | add edi, CURRENT_TASK - (SLOT_BASE shr 3) |
|
- | 350 | mov al, [edi+TASKDATA.state] |
|
- | 351 | test al, al |
|
- | 352 | jz .task_found ; state == 0 |
|
- | 353 | cmp al, 5 |
|
- | 354 | jne .task_next ; state == 1,2,3,4,9 |
|
- | 355 | ; state == 5 |
|
- | 356 | pushad ; more freedom for [APPDATA.wait_test] |
|
- | 357 | call [ebx+APPDATA.wait_test] |
|
- | 358 | mov [esp+28], eax |
|
- | 359 | popad |
|
- | 360 | or eax, eax |
|
- | 361 | jnz @f |
|
- | 362 | ; testing for timeout |
|
- | 363 | mov eax, [timer_ticks] |
|
- | 364 | sub eax, [ebx+APPDATA.wait_begin] |
|
- | 365 | cmp eax, [ebx+APPDATA.wait_timeout] |
|
- | 366 | jb .task_next |
|
- | 367 | xor eax, eax |
|
- | 368 | @@: |
|
- | 369 | mov [ebx+APPDATA.wait_param], eax ; retval for wait |
|
- | 370 | mov [edi+TASKDATA.state], 0 |
|
- | 371 | .task_found: |
|
- | 372 | mov [scheduler_current+ecx*4], ebx |
|
- | 373 | spin_unlock_irqrestore SchedulerLock |
|
- | 374 | .found: |
|
- | 375 | mov [CURRENT_TASK], bh |
|
- | 376 | mov [TASK_BASE], edi |
|
- | 377 | rdtsc ;call _rdtsc |
|
- | 378 | mov [edi+TASKDATA.counter_add], eax; for next using update_counters |
|
- | 379 | cmp ebx, [current_slot] |
|
- | 380 | ret |
|
- | 381 | .task_next: |
|
- | 382 | cmp ebx, [scheduler_current+ecx*4] |
|
- | 383 | jnz .task_loop |
|
- | 384 | .priority_next: |
|
- | 385 | inc ecx |
|
- | 386 | cmp ecx, NR_SCHED_QUEUES |
|
- | 387 | jb .priority_loop |
|
- | 388 | hlt |
|
305 | 389 | jmp $-1 |
|
Line 306... | Line 390... | ||
306 | purge MUTEX_WAITER |
390 | endp |
307 | 391 | ||
308 | if 0 |
392 | if 0 |
Line 314... | Line 398... | ||
314 | .func dd ? |
398 | .func dd ? |
315 | .arg dd ? |
399 | .arg dd ? |
316 | } |
400 | } |
Line 317... | Line -... | ||
317 | - | ||
318 | - | ||
319 | MAX_PROIRITY 0 ; highest, used for kernel tasks |
- | |
320 | MAX_USER_PRIORITY 0 ; highest priority for user processes |
- | |
321 | USER_PRIORITY 7 ; default (should correspond to nice 0) |
- | |
322 | MIN_USER_PRIORITY 14 ; minimum priority for user processes |
- | |
323 | IDLE_PRIORITY 15 ; lowest, only IDLE process goes here |
- | |
324 | NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1 |
401 | |
325 | 402 | ||
326 | uglobal |
403 | uglobal |
Line 327... | Line 404... | ||
327 | rdy_head rd 16 |
404 | rdy_head rd 16 |