Subversion Repositories Kolibri OS

Rev

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