Subversion Repositories Kolibri OS

Rev

Rev 802 | Rev 1055 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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