allow high-priority threads to wakeup after any IRQ, not just timer

git-svn-id: svn://kolibrios.org@3615 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
CleverMouse 2013-06-07 16:46:52 +00:00
parent d4216492e1
commit 30b17fb697
3 changed files with 39 additions and 4 deletions

View File

@ -273,6 +273,12 @@ align 16
mov ecx, ebp mov ecx, ebp
call irq_eoi call irq_eoi
; IRQ handler could make some kernel thread ready; reschedule
mov bl, SCHEDULE_HIGHER_PRIORITY
call find_next_task
jz .return ; if there is only one running process
call do_change_task
.return:
restore_ring3_context restore_ring3_context
add esp, 4 add esp, 4
iret iret

View File

@ -31,6 +31,7 @@ irq0:
call irq_eoi call irq_eoi
; btr dword[DONT_SWITCH], 0 ; btr dword[DONT_SWITCH], 0
; jc .return ; jc .return
mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task call find_next_task
jz .return ; if there is only one running process jz .return ; if there is only one running process
call do_change_task call do_change_task
@ -58,6 +59,7 @@ if 0
.find_next_task: .find_next_task:
; \end{Mario79} ; \end{Mario79}
end if end if
mov bl, SCHEDULE_ANY_PRIORITY
call find_next_task call find_next_task
jz .return ; the same task -> skip switch jz .return ; the same task -> skip switch
@@: @@:
@ -324,8 +326,16 @@ proc scheduler_remove_thread
ret ret
endp endp
SCHEDULE_ANY_PRIORITY = 0
SCHEDULE_HIGHER_PRIORITY = 1
;info: ;info:
; Find next task to execute ; Find next task to execute
;in:
; bl = SCHEDULE_ANY_PRIORITY:
; consider threads with any priority
; bl = SCHEDULE_HIGHER_PRIORITY:
; consider only threads with strictly higher priority than the current one,
; keep running the current thread if other ready threads have the same or lower priority
;retval: ;retval:
; ebx = address of the APPDATA for the selected task (slot-base) ; ebx = address of the APPDATA for the selected task (slot-base)
; edi = address of the TASKDATA for the selected task ; edi = address of the TASKDATA for the selected task
@ -337,6 +347,18 @@ endp
proc find_next_task proc find_next_task
call update_counters call update_counters
spin_lock_irqsave SchedulerLock spin_lock_irqsave SchedulerLock
push NR_SCHED_QUEUES
; If bl == SCHEDULE_ANY_PRIORITY = 0, loop over all NR_SCHED lists.
; Otherwise, loop over first [APPDATA.priority] lists.
test bl, bl
jz .start
mov ebx, [current_slot]
mov edi, [TASK_BASE]
mov eax, [ebx+APPDATA.priority]
test eax, eax
jz .unlock_found
mov [esp], eax
.start:
xor ecx, ecx xor ecx, ecx
.priority_loop: .priority_loop:
mov ebx, [scheduler_current+ecx*4] mov ebx, [scheduler_current+ecx*4]
@ -370,6 +392,8 @@ proc find_next_task
mov [edi+TASKDATA.state], 0 mov [edi+TASKDATA.state], 0
.task_found: .task_found:
mov [scheduler_current+ecx*4], ebx mov [scheduler_current+ecx*4], ebx
.unlock_found:
pop ecx
spin_unlock_irqrestore SchedulerLock spin_unlock_irqrestore SchedulerLock
.found: .found:
mov [CURRENT_TASK], bh mov [CURRENT_TASK], bh
@ -383,10 +407,11 @@ proc find_next_task
jnz .task_loop jnz .task_loop
.priority_next: .priority_next:
inc ecx inc ecx
cmp ecx, NR_SCHED_QUEUES cmp ecx, [esp]
jb .priority_loop jb .priority_loop
hlt mov ebx, [current_slot]
jmp $-1 mov edi, [TASK_BASE]
jmp .unlock_found
endp endp
if 0 if 0

View File

@ -160,7 +160,11 @@ exc_c: ; исключения (все, кроме 7-г
;mov edx, [TASK_BASE] ;mov edx, [TASK_BASE]
mov [edx + TASKDATA.state], byte 4 ; terminate mov [edx + TASKDATA.state], byte 4 ; terminate
call wakeup_osloop call wakeup_osloop
jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc call change_task
; If we're here, then the main OS thread has crashed before initializing IDLE thread.
; Or they both have crashed. Anyway, things are hopelessly broken.
hlt
jmp $-1
.debug: .debug:
; we are debugged process, notify debugger and suspend ourself ; we are debugged process, notify debugger and suspend ourself
; eax=debugger PID ; eax=debugger PID