Subversion Repositories Kolibri OS

Rev

Rev 1635 | Rev 2143 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1635 Rev 1638
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: 1434 $
8
$Revision: 1638 $
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     ds, ax, app_data
19
        Mov     ds, ax, app_data
20
        mov     es, ax
20
        mov     es, ax
21
        inc     [timer_ticks]
21
        inc     [timer_ticks]
22
        mov     eax, [timer_ticks]
22
        mov     eax, [timer_ticks]
23
        call    playNote       ; <<<--- Speaker driver
23
        call    playNote       ; <<<--- Speaker driver
24
        sub     eax,[next_usage_update]
24
        sub     eax,[next_usage_update]
25
        cmp     eax,100
25
        cmp     eax,100
26
        jb      .nocounter
26
        jb      .nocounter
27
        add     [next_usage_update],100
27
        add     [next_usage_update],100
28
        call    updatecputimes
28
        call    updatecputimes
29
  .nocounter:
29
  .nocounter:
30
        mov     al,0x20  ; send End Of Interrupt signal
30
	mov	al, 0	; send End Of Interrupt signal
31
        out     0x20,al
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
39
        iretd
39
        iretd
40
 
40
 
41
align 4
41
align 4
42
change_task:
42
change_task:
43
        pushfd
43
        pushfd
44
        cli
44
        cli
45
        pushad
45
        pushad
46
if 0
46
if 0
47
; \begin{Mario79} ; <- must be refractoried, if used...
47
; \begin{Mario79} ; <- must be refractoried, if used...
48
        cmp     [dma_task_switched], 1
48
        cmp     [dma_task_switched], 1
49
        jne     .find_next_task
49
        jne     .find_next_task
50
        mov     [dma_task_switched], 0
50
        mov     [dma_task_switched], 0
51
        mov     ebx, [dma_process]
51
        mov     ebx, [dma_process]
52
        cmp     [CURRENT_TASK], ebx
52
        cmp     [CURRENT_TASK], ebx
53
        je      .return
53
        je      .return
54
        mov     edi, [dma_slot_ptr]
54
        mov     edi, [dma_slot_ptr]
55
        mov     [CURRENT_TASK], ebx
55
        mov     [CURRENT_TASK], ebx
56
        mov     [TASK_BASE], edi
56
        mov     [TASK_BASE], edi
57
        jmp     @f
57
        jmp     @f
58
.find_next_task:
58
.find_next_task:
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
  @@:   mov     byte[DONT_SWITCH], 1
63
  @@:   mov     byte[DONT_SWITCH], 1
64
        call    do_change_task
64
        call    do_change_task
65
  .return:
65
  .return:
66
        popad
66
        popad
67
        popfd
67
        popfd
68
        ret
68
        ret
69
 
69
 
70
uglobal
70
uglobal
71
align 4
71
align 4
72
;  far_jump:
72
;  far_jump:
73
;   .offs dd ?
73
;   .offs dd ?
74
;   .sel  dw ?
74
;   .sel  dw ?
75
   context_counter     dd 0 ;noname & halyavin
75
   context_counter     dd 0 ;noname & halyavin
76
   next_usage_update   dd 0
76
   next_usage_update   dd 0
77
   timer_ticks         dd 0
77
   timer_ticks         dd 0
78
;  prev_slot           dd ?
78
;  prev_slot           dd ?
79
;  event_sched         dd ?
79
;  event_sched         dd ?
80
endg
80
endg
81
 
81
 
82
align 4
82
align 4
83
update_counters:
83
update_counters:
84
        mov     edi, [TASK_BASE]
84
        mov     edi, [TASK_BASE]
85
        rdtsc
85
        rdtsc
86
        sub     eax, [edi+TASKDATA.counter_add] ; time stamp counter add
86
        sub     eax, [edi+TASKDATA.counter_add] ; time stamp counter add
87
        add     [edi+TASKDATA.counter_sum], eax ; counter sum
87
        add     [edi+TASKDATA.counter_sum], eax ; counter sum
88
        ret
88
        ret
89
align 4
89
align 4
90
updatecputimes:
90
updatecputimes:
91
        xor     eax,eax
91
        xor     eax,eax
92
        xchg    eax,[idleuse]
92
        xchg    eax,[idleuse]
93
        mov     [idleusesec],eax
