diff --git a/kernel/trunk/core/sched.inc b/kernel/trunk/core/sched.inc index 048918cd11..4ff0046830 100644 --- a/kernel/trunk/core/sched.inc +++ b/kernel/trunk/core/sched.inc @@ -2,6 +2,7 @@ ;; IRQ0 HANDLER (TIMER INTERRUPT) ;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + align 32 irq0: save_ring3_context @@ -9,11 +10,6 @@ irq0: mov ds, ax mov es, ax - mov edi,[0x3000] - shl edi, 3 - ; fields of TSS descriptor: -; mov [edi+gdts+ tss0 +5], word 01010000b *256 +11101001b - inc dword [timer_ticks] mov eax, [timer_ticks] @@ -26,21 +22,90 @@ irq0: call updatecputimes .nocounter: - mov edi, [0x3010] + cmp [0xffff], byte 1 + jne .change_task + mov al,0x20 ; send End Of Interrupt signal + mov dx,0x20 + out dx,al + + mov [0xffff], byte 0 + + restore_ring3_context + iret + + .change_task: + call update_counters + + call find_next_task + mov ecx, eax + + mov al,0x20 ; send End Of Interrupt signal + mov dx,0x20 + out dx,al + + test ecx, ecx ; if there is only one running process + jnz .return + + call do_change_task + + .return: + restore_ring3_context + iret + + +align 4 +change_task: + + pushfd + cli + pushad + + call update_counters + call find_next_task + test eax, eax ; the same task -> skip switch + jnz .return + + mov [0xffff],byte 1 + call do_change_task + + .return: + popad + popfd + + ret + + +uglobal + align 4 + far_jump: + .offs dd ? + .sel dw ? + context_counter dd ? ;noname & halyavin + next_usage_update dd ? + timer_ticks dd ? + prev_slot dd ? + event_sched dd ? +endg + + +update_counters: + mov edi, [0x3010] mov ebx, [edi+0x18] ; time stamp counter add call _rdtsc sub eax, ebx add eax, [edi+0x14] ; counter sum mov [edi+0x14], eax +ret + +; Find next task to execute +; result: ebx = number of the selected task +; [0xffff] = 1 if the task is the same +find_next_task: mov ebx,[0x3000] mov [prev_slot], ebx - cmp [0xffff], byte 1 - je .do_not_change_task - - .waiting_for_termination: .waiting_for_reuse: .waiting_for_event: @@ -55,6 +120,8 @@ irq0: inc ebx mov al, byte [edi+0xA] + test al, al + jz .found cmp al, 1 jz .suspended cmp al, 2 @@ -77,73 +144,27 @@ irq0: mov [event_sched], eax mov [edi+0xA], byte 0 .noevents: - cmp ebx, [prev_slot] - sete [0xffff] - - - .do_not_change_task: - + .found: + mov [0x3000],ebx + mov [0x3010],edi call _rdtsc mov [edi+0x18],eax + xor eax, eax + cmp ebx, [prev_slot] + sete al +ret + +; in: ebx = TSS selector index +do_change_task: shl ebx, 3 xor eax, eax add ebx, tss0 - mov word [far_jump.sel], bx ; selector - mov dword [far_jump.offs], eax ; offset - - cmp [irq0needeoi],byte 0 - mov [irq0needeoi],byte 1 - jz .noeoi - - mov al,0x20 ; send End Of Interrupt signal - mov dx,0x20 - out dx,al -.noeoi: - - cmp [0xffff],byte 0 - je .switch - dec byte [0xffff] - jz @f - .switch: + mov [far_jump.sel], bx ; selector + mov [far_jump.offs], eax ; offset jmp pword [far_jump] inc [context_counter] ;noname & halyavin - @@: - - restore_ring3_context - iret - - -uglobal - align 4 - far_jump: - .offs dd ? - .sel dw ? - context_counter dd ? ;noname & halyavin - next_usage_update dd ? - timer_ticks dd ? - prev_slot dd ? - event_sched dd ? -endg -iglobal - irq0needeoi db 1 -endg - - -align 4 -change_task: - - pushfd - cli - mov [0xffff],byte 2 - - mov [irq0needeoi],byte 0 - dec dword [timer_ticks] ; because irq0 will increase it - - int 0x20 ; irq0 handler - popfd - - ret +ret