/kernel/trunk/core/fpu.inc |
---|
179,5 → 179,5 |
iret |
iglobal |
fpu_owner dd 0 |
fpu_owner dd 2 |
endg |
/kernel/trunk/core/irq.inc |
---|
267,7 → 267,6 |
.fail: |
inc [irq_failed+ebp*4] |
.exit: |
mov [check_idle_semaphore], 5 |
mov ecx, ebp |
call irq_eoi |
/kernel/trunk/core/memory.inc |
---|
1136,11 → 1136,6 |
mov eax, [dst_slot] |
shl eax, 8 |
or [eax+SLOT_BASE+0xA8], dword 0x40 |
cmp dword [check_idle_semaphore], 20 |
jge .ipc_no_cis |
mov dword [check_idle_semaphore], 5 |
.ipc_no_cis: |
push 0 |
jmp .ret |
.no_pid: |
/kernel/trunk/core/sched.inc |
---|
89,9 → 89,6 |
ret |
align 4 |
updatecputimes: |
xor eax, eax |
xchg eax, [idleuse] |
mov [idleusesec], eax |
mov ecx, [TASK_COUNT] |
mov edi, TASK_DATA |
.newupdate: |
102,56 → 99,6 |
loop .newupdate |
ret |
align 4 |
find_next_task: |
;info: |
; Find next task to execute |
;retval: |
; ebx = address of the APPDATA for the selected task (slot-base) |
; esi = previous slot-base ([current_slot] at the begin) |
; edi = address of the TASKDATA for the selected task |
; ZF = 1 if the task is the same |
;warning: |
; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result |
; [current_slot] is not set to new value (ebx)!!! |
;scratched: eax,ecx |
call update_counters ; edi := [TASK_BASE] |
Mov esi, ebx, [current_slot] |
.loop: |
cmp bh, [TASK_COUNT] |
jb @f |
xor bh, bh |
mov edi, CURRENT_TASK |
@@: |
inc bh ; ebx += APPDATA.size |
add edi, 0x20; edi += TASKDATA.size |
mov al, [edi+TASKDATA.state] |
test al, al |
jz .found ; state == 0 |
cmp al, 5 |
jne .loop ; state == 1,2,3,4,9 |
; state == 5 |
pushad ; more freedom for [APPDATA.wait_test] |
call [ebx+APPDATA.wait_test] |
mov [esp+28], eax |
popad |
or eax, eax |
jnz @f |
; testing for timeout |
mov ecx, [timer_ticks] |
sub ecx, [ebx+APPDATA.wait_begin] |
cmp ecx, [ebx+APPDATA.wait_timeout] |
jb .loop |
@@: |
mov [ebx+APPDATA.wait_param], eax ; retval for wait |
mov [edi+TASKDATA.state], 0 |
.found: |
mov [CURRENT_TASK], bh |
mov [TASK_BASE], edi |
rdtsc ;call _rdtsc |
mov [edi+TASKDATA.counter_add], eax; for next using update_counters |
cmp ebx, esi ;esi - previous slot-base |
ret |
;TODO: Íàäî áû óáðàòü èñïîëüçîâàíèå do_change_task èç V86... |
; è ïîñëå ýòîãî ïåðåíåñòè îáðàáîòêó TASKDATA.counter_add/sum â do_change_task |
305,6 → 252,143 |
purge MUTEX_WAITER |
MAX_PRIORITY = 0 ; highest, used for kernel tasks |
USER_PRIORITY = 1 ; default |
IDLE_PRIORITY = 2 ; lowest, only IDLE thread goes here |
NR_SCHED_QUEUES = 3 ; MUST equal IDLE_PRIORYTY + 1 |
uglobal |
; [scheduler_current + i*4] = zero if there are no threads with priority i, |
; pointer to APPDATA of the current thread with priority i otherwise. |
align 4 |
scheduler_current rd NR_SCHED_QUEUES |
endg |
; Add the given thread to the given priority list for the scheduler. |
; in: edx -> APPDATA, ecx = priority |
proc scheduler_add_thread |
; 1. Acquire the lock. |
spin_lock_irqsave SchedulerLock |
; 2. Store the priority in APPDATA structure. |
mov [edx+APPDATA.priority], ecx |
; 3. There are two different cases: the given list is empty or not empty. |
; In first case, go to 6. Otherwise, advance to 4. |
mov eax, [scheduler_current+ecx*4] |
test eax, eax |
jz .new_list |
; 4. Insert the new item immediately before the current item. |
mov ecx, [eax+APPDATA.in_schedule.prev] |
mov [edx+APPDATA.in_schedule.next], eax |
mov [edx+APPDATA.in_schedule.prev], ecx |
mov [eax+APPDATA.in_schedule.prev], edx |
mov [ecx+APPDATA.in_schedule.next], edx |
; 5. Release the lock and return. |
spin_unlock_irqrestore SchedulerLock |
ret |
.new_list: |
; 6. Initialize the list with one item and make it the current item. |
mov [edx+APPDATA.in_schedule.next], edx |
mov [edx+APPDATA.in_schedule.prev], edx |
mov [scheduler_current+ecx*4], edx |
; 7. Release the lock and return. |
spin_unlock_irqrestore SchedulerLock |
ret |
endp |
; Remove the given thread from the corresponding priority list for the scheduler. |
; in: edx -> APPDATA |
proc scheduler_remove_thread |
; 1. Acquire the lock. |
spin_lock_irqsave SchedulerLock |
; 2. Remove the item from the corresponding list. |
mov eax, [edx+APPDATA.in_schedule.next] |
mov ecx, [edx+APPDATA.in_schedule.prev] |
mov [eax+APPDATA.in_schedule.prev], ecx |
mov [ecx+APPDATA.in_schedule.next], eax |
; 3. If the given thread is the current item in the list, |
; advance the current item. |
; 3a. Check whether the given thread is the current item; |
; if no, skip the rest of this step. |
mov ecx, [edx+APPDATA.priority] |
cmp [scheduler_current+ecx*4], edx |
jnz .return |
; 3b. Set the current item to eax; step 2 has set eax = next item. |
mov [scheduler_current+ecx*4], eax |
; 3c. If there were only one item in the list, zero the current item. |
cmp eax, edx |
jnz .return |
mov [scheduler_current+ecx*4], 0 |
.return: |
; 4. Release the lock and return. |
spin_unlock_irqrestore SchedulerLock |
ret |
endp |
;info: |
; Find next task to execute |
;retval: |
; ebx = address of the APPDATA for the selected task (slot-base) |
; edi = address of the TASKDATA for the selected task |
; ZF = 1 if the task is the same |
;warning: |
; [CURRENT_TASK] = bh , [TASK_BASE] = edi -- as result |
; [current_slot] is not set to new value (ebx)!!! |
;scratched: eax,ecx |
proc find_next_task |
call update_counters |
spin_lock_irqsave SchedulerLock |
xor ecx, ecx |
.priority_loop: |
mov ebx, [scheduler_current+ecx*4] |
test ebx, ebx |
jz .priority_next |
.task_loop: |
mov ebx, [ebx+APPDATA.in_schedule.next] |
mov edi, ebx |
shr edi, 3 |
add edi, CURRENT_TASK - (SLOT_BASE shr 3) |
mov al, [edi+TASKDATA.state] |
test al, al |
jz .task_found ; state == 0 |
cmp al, 5 |
jne .task_next ; state == 1,2,3,4,9 |
; state == 5 |
pushad ; more freedom for [APPDATA.wait_test] |
call [ebx+APPDATA.wait_test] |
mov [esp+28], eax |
popad |
or eax, eax |
jnz @f |
; testing for timeout |
mov eax, [timer_ticks] |
sub eax, [ebx+APPDATA.wait_begin] |
cmp eax, [ebx+APPDATA.wait_timeout] |
jb .task_next |
xor eax, eax |
@@: |
mov [ebx+APPDATA.wait_param], eax ; retval for wait |
mov [edi+TASKDATA.state], 0 |
.task_found: |
mov [scheduler_current+ecx*4], ebx |
spin_unlock_irqrestore SchedulerLock |
.found: |
mov [CURRENT_TASK], bh |
mov [TASK_BASE], edi |
rdtsc ;call _rdtsc |
mov [edi+TASKDATA.counter_add], eax; for next using update_counters |
cmp ebx, [current_slot] |
ret |
.task_next: |
cmp ebx, [scheduler_current+ecx*4] |
jnz .task_loop |
.priority_next: |
inc ecx |
cmp ecx, NR_SCHED_QUEUES |
jb .priority_loop |
hlt |
jmp $-1 |
endp |
if 0 |
struc TIMER |
316,13 → 400,6 |
} |
MAX_PROIRITY 0 ; highest, used for kernel tasks |
MAX_USER_PRIORITY 0 ; highest priority for user processes |
USER_PRIORITY 7 ; default (should correspond to nice 0) |
MIN_USER_PRIORITY 14 ; minimum priority for user processes |
IDLE_PRIORITY 15 ; lowest, only IDLE process goes here |
NR_SCHED_QUEUES 16 ; MUST equal IDLE_PRIORYTY + 1 |
uglobal |
rdy_head rd 16 |
endg |
/kernel/trunk/core/sys32.inc |
---|
159,6 → 159,7 |
call show_error_parameters ;; only ONE using, inline ??? |
;mov edx, [TASK_BASE] |
mov [edx + TASKDATA.state], byte 4 ; terminate |
call wakeup_osloop |
jmp change_task ; stack - here it does not matter at all, SEE: core/shed.inc |
.debug: |
; we are debugged process, notify debugger and suspend ourself |
261,8 → 262,10 |
align 4 |
set_application_table_status: |
push eax |
lock_application_table: |
push eax ecx edx |
mov ecx, application_table_mutex |
call mutex_lock |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
269,29 → 272,22 |
add eax, CURRENT_TASK+TASKDATA.pid |
mov eax, [eax] |
mov [application_table_status], eax |
mov [application_table_owner], eax |
pop eax |
pop edx ecx eax |
ret |
align 4 |
clear_application_table_status: |
push eax |
unlock_application_table: |
push eax ecx edx |
mov eax, [CURRENT_TASK] |
shl eax, 5 |
add eax, CURRENT_TASK+TASKDATA.pid |
mov eax, [eax] |
mov [application_table_owner], 0 |
mov ecx, application_table_mutex |
call mutex_unlock |
cmp eax, [application_table_status] |
jne apptsl1 |
xor eax, eax |
mov [application_table_status], eax |
apptsl1: |
pop edx ecx eax |
pop eax |
ret |
; * eax = 64 - íîìåð ôóíêöèè |
338,17 → 334,11 |
mov [CURRENT_TASK+esi+TASKDATA.state], 9 |
ret |
@@: |
lea edx, [SLOT_BASE+esi] |
call scheduler_remove_thread |
;mov esi,process_terminating |
;call sys_msg_board_str |
@@: |
cli |
cmp [application_table_status], 0 |
je term9 |
sti |
call change_task |
jmp @b |
term9: |
call set_application_table_status |
call lock_application_table |
; if the process is in V86 mode... |
mov eax, [.slot] |
391,11 → 381,11 |
stdcall destroy_app_space, [SLOT_BASE+eax+APPDATA.dir_table], [SLOT_BASE+eax+APPDATA.dlls_list_ptr] |
mov esi, [.slot] |
cmp [fpu_owner], esi ; if user fpu last -> fpu user = 1 |
cmp [fpu_owner], esi ; if user fpu last -> fpu user = 2 |
jne @F |
mov [fpu_owner], 1 |
mov eax, [256+SLOT_BASE+APPDATA.fpu_state] |
mov [fpu_owner], 2 |
mov eax, [256*2+SLOT_BASE+APPDATA.fpu_state] |
clts |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
688,7 → 678,7 |
mov [MOUSE_BACKGROUND], byte 0; no mouse background |
mov [DONT_DRAW_MOUSE], byte 0; draw mouse |
and [application_table_status], 0 |
call unlock_application_table |
;mov esi,process_terminated |
;call sys_msg_board_str |
add esp, 4 |
/kernel/trunk/core/taskman.inc |
---|
90,7 → 90,7 |
stdcall set_cursor, [def_cursor_clock] |
mov [handle], eax |
mov [redrawmouse_unconditional], 1 |
call __sys_draw_pointer |
call wakeup_osloop |
popad |
@@: |
mov [flags], edx |
152,20 → 152,8 |
test eax, eax |
jz .err_hdr |
.wait_lock: |
cmp [application_table_status], 0 |
je .get_lock |
call change_task |
jmp .wait_lock |
call lock_application_table |
.get_lock: |
mov eax, 1 |
xchg eax, [application_table_status] |
test eax, eax |
jnz .wait_lock |
call set_application_table_status |
call get_new_process_place |
test eax, eax |
mov esi, -0x20 ; too many processes |
246,9 → 234,8 |
mov eax, [save_cr3] |
call set_cr3 |
xor ebx, ebx |
mov [application_table_status], ebx;unlock application_table_status mutex |
mov eax, [process_number];set result |
call unlock_application_table |
jmp .final |
259,8 → 246,7 |
.err_hdr: |
stdcall kernel_free, [file_base] |
.err_file: |
xor eax, eax |
mov [application_table_status], eax |
call unlock_application_table |
mov eax, esi |
.final: |
cmp [SCR_MODE], word 0x13 |
268,7 → 254,7 |
pushad |
stdcall set_cursor, [handle] |
mov [redrawmouse_unconditional], 1 |
call __sys_draw_pointer |
call wakeup_osloop |
popad |
@@: |
ret |
898,20 → 884,8 |
mov [app_path], eax |
;mov esi,new_process_loading |
;call sys_msg_board_str |
.wait_lock: |
cmp [application_table_status], 0 |
je .get_lock |
call change_task |
jmp .wait_lock |
call lock_application_table |
.get_lock: |
mov eax, 1 |
xchg eax, [application_table_status] |
test eax, eax |
jnz .wait_lock |
call set_application_table_status |
call get_new_process_place |
test eax, eax |
jz .failed |
967,14 → 941,13 |
;mov esi,new_process_running |
;call sys_msg_board_str ;output information about succefull startup |
xor eax, eax |
mov [application_table_status], eax ;unlock application_table_status mutex |
mov eax, [process_number] ;set result |
call unlock_application_table |
ret |
.failed: |
xor eax, eax |
.failed1: |
mov [application_table_status], eax |
call unlock_application_table |
dec eax ;-1 |
ret |
endp |
1148,6 → 1121,7 |
mov eax, [esi+0x08] ;app_eip |
mov [ebx+REG_EIP], eax;app_entry |
mov [ebx+REG_CS], dword app_code |
mov ecx, USER_PRIORITY |
mov eax, [CURRENT_TASK] |
shl eax, 8 ; created by kernel? |
cmp [SLOT_BASE+eax+APPDATA.dir_table], sys_pgdir - OS_BASE |
1155,6 → 1129,7 |
cmp [app_path], 0 ; it is a thread? |
jnz @f |
mov [ebx+REG_CS], dword os_code ; kernel thread |
mov ecx, MAX_PRIORITY |
@@: |
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF |
1162,20 → 1137,22 |
mov [ebx+REG_APP_ESP], eax;app_stack |
mov [ebx+REG_SS], dword app_data |
lea ecx, [ebx+REG_RET] |
lea edx, [ebx+REG_RET] |
mov ebx, [slot] |
shl ebx, 5 |
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], ecx |
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], edx |
xor ecx, ecx; process state - running |
xor edx, edx; process state - running |
; set if debuggee |
test byte [flags], 1 |
jz .no_debug |
inc ecx ; process state - suspended |
inc edx ; process state - suspended |
mov eax, [CURRENT_TASK] |
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot], eax |
.no_debug: |
mov [CURRENT_TASK+ebx+TASKDATA.state], cl |
mov [CURRENT_TASK+ebx+TASKDATA.state], dl |
lea edx, [SLOT_BASE+ebx*8] |
call scheduler_add_thread |
;mov esi,new_process_running |
;call sys_msg_board_str ;output information about succefull startup |
ret |
/kernel/trunk/core/timers.inc |
---|
203,3 → 203,28 |
call unlock_timer_list |
; 4. Return. |
ret |
; This is a simplified version of check_timers that does not call anything, |
; just checks whether check_timers should do something. |
proc check_timers_has_work? |
pushf |
cli |
mov eax, [timer_list+TIMER.Next] |
.loop: |
cmp eax, timer_list |
jz .done_nowork |
mov edx, [timer_ticks] |
sub edx, [eax+TIMER.Time] |
jns .done_haswork |
mov eax, [eax+TIMER.Next] |
jmp .loop |
.done_nowork: |
popf |
xor eax, eax |
ret |
.done_haswork: |
popf |
xor eax, eax |
inc eax |
ret |
endp |