diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index fc059affa7..50e5204c31 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -511,7 +511,7 @@ struct APPDATA exc_handler dd ? ;+32 except_mask dd ? ;+36 pl0_stack dd ? ;+40 - dd ? ;+44 + exc_reserve_stack dd ? ;+44 fd_ev dd ? ;+48 bk_ev dd ? ;+52 fd_obj dd ? ;+56 @@ -528,7 +528,9 @@ struct APPDATA tls_base dd ? ;+104 event_mask dd ? ;+108 stores event types allowed for task tid dd ? ;+112 thread id - dd ? ;+116 + def_priority db ? ;+116 + cur_priority db ? ;+117 + dw ? ;+118 dd ? ;+120 state db ? ;+124 thread state wnd_number db ? ;+125 @@ -590,6 +592,8 @@ ZPOS_ALWAYS_BACK = -1 ZPOS_NORMAL = 0 ZPOS_ALWAYS_TOP = 1 ;ZPOS_ALWAYS_TOP is always last and has max number! +CONTROL_EXCEPTION = 'EXPT' + ; Window structure: struct WDATA box BOX diff --git a/kernel/trunk/core/memory.inc b/kernel/trunk/core/memory.inc index e185dc129d..351cb4ec22 100644 --- a/kernel/trunk/core/memory.inc +++ b/kernel/trunk/core/memory.inc @@ -1177,6 +1177,7 @@ f68: mov eax, [current_slot] xchg ecx, [eax + APPDATA.exc_handler] xchg edx, [eax + APPDATA.except_mask] + xchg esi, [eax + APPDATA.exc_reserve_stack] mov [esp + SYSCALL_STACK.ebx], edx mov [esp + SYSCALL_STACK.eax], ecx ret diff --git a/kernel/trunk/core/sched.inc b/kernel/trunk/core/sched.inc index 284c8aa4c3..42e0d610df 100644 --- a/kernel/trunk/core/sched.inc +++ b/kernel/trunk/core/sched.inc @@ -307,6 +307,13 @@ proc find_next_task mov [ebx + APPDATA.wait_param], eax ; retval for wait mov [ebx + APPDATA.state], TSTATE_RUNNING .task_found: + mov dl, [ebx + APPDATA.def_priority] + test dl, dl + jz .no_local_priority + dec [ebx + APPDATA.cur_priority] + jnz .task_next + xchg [ebx + APPDATA.cur_priority], dl +.no_local_priority: mov [scheduler_current+ecx*4], ebx ; If we have selected a thread with higher priority ; AND rescheduling is due to IRQ, diff --git a/kernel/trunk/core/sys32.inc b/kernel/trunk/core/sys32.inc index b48650e757..d3a4417735 100644 --- a/kernel/trunk/core/sys32.inc +++ b/kernel/trunk/core/sys32.inc @@ -114,6 +114,18 @@ endg page_fault_exc: ; foolproof: selectors are clobbered ... pop [ss:pf_err_code] ; actually, until the next #PF + + cmp edi, CONTROL_EXCEPTION ; equ 'EXPT' + jne .no_ctrl_exc + bt dword [esp], 31 + jc .setret + test esi, esi + jl .no_ctrl_exc +.setret: + mov [esp], esi + iret + +.no_ctrl_exc: save_ring3_context mov bl, 14 @@ -211,8 +223,7 @@ IRetToUserHook: add ecx, 1000h jl .nostack .ex_stack: - xor ecx, ecx - mov ecx, [ecx+APP_HEADER_01_.except_stack_top] + mov ecx, [esi+APPDATA.exc_reserve_stack] test ecx, ecx jle .nostack xchg edi, eax diff --git a/kernel/trunk/core/taskman.inc b/kernel/trunk/core/taskman.inc index 2ecb034b67..708e09752b 100644 --- a/kernel/trunk/core/taskman.inc +++ b/kernel/trunk/core/taskman.inc @@ -28,7 +28,6 @@ struct APP_HEADER_01_ stack_top dd ? ;+24 i_param dd ? ;+28 i_icon dd ? ;+32 - except_stack_top dd ? ;+36 ends struct APP_HDR @@ -1009,6 +1008,7 @@ proc set_app_params stdcall,slot:dword, params:dword, flags:dword ;set draw data to full screen xor eax, eax + mov [SLOT_BASE + ebx + APPDATA.def_priority], al mov [ecx + WDATA.draw_data.left], eax mov [ecx + WDATA.draw_data.top], eax mov eax, [screen_workarea.right] diff --git a/kernel/trunk/docs/sysfuncr.txt b/kernel/trunk/docs/sysfuncr.txt index c1c78909c8..0ba3c92d89 100644 --- a/kernel/trunk/docs/sysfuncr.txt +++ b/kernel/trunk/docs/sysfuncr.txt @@ -2550,11 +2550,12 @@ dword-значение цвета 0x00RRGGBB ---------------------- Константы для регистров: ---------------------- eax - SF_SET_WINDOW_SHAPE (50) ====================================================================== -===================== Функция 51 - создать поток. ==================== +===================== Функция 51, подфункция 1 ======================= +========================== Создать поток ============================= ====================================================================== Параметры: * eax = 51 - номер функции - * ebx = 1 - единственная подфункция + * ebx = 1 - номер подфункции * ecx = адрес точки входа потока (начальный eip) * edx = указатель стэка потока (начальный esp) Возвращаемое значение: @@ -2564,6 +2565,47 @@ dword-значение цвета 0x00RRGGBB ---------------------- Константы для регистров: ---------------------- eax - SF_CREATE_THREAD (51) ====================================================================== +===================== Функция 51, подфункция 2 ======================= +=================== Получить номер слота потока ====================== +====================================================================== +Параметры: + * eax = 51 - номер функции + * ebx = 2 - номер подфункции +Возвращаемое значение: + * eax = номер слота потока + +====================================================================== +===================== Функция 51, подфункция 3 ======================= +==================== Получить приоритет потока ======================= +====================================================================== +Параметры: + * eax = 51 - номер функции + * ebx = 3 - номер подфункции + * ecx = номер слота потока или -1 (текущий поток) +Возвращаемое значение: + * eax = -1 - ошибка (неверный номер слота потока или поток завершен) + * иначе eax = номер приоритета потока +Замечания: + * Приоритет потока имеет диапазон значений от 0 до 255. + Значение 0 - наивысший приоритет потока, устанавливаемый по умолчанию при создании потока. + +====================================================================== +===================== Функция 51, подфункция 4 ======================= +=================== Установить приоритет потока ====================== +====================================================================== +Параметры: + * eax = 51 - номер функции + * ebx = 4 - номер подфункции + * ecx = номер слота потока или -1 (текущий поток) + * edx = приоритет потока +Возвращаемое значение: + * eax = -1 - ошибка (неверный номер слота потока или поток завершен) + * иначе eax = старое значение приоритета потока +Замечания: + * Приоритет потока имеет диапазон значений от 0 до 255. + Значение 0 - наивысший приоритет потока, устанавливаемый по умолчанию при создании потока. + +====================================================================== ====================== Функция 54, подфункция 0 ====================== ============== Узнать количество слотов в буфере обмена. ============= ====================================================================== @@ -3599,9 +3641,14 @@ Architecture Software Developer's Manual, Volume 3, Appendix B); подфункцией 25. Сброс флагов исключений в модулях FPU и XMM также возлагается на обработчик пользователя. Внимание: - Если пользовательский обработчик обрабатывает исключение переполнения стека (#SS), то должен быть установлен адрес резервного стека в заголовке программы (см. структуру APP_HEADER_01_ taskman.inc). - В этот резервный стек будут записаны дополнительные данные (см. структуру EXCEPT_STACK sys32.inc). - Пользовательский бработчик,при завершении обработки этого исключения, должен дополнительно обнулить бит занятости (бит номер 0) резервного стека в поле LockAccess структуры EXCEPT_STACK. + 1) Если пользовательский обработчик обрабатывает исключение переполнения стека (#SS), то должен быть установлен стартовый адрес резервного стека в регистре ESI. + При возникновении исключения (#SS), в этот резервный стек будут записаны дополнительные данные (см. структуру EXCEPT_STACK sys32.inc). + При завершении обработки этого исключения, пользовательский обработчик должен дополнительно обнулить бит занятости (бит номер 0) резервного стека в поле LockAccess структуры EXCEPT_STACK. + + 2) Вы можете использовать режим "контролируемое исключение" для проверок на корректность адресов памяти при считывании\записи данных. + Для этого: + - В регистр ESI заносится адрес, куда должно перейти выполнение кода при возникновении исключения. + - В регистр EDI заносится сигнатура - текст 'EXPT'. ---------------------- Константы для регистров: ---------------------- diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 15d4bb046a..471d0a4660 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -4281,15 +4281,85 @@ align 4 ;----------------------------------------------------------------------------- align 4 -syscall_threads: ; CreateThreads -; -; ecx=thread entry point -; edx=thread stack pointer -; -; on return : eax = pid - xor ebx, ebx +syscall_threads: +; eax = 51 +; if ebx = 1 CreateThreads +; ecx = thread entry point +; edx = thread stack pointer +; return eax = pid + +; if ebx = 2 GetCurrentThreadId +; return eax = current id slot + +; if ebx = 3 GetThreadPriority +; ecx = -1 curr slot or id slot +; return eax = priority + +; if ebx = 4 SetThreadPriority +; ecx = -1 curr slot or id slot +; edx = set priority +; return eax = old priority + + dec ebx + jz .create + mov eax, [current_slot_idx] + dec ebx + jz .end ;get_curr_slot + + test ecx, ecx ;-1 curr slot + jl .cur_slot + mov eax, ecx +.cur_slot: + shl eax, BSF sizeof.APPDATA + add eax, SLOT_BASE + + test ecx, ecx ;-1 curr slot + jl .curr_slot + + mov esi, .err_exit + mov edi, CONTROL_EXCEPTION + + movzx ecx, [eax+APPDATA.state] + test ecx, ecx + jnz .check_state + + cmp [eax+APPDATA.tid], ecx + jnz .curr_slot + jmp .err_exit + +.check_state: + sub ecx, 3 ;TSTATE_ZOMBIE + jl .curr_slot + je .err_exit + dec ecx ; 4 TSTATE_TERMINATING + dec ecx ; 5 TSTATE_WAITING + jnz .err_exit + +.curr_slot: + dec ebx + jz .get_priority + dec ebx + jz .set_priority + +.err_exit: + push -1 + pop eax + jmp .end + +.set_priority: ;;sysfn 51,4 + mov dh, dl + lock xchg word [eax+APPDATA.def_priority], dx + movzx eax, dl ;old priority + jmp .end + +.get_priority: ;;sysfn 51,3 + movzx eax, [eax+APPDATA.def_priority] + jmp .end + +.create: ;sysfn 51,1 call new_sys_threads +.end: mov [esp + SYSCALL_STACK.eax], eax ret