93
        mov     [idleusesec],eax
94
        mov     ecx, [TASK_COUNT]
94
        mov     ecx, [TASK_COUNT]
95
        mov     edi, TASK_DATA
95
        mov     edi, TASK_DATA
96
  .newupdate:
96
  .newupdate:
97
        xor     eax,eax
97
        xor     eax,eax
98
        xchg    eax,[edi+TASKDATA.counter_sum]
98
        xchg    eax,[edi+TASKDATA.counter_sum]
99
        mov     [edi+TASKDATA.cpu_usage],eax
99
        mov     [edi+TASKDATA.cpu_usage],eax
100
        add     edi,0x20
100
        add     edi,0x20
101
        loop    .newupdate
101
        loop    .newupdate
102
        ret
102
        ret
103
 
103
 
104
align 4
104
align 4
105
find_next_task:
105
find_next_task:
106
;info:
106
;info:
107
;   Find next task to execute
107
;   Find next task to execute
108
;retval:
108
;retval:
109
;   ebx = address of the APPDATA for the selected task (slot-base)
109
;   ebx = address of the APPDATA for the selected task (slot-base)
110
;   esi = previous slot-base ([current_slot] at the begin)
110
;   esi = previous slot-base ([current_slot] at the begin)
111
;   edi = address of the TASKDATA for the selected task
111
;   edi = address of the TASKDATA for the selected task
112
;   ZF  = 1  if the task is the same
112
;   ZF  = 1  if the task is the same
113
;warning:
113
;warning:
114
;   [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
114
;   [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result
115
;   [current_slot] is not set to new value (ebx)!!!
115
;   [current_slot] is not set to new value (ebx)!!!
116
;scratched: eax,ecx
116
;scratched: eax,ecx
117
        call    update_counters ; edi := [TASK_BASE]
117
        call    update_counters ; edi := [TASK_BASE]
118
        Mov     esi, ebx, [current_slot]
118
        Mov     esi, ebx, [current_slot]
119
  .loop:
119
  .loop:
120
        cmp     bh,[TASK_COUNT]
120
        cmp     bh,[TASK_COUNT]
121
        jb      @f
121
        jb      @f
122
        xor     bh, bh
122
        xor     bh, bh
123
        mov     edi,CURRENT_TASK
123
        mov     edi,CURRENT_TASK
124
  @@:   inc     bh       ; ebx += APPDATA.size
124
  @@:   inc     bh       ; ebx += APPDATA.size
125
        add     edi,0x20 ; edi += TASKDATA.size
125
        add     edi,0x20 ; edi += TASKDATA.size
126
        mov     al, [edi+TASKDATA.state]
126
        mov     al, [edi+TASKDATA.state]
127
        test    al, al
127
        test    al, al
128
        jz      .found   ; state == 0
128
        jz      .found   ; state == 0
129
        cmp     al, 5
129
        cmp     al, 5
130
        jne     .loop    ; state == 1,2,3,4,9
130
        jne     .loop    ; state == 1,2,3,4,9
131
      ; state == 5
131
      ; state == 5
132
        pushad  ; more freedom for [APPDATA.wait_test]
132
        pushad  ; more freedom for [APPDATA.wait_test]
133
        call    [ebx+APPDATA.wait_test]
133
        call    [ebx+APPDATA.wait_test]
134
        mov     [esp+28],eax
134
        mov     [esp+28],eax
135
        popad
135
        popad
136
        or      eax,eax
136
        or      eax,eax
137
        jnz     @f
137
        jnz     @f
138
      ; testing for timeout
138
      ; testing for timeout
139
        mov     ecx, [timer_ticks]
139
        mov     ecx, [timer_ticks]
140
        sub     ecx, [ebx+APPDATA.wait_begin]
140
        sub     ecx, [ebx+APPDATA.wait_begin]
141
        cmp     ecx, [ebx+APPDATA.wait_timeout]
141
        cmp     ecx, [ebx+APPDATA.wait_timeout]
142
        jb      .loop
142
        jb      .loop
143
  @@:   mov     [ebx+APPDATA.wait_param], eax  ; retval for wait
143
  @@:   mov     [ebx+APPDATA.wait_param], eax  ; retval for wait
144
        mov     [edi+TASKDATA.state], 0
144
        mov     [edi+TASKDATA.state], 0
145
  .found:
145
  .found:
146
        mov     [CURRENT_TASK],bh
146
        mov     [CURRENT_TASK],bh
147
        mov     [TASK_BASE],edi
147
        mov     [TASK_BASE],edi
148
        rdtsc   ;call  _rdtsc
148
        rdtsc   ;call  _rdtsc
149
        mov     [edi+TASKDATA.counter_add],eax ; for next using update_counters
149
        mov     [edi+TASKDATA.counter_add],eax ; for next using update_counters
150
        cmp     ebx, esi ;esi - previous slot-base
150
        cmp     ebx, esi ;esi - previous slot-base
151
        ret
151
        ret
152
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
152
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86...
153
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task
153
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task
154
 
154
 
155
align 4
155
align 4
156
do_change_task:
156
do_change_task:
157
;param:
157
;param:
158
;   ebx = address of the APPDATA for incoming task (new)
158
;   ebx = address of the APPDATA for incoming task (new)
159
;warning:
159
;warning:
160
;   [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
160
;   [CURRENT_TASK] and [TASK_BASE] must be changed before (e.g. in find_next_task)
161
;   [current_slot] is the outcoming (old), and set here to a new value (ebx)
161
;   [current_slot] is the outcoming (old), and set here to a new value (ebx)
162
;scratched: eax,ecx,esi
162
;scratched: eax,ecx,esi
163
        mov     esi,ebx
163
        mov     esi,ebx
164
        xchg    esi,[current_slot]
164
        xchg    esi,[current_slot]
165
; set new stack after saving old
165
; set new stack after saving old
166
        mov     [esi+APPDATA.saved_esp], esp
166
        mov     [esi+APPDATA.saved_esp], esp
167
        mov     esp, [ebx+APPDATA.saved_esp]
167
        mov     esp, [ebx+APPDATA.saved_esp]
168
; set new thread io-map
168
; set new thread io-map
169
        Mov     dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
169
        Mov     dword [page_tabs+((tss._io_map_0 and -4096) shr 10)],eax,[ebx+APPDATA.io_map]
170
        Mov     dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
170
        Mov     dword [page_tabs+((tss._io_map_1 and -4096) shr 10)],eax,[ebx+APPDATA.io_map+4]
171
; set new thread memory-map
171
; set new thread memory-map
172
        mov     ecx, APPDATA.dir_table
172
        mov     ecx, APPDATA.dir_table
173
        mov     eax, [ebx+ecx]      ;offset>0x7F
173
        mov     eax, [ebx+ecx]      ;offset>0x7F
174
        cmp     eax, [esi+ecx]      ;offset>0x7F
174
        cmp     eax, [esi+ecx]      ;offset>0x7F
175
        je      @f
175
        je      @f
176
        mov     cr3, eax
176
        mov     cr3, eax
177
@@:
177
@@:
178
; set tss.esp0
178
; set tss.esp0
179
 
179
 
180
        Mov     [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
180
        Mov     [tss._esp0],eax,[ebx+APPDATA.saved_esp0]
181
 
181
 
182
        mov edx, [ebx+APPDATA.tls_base]
182
        mov edx, [ebx+APPDATA.tls_base]
183
        cmp edx, [esi+APPDATA.tls_base]
183
        cmp edx, [esi+APPDATA.tls_base]
184
        je @f
184
        je @f
185
 
185
 
186
        mov     [tls_data_l+2],dx
186
        mov     [tls_data_l+2],dx
187
        shr     edx,16
187
        shr     edx,16
188
        mov     [tls_data_l+4],dl
188
        mov     [tls_data_l+4],dl
189
        mov     [tls_data_l+7],dh
189
        mov     [tls_data_l+7],dh
190
 
190
 
191
        mov dx, app_tls
191
        mov dx, app_tls
192
        mov fs, dx
192
        mov fs, dx
193
@@:
193
@@:
194
; set gs selector unconditionally
194
; set gs selector unconditionally
195
        Mov     gs,ax,graph_data
195
        Mov     gs,ax,graph_data
196
      ; set CR0.TS
196
      ; set CR0.TS
197
        cmp     bh, byte[fpu_owner] ;bh == incoming task (new)
197
        cmp     bh, byte[fpu_owner] ;bh == incoming task (new)
198
        clts                        ;clear a task switch flag
198
        clts                        ;clear a task switch flag
199
        je      @f
199
        je      @f
200
        mov     eax, cr0            ;and set it again if the owner
200
        mov     eax, cr0            ;and set it again if the owner
201
        or      eax, CR0_TS         ;of a fpu has changed
201
        or      eax, CR0_TS         ;of a fpu has changed
202
        mov     cr0, eax
202
        mov     cr0, eax
203
  @@: ; set context_counter (only for user pleasure ???)
203
  @@: ; set context_counter (only for user pleasure ???)
204
        inc     [context_counter]   ;noname & halyavin
204
        inc     [context_counter]   ;noname & halyavin
205
      ; set debug-registers, if it's necessary
205
      ; set debug-registers, if it's necessary
206
        test    byte[ebx+APPDATA.dbg_state], 1
206
        test    byte[ebx+APPDATA.dbg_state], 1
207
        jz      @f
207
        jz      @f
208
        xor     eax, eax
208
        xor     eax, eax
209
        mov     dr6, eax
209
        mov     dr6, eax
210
        lea     esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
210
        lea     esi,[ebx+ecx+APPDATA.dbg_regs-APPDATA.dir_table] ;offset>0x7F
211
        cld
211
        cld
212
  macro lodsReg [reg] {
212
  macro lodsReg [reg] {
213
        lodsd
213
        lodsd
214
        mov     reg,eax
214
        mov     reg,eax
215
  }     lodsReg dr0, dr1, dr2, dr3, dr7
215
  }     lodsReg dr0, dr1, dr2, dr3, dr7
216
  purge lodsReg
216
  purge lodsReg
217
  @@:   ret
217
  @@:   ret
218
;end.
218
;end.
219
 
219
 
220
 
220
 
221
 
221
 
222
struc MUTEX_WAITER
222
struc MUTEX_WAITER
223
{
223
{
224
    .next   rd 1
224
    .next   rd 1
225
    .prev   rd 1
225
    .prev   rd 1
226
    .task   rd 1
226
    .task   rd 1
227
    .sizeof:
227
    .sizeof:
228
};
228
};
229
 
229
 
230
virtual at 0
230
virtual at 0
231
 MUTEX_WAITER MUTEX_WAITER
231
 MUTEX_WAITER MUTEX_WAITER
232
end virtual
232
end virtual
233
 
233
 
234
;void  __fastcall mutex_init(struct mutex *lock)
234
;void  __fastcall mutex_init(struct mutex *lock)
235
 
235
 
236
align 4
236
align 4
237
mutex_init:
237
mutex_init:
238
        lea eax, [ecx+MUTEX.next]
238
        lea eax, [ecx+MUTEX.next]
239
        mov [ecx+MUTEX.count],1
239
        mov [ecx+MUTEX.count],1
240
        mov [ecx+MUTEX.next], eax
240
        mov [ecx+MUTEX.next], eax
241
        mov [ecx+MUTEX.prev], eax
241
        mov [ecx+MUTEX.prev], eax
242
        ret
242
        ret
243
 
243
 
244
 
244
 
245
;void  __fastcall mutex_lock(struct mutex *lock)
245
;void  __fastcall mutex_lock(struct mutex *lock)
246
 
246
 
247
align 4
247
align 4
248
mutex_lock:
248
mutex_lock:
249
 
249
 
250
        dec [ecx+MUTEX.count]
250
        dec [ecx+MUTEX.count]
251
        jns .done
251
        jns .done
252
 
252
 
253
        pushfd
253
        pushfd
254
        cli
254
        cli
255
 
255
 
256
        push esi
256
        push esi
257
        sub esp, MUTEX_WAITER.sizeof
257
        sub esp, MUTEX_WAITER.sizeof
258
 
258
 
259
        mov eax, [ecx+MUTEX.prev]
259
        mov eax, [ecx+MUTEX.prev]
260
        lea esi, [ecx+MUTEX.next]
260
        lea esi, [ecx+MUTEX.next]
261
 
261
 
262
        mov [ecx+MUTEX.prev], esp
262
        mov [ecx+MUTEX.prev], esp
263
        mov [esp+MUTEX_WAITER.next],  esi
263
        mov [esp+MUTEX_WAITER.next],  esi
264
        mov [esp+MUTEX_WAITER.prev],  eax
264
        mov [esp+MUTEX_WAITER.prev],  eax
265
        mov [eax], esp
265
        mov [eax], esp
266
 
266
 
267
        mov edx, [TASK_BASE]
267
        mov edx, [TASK_BASE]
268
        mov [esp+MUTEX_WAITER.task], edx
268
        mov [esp+MUTEX_WAITER.task], edx
269
 
269
 
270
.forever:
270
.forever:
271
 
271
 
272
        mov eax, -1
272
        mov eax, -1
273
        xchg eax, [ecx+MUTEX.count]
273
        xchg eax, [ecx+MUTEX.count]
274
        dec eax
274
        dec eax
275
        jz @F
275
        jz @F
276
 
276
 
277
        mov [edx+TASKDATA.state], 1
277
        mov [edx+TASKDATA.state], 1
278
        call change_task
278
        call change_task
279
        jmp .forever
279
        jmp .forever
280
@@:
280
@@:
281
        mov edx, [esp+MUTEX_WAITER.next]
281
        mov edx, [esp+MUTEX_WAITER.next]
282
        mov eax, [esp+MUTEX_WAITER.prev]
282
        mov eax, [esp+MUTEX_WAITER.prev]
283
 
283
 
284
        mov [eax+MUTEX_WAITER.next], edx
284
        mov [eax+MUTEX_WAITER.next], edx
285
        cmp [ecx+MUTEX.next], esi
285
        cmp [ecx+MUTEX.next], esi
286
        mov [edx+MUTEX_WAITER.prev], eax
286
        mov [edx+MUTEX_WAITER.prev], eax
287
        jne @F
287
        jne @F
288
 
288
 
289
        mov [ecx+MUTEX.count], 0
289
        mov [ecx+MUTEX.count], 0
290
@@:
290
@@:
291
        add  esp, MUTEX_WAITER.sizeof
291
        add  esp, MUTEX_WAITER.sizeof
292
 
292
 
293
        pop esi
293
        pop esi
294
        popfd
294
        popfd
295
.done:
295
.done:
296
        ret
296
        ret
297
 
297
 
298
;void  __fastcall mutex_unlock(struct mutex *lock)
298
;void  __fastcall mutex_unlock(struct mutex *lock)
299
 
299
 
300
align 4
300
align 4
301
mutex_unlock:
301
mutex_unlock:
302
 
302
 
303
        pushfd
303
        pushfd
304
        cli
304
        cli
305
 
305
 
306
        lea eax, [ecx+MUTEX.next]
306
        lea eax, [ecx+MUTEX.next]
307
        cmp eax, [ecx+MUTEX.next]
307
        cmp eax, [ecx+MUTEX.next]
308
        mov [ecx+MUTEX.count], 1
308
        mov [ecx+MUTEX.count], 1
309
        je @F
309
        je @F
310
 
310
 
311
        mov eax, [eax+MUTEX_WAITER.task]
311
        mov eax, [eax+MUTEX_WAITER.task]
312
        mov [eax+TASKDATA.state], 0
312
        mov [eax+TASKDATA.state], 0
313
@@:
313
@@:
314
        popfd
314
        popfd
315
        ret
315
        ret
316
 
316
 
317
 
317
 
318
purge MUTEX_WAITER
318
purge MUTEX_WAITER
319
 
319
 
320
if 0
320
if 0
321
 
321
 
322
struc TIMER
322
struc TIMER
323
{
323
{
324
  .next      dd ?
324
  .next      dd ?
325
  .exp_time  dd ?
325
  .exp_time  dd ?
326
  .func      dd ?
326
  .func      dd ?
327
  .arg       dd ?
327
  .arg       dd ?
328
}
328
}
329
 
329
 
330
 
330
 
331
MAX_PROIRITY         0   ; highest, used for kernel tasks
331
MAX_PROIRITY         0   ; highest, used for kernel tasks
332
MAX_USER_PRIORITY    0   ; highest priority for user processes
332
MAX_USER_PRIORITY    0   ; highest priority for user processes
333
USER_PRIORITY        7   ; default (should correspond to nice 0)
333
USER_PRIORITY        7   ; default (should correspond to nice 0)
334
MIN_USER_PRIORITY   14   ; minimum priority for user processes
334
MIN_USER_PRIORITY   14   ; minimum priority for user processes
335
IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
335
IDLE_PRIORITY       15   ; lowest, only IDLE process goes here
336
NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
336
NR_SCHED_QUEUES     16   ; MUST equal IDLE_PRIORYTY + 1
337
 
337
 
338
uglobal
338
uglobal
339
rdy_head   rd 16
339
rdy_head   rd 16
340
endg
340
endg
341
 
341
 
342
align 4
342
align 4
343
pick_task:
343
pick_task:
344
 
344
 
345
       xor eax, eax
345
       xor eax, eax
346
  .pick:
346
  .pick:
347
       mov ebx, [rdy_head+eax*4]
347
       mov ebx, [rdy_head+eax*4]
348
       test ebx, ebx
348
       test ebx, ebx
349
       jz .next
349
       jz .next
350
 
350
 
351
       mov [next_task], ebx
351
       mov [next_task], ebx
352
       test [ebx+flags.billable]
352
       test [ebx+flags.billable]
353
       jz @F
353
       jz @F
354
       mov [bill_task], ebx
354
       mov [bill_task], ebx
355
  @@:
355
  @@:
356
       ret
356
       ret
357
  .next:
357
  .next:
358
       inc eax
358
       inc eax
359
       jmp .pick
359
       jmp .pick
360
 
360
 
361
; param
361
; param
362
;  eax= task
362
;  eax= task
363
;
363
;
364
; retval
364
; retval
365
;  eax= task
365
;  eax= task
366
;  ebx= queue
366
;  ebx= queue
367
;  ecx= front if 1 or back if 0
367
;  ecx= front if 1 or back if 0
368
align 4
368
align 4
369
shed:
369
shed:
370
       cmp [eax+.tics_left], 0 ;signed compare
370
       cmp [eax+.tics_left], 0 ;signed compare
371
       mov ebx, [eax+.priority]
371
       mov ebx, [eax+.priority]
372
       setg ecx
372
       setg ecx
373
       jg @F
373
       jg @F
374
 
374
 
375
       mov edx, [eax+.tics_quantum]
375
       mov edx, [eax+.tics_quantum]
376
       mov [eax+.ticks_left], edx
376
       mov [eax+.ticks_left], edx
377
       cmp ebx, (IDLE_PRIORITY-1)
377
       cmp ebx, (IDLE_PRIORITY-1)
378
       je @F
378
       je @F
379
       inc ebx
379
       inc ebx
380
  @@:
380
  @@:
381
       ret
381
       ret
382
 
382
 
383
; param
383
; param
384
;  eax= task
384
;  eax= task
385
align 4
385
align 4
386
enqueue:
386
enqueue:
387
      call shed  ;eax
387
      call shed  ;eax
388
      cmp [rdy_head+ebx*4],0
388
      cmp [rdy_head+ebx*4],0
389
      jnz @F
389
      jnz @F
390
 
390
 
391
      mov [rdy_head+ebx*4], eax
391
      mov [rdy_head+ebx*4], eax
392
      mov [rdy_tail+ebx*4], eax
392
      mov [rdy_tail+ebx*4], eax
393
      mov [eax+.next_ready], 0
393
      mov [eax+.next_ready], 0
394
      jmp .pick
394
      jmp .pick
395
  @@:
395
  @@:
396
      test ecx, ecx
396
      test ecx, ecx
397
      jz .back
397
      jz .back
398
 
398
 
399
      mov ecx, [rdy_head+ebx*4]
399
      mov ecx, [rdy_head+ebx*4]
400
      mov [eax+.next_ready], ecx
400
      mov [eax+.next_ready], ecx
401
      mov [rdy_head+ebx*4], eax
401
      mov [rdy_head+ebx*4], eax
402
      jmp .pick
402
      jmp .pick
403
  .back:
403
  .back:
404
      mov ecx, [rdy_tail+ebx*4]
404
      mov ecx, [rdy_tail+ebx*4]
405
      mov [ecx+.next_ready], eax
405
      mov [ecx+.next_ready], eax
406
      mov [rdy_tail+ebx*4], eax
406
      mov [rdy_tail+ebx*4], eax
407
      mov [eax+.next_ready], 0
407
      mov [eax+.next_ready], 0
408
  .pick:
408
  .pick:
409
      call pick_proc     ;select next task
409
      call pick_proc     ;select next task
410
      ret
410
      ret
411
 
411
 
412
end if
412
end if