From 25ecf7263e6582637eab52249b0141527eab8f3e Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Tue, 19 Jan 2016 01:02:44 +0000 Subject: [PATCH] new Fn77 - fast user-space locking git-svn-id: svn://kolibrios.org@6079 a494cfbc-eb01-0410-851d-a64ba20cac60 --- kernel/trunk/const.inc | 282 ++++++++++++++++--- kernel/trunk/core/sched.inc | 240 ---------------- kernel/trunk/core/sync.inc | 484 +++++++++++++++++++++++++++++++++ kernel/trunk/core/syscall.inc | 2 + kernel/trunk/docs/sysfuncs.txt | 88 +++++- kernel/trunk/kernel32.inc | 191 ------------- 6 files changed, 804 insertions(+), 483 deletions(-) diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index 35e68be09b..407d15aa26 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -354,17 +354,214 @@ EVENT_EXTENDED equ 0x00000400 EV_INTR equ 1 -struct THR_DATA - rb (8192-512) -; pl0_stack - fpu_state rb 512 - tls_page rb 4096 - pdbr rb 4096 +STDIN_FILENO equ 0 +STDOUT_FILENO equ 1 +STDERR_FILENO equ 2 + +struct SYSCALL_STACK + _eip dd ? + _edi dd ? ; +4 + _esi dd ? ; +8 + _ebp dd ? ; +12 + _esp dd ? ; +16 + _ebx dd ? ; +20 + _edx dd ? ; +24 + _ecx dd ? ; +28 + _eax dd ? ; +32 ends -virtual at (OS_BASE-sizeof.THR_DATA) - thr_data THR_DATA -end virtual +struct LHEAD + next dd ? ;next object in list + prev dd ? ;prev object in list +ends + +struct MUTEX_WAITER + list LHEAD + task dd ? + type dd ? +ends + +struct MUTEX + wait_list LHEAD + count dd ? +ends + +struct RWSEM + wait_list LHEAD + count dd ? +ends + +struct FUTEX + list LHEAD + magic dd ? + handle dd ? + destroy dd ? + + wait_list LHEAD + pointer dd ? + flags dd ? +ends + +FUTEX_INIT equ 0 +FUTEX_DESTROY equ 1 +FUTEX_WAIT equ 2 +FUTEX_WAKE equ 3 + +struct PROC + list LHEAD + thr_list LHEAD + heap_lock MUTEX + heap_base rd 1 + heap_top rd 1 + mem_used rd 1 + dlls_list_ptr rd 1 + pdt_0_phys rd 1 + pdt_1_phys rd 1 + io_map_0 rd 1 + io_map_1 rd 1 + + ht_lock rd 1 + ht_free rd 1 ;htab[0] stdin + ht_next rd 1 ;htab[1] stdout + htab rd (4096-$)/4 ;htab[2] stderr + pdt_0 rd 1024 +ends + +struct DBG_REGS + dr0 dd ? + dr1 dd ? + dr2 dd ? + dr3 dd ? + dr7 dd ? +ends + +struct POINT + x dd ? + y dd ? +ends + +struct RECT + left dd ? + top dd ? + right dd ? + bottom dd ? +ends + +struct BOX + left dd ? + top dd ? + width dd ? + height dd ? +ends + +struct APPDATA + app_name rb 11 + rb 5 + + list LHEAD ;+16 + process dd ? ;+24 + fpu_state dd ? ;+28 + exc_handler dd ? ;+32 + except_mask dd ? ;+36 + pl0_stack dd ? ;+40 + cursor dd ? ;+44 + fd_ev dd ? ;+48 + bk_ev dd ? ;+52 + fd_obj dd ? ;+56 + bk_obj dd ? ;+60 + saved_esp dd ? ;+64 + io_map rd 2 ;+68 + dbg_state dd ? ;+76 + cur_dir dd ? ;+80 + wait_timeout dd ? ;+84 + saved_esp0 dd ? ;+88 + wait_begin dd ? ;+92 +++ + wait_test dd ? ;+96 +++ + wait_param dd ? ;+100 +++ + tls_base dd ? ;+104 + dd ? ;+108 + event_filter dd ? ;+112 + draw_bgr_x dd ? ;+116 + draw_bgr_y dd ? ;+120 + dd ? ;+124 + + wnd_shape dd ? ;+128 + wnd_shape_scale dd ? ;+132 + dd ? ;+136 + dd ? ;+140 + saved_box BOX ;+144 + ipc_start dd ? ;+160 + ipc_size dd ? ;+164 + event_mask dd ? ;+168 + debugger_slot dd ? ;+172 + terminate_protection dd ? ;+176 + keyboard_mode db ? ;+180 + rb 3 + dd ? ;+184 + dbg_event_mem dd ? ;+188 + dbg_regs DBG_REGS ;+192 + wnd_caption dd ? ;+212 + wnd_clientbox BOX ;+216 + priority dd ? ;+232 + in_schedule LHEAD ;+236 +ends + +APP_OBJ_OFFSET equ 48 +APP_EV_OFFSET equ 40 + +struct TASKDATA + event_mask dd ? + pid dd ? + dw ? + state db ? + db ? + dw ? + wnd_number db ? + db ? + mem_start dd ? + counter_sum dd ? + counter_add dd ? + cpu_usage dd ? +ends + +TSTATE_RUNNING = 0 +TSTATE_RUN_SUSPENDED = 1 +TSTATE_WAIT_SUSPENDED = 2 +TSTATE_ZOMBIE = 3 +TSTATE_TERMINATING = 4 +TSTATE_WAITING = 5 +TSTATE_FREE = 9 + +; constants definition +WSTATE_NORMAL = 00000000b +WSTATE_MAXIMIZED = 00000001b +WSTATE_MINIMIZED = 00000010b +WSTATE_ROLLEDUP = 00000100b + +WSTATE_REDRAW = 00000001b +WSTATE_WNDDRAWN = 00000010b + +WSTYLE_HASCAPTION = 00010000b +WSTYLE_CLIENTRELATIVE = 00100000b + +ZPOS_DESKTOP = -2 +ZPOS_ALWAYS_BACK = -1 +ZPOS_NORMAL = 0 +ZPOS_ALWAYS_TOP = 1 ;ZPOS_ALWAYS_TOP is always last and has max number! +; structures definition +struct WDATA + box BOX + cl_workarea dd ? + cl_titlebar dd ? + cl_frames dd ? + z_modif db ? + fl_wstate db ? + fl_wdrawn db ? + fl_redraw db ? +ends + +label WDATA.fl_wstyle byte at WDATA.cl_workarea + 3 + struct SYS_VARS bpp dd ? @@ -382,9 +579,6 @@ struct APPOBJ ; common object header pid dd ? ; owner id ends -APP_OBJ_OFFSET equ 48 -APP_EV_OFFSET equ 40 - struct CURSOR APPOBJ base dd ? ;allocated memory hot_x dd ? ;hotspot coords @@ -480,32 +674,6 @@ struct BOOT_DATA dd ? ends -struct LHEAD - next dd ? ;next object in list - prev dd ? ;prev object in list -ends - -struct MUTEX - wait_list LHEAD - count dd ? -ends - -struct RWSEM - wait_list LHEAD - count dd ? -ends - -struct FUTEX - list LHEAD - magic dd ? - handle dd ? - destroy dd ? - - wait_list LHEAD - pointer dd ? - flags dd ? -ends - struct display_t x dd ? y dd ? @@ -544,6 +712,13 @@ struct display_t bytes_per_pixel dd ? ends +struct DISPMODE + width dw ? + height dw ? + bpp dw ? + freq dw ? +ends + struct PCIDEV bk dd ? @@ -556,6 +731,37 @@ struct PCIDEV owner dd ? ; pointer to SRV or 0 ends +struct IDE_DATA + ProgrammingInterface dd ? + Interrupt dw ? + RegsBaseAddres dw ? + BAR0_val dw ? + BAR1_val dw ? + BAR2_val dw ? + BAR3_val dw ? + dma_hdd_channel_1 db ? + dma_hdd_channel_2 db ? +ends + +struct IDE_CACHE + pointer dd ? + size dd ? ; not use + data_pointer dd ? + system_data_size dd ? ; not use + appl_data_size dd ? ; not use + system_data dd ? + appl_data dd ? + system_sad_size dd ? + appl_sad_size dd ? + search_start dd ? + appl_search_start dd ? +ends + +struct IDE_DEVICE + UDMA_possible_modes db ? + UDMA_set_mode db ? +ends + ; The following macro assume that we are on uniprocessor machine. ; Serious work is needed for multiprocessor machines. macro spin_lock_irqsave spinlock diff --git a/kernel/trunk/core/sched.inc b/kernel/trunk/core/sched.inc index e1cc376002..7227f0ce05 100644 --- a/kernel/trunk/core/sched.inc +++ b/kernel/trunk/core/sched.inc @@ -158,246 +158,6 @@ do_change_task: ;end. -struct MUTEX_WAITER - list LHEAD - task dd ? - type dd ? -ends - -RWSEM_WAITING_FOR_WRITE equ 0 -RWSEM_WAITING_FOR_READ equ 1 - -;void __fastcall mutex_init(struct mutex *lock) - -align 4 -mutex_init: - mov [ecx+MUTEX.wait_list.next], ecx - mov [ecx+MUTEX.wait_list.prev], ecx - mov [ecx+MUTEX.count], 1 - ret - -;void __fastcall mutex_lock(struct mutex *lock) - -align 4 -mutex_lock: - - dec [ecx+MUTEX.count] - jns .done - - pushfd - cli - - sub esp, sizeof.MUTEX_WAITER - - list_add_tail esp, ecx ;esp= new waiter, ecx= list head - - mov edx, [TASK_BASE] - mov [esp+MUTEX_WAITER.task], edx - -.forever: - - mov eax, -1 - xchg eax, [ecx+MUTEX.count] - dec eax - jz @F - - mov [edx+TASKDATA.state], 1 - call change_task - jmp .forever -@@: - mov eax, ecx - list_del esp - - cmp [eax+MUTEX.wait_list.next], eax - jne @F - - mov [eax+MUTEX.count], 0 -@@: - add esp, sizeof.MUTEX_WAITER - - popfd -.done: - ret - -;void __fastcall mutex_unlock(struct mutex *lock) - -align 4 -mutex_unlock: - - pushfd - cli - - mov eax, [ecx+MUTEX.wait_list.next] - cmp eax, ecx - mov [ecx+MUTEX.count], 1 - je @F - - mov eax, [eax+MUTEX_WAITER.task] - mov [eax+TASKDATA.state], 0 -@@: - popfd - ret - - -;void __fastcall init_rwsem(struct rw_semaphore *sem) - -align 4 -init_rwsem: - mov [ecx+RWSEM.wait_list.next], ecx - mov [ecx+RWSEM.wait_list.prev], ecx - mov [ecx+RWSEM.count], 0 - ret - -;void __fastcall down_read(struct rw_semaphore *sem) - -align 4 -down_read: - pushfd - cli - - mov eax, [ecx+RWSEM.count] - test eax, eax - js @F - - cmp ecx, [ecx+RWSEM.wait_list.next] - je .ok -@@: - sub esp, sizeof.MUTEX_WAITER - - mov eax, [TASK_BASE] - mov [esp+MUTEX_WAITER.task], eax - mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_READ - mov [eax+TASKDATA.state], 1 - - list_add_tail esp, ecx ;esp= new waiter, ecx= list head - - call change_task - - add esp, sizeof.MUTEX_WAITER - popfd - ret -.ok: - inc eax - mov [ecx+RWSEM.count], eax - - popfd - ret - -;void __fastcall down_write(struct rw_semaphore *sem) - -align 4 -down_write: - pushfd - cli - sub esp, sizeof.MUTEX_WAITER - - mov edx, [TASK_BASE] - mov [esp+MUTEX_WAITER.task], edx - mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE - mov [edx+TASKDATA.state], 1 - - list_add_tail esp, ecx ;esp= new waiter, ecx= list head - - xor eax, eax - not eax - -.forever: - test eax, [ecx+RWSEM.count] - jz @F - - mov [edx+TASKDATA.state], 1 - call change_task - jmp .forever -@@: - mov [ecx+RWSEM.count], eax - list_del esp - - add esp, sizeof.MUTEX_WAITER - popfd - ret - -;void __fastcall up_read(struct rw_semaphore *sem) - -align 4 -up_read: - pushfd - cli - - dec [ecx+RWSEM.count] - jnz @F - - mov eax, [ecx+RWSEM.wait_list.next] - cmp eax, ecx - je @F - - mov eax, [eax+MUTEX_WAITER.task] - mov [eax+TASKDATA.state], 0 -@@: - popfd - ret - -;void __fastcall up_write(struct rw_semaphore *sem) - -align 4 -up_write: - - pushfd - cli - - mov eax, [ecx+RWSEM.wait_list.next] - mov [ecx+RWSEM.count], 0 - - cmp ecx, eax - je .done - - mov edx, [eax+MUTEX_WAITER.type] - test edx, edx - jnz .wake - - mov eax, [eax+MUTEX_WAITER.task] - mov [eax+TASKDATA.state], 0 -.done: - popfd - ret - -.wake: - push ebx - push esi - push edi - - xor esi, esi - mov edi, ecx - -.wake_list: - - mov ebx, [eax+MUTEX_WAITER.list.next] - list_del eax - mov edx, [eax+MUTEX_WAITER.task] - mov [edx+TASKDATA.state], 0 - inc esi - cmp edi, ebx - je .wake_done - - mov ecx, [ebx+MUTEX_WAITER.type] - test ecx, ecx - jz .wake_done - - mov eax, ebx - jmp .wake_list - -.wake_done: - add [edi+RWSEM.count], esi - - pop edi - pop esi - pop ebx - popfd - ret - - -purge MUTEX_WAITER -purge RWSEM_WAITING_FOR_WRITE -purge RWSEM_WAITING_FOR_READ MAX_PRIORITY = 0 ; highest, used for kernel tasks diff --git a/kernel/trunk/core/sync.inc b/kernel/trunk/core/sync.inc index 329a996db5..afabc4c647 100644 --- a/kernel/trunk/core/sync.inc +++ b/kernel/trunk/core/sync.inc @@ -9,6 +9,490 @@ $Revision$ +align 4 +;struct futex* __fastcall create_futex(int *ptr) +create_futex: + push ecx + mov ecx, sizeof.FUTEX + call create_object + pop ecx + test eax, eax + jz .fail + + mov [eax+FUTEX.magic], 'FUTX' + mov [eax+FUTEX.destroy], 0 + mov [eax+FUTEX.pointer], ecx + lea ecx, [eax+FUTEX.wait_list] + list_init ecx + mov [eax+FUTEX.flags], 0 +.fail: + ret + +align 4 +;int __fastcall destroy_futex(struct futex *futex) +destroy_futex: + push esi + mov esi, [current_process] + mov edx, [ecx+FUTEX.handle] + + pushfd + cli + + lea eax, [ecx+FUTEX.wait_list] + cmp eax, [eax+LHEAD.next] + jne .fail + + mov eax, [esi+PROC.ht_next] + mov [esi+PROC.htab+edx*4], eax + mov [esi+PROC.ht_next], edx + inc [esi+PROC.ht_free] + + popfd + pop esi + + mov eax, ecx + call free + xor eax, eax + ret + +.fail: + popfd + pop esi + mov eax, -1 + ret + + +iglobal +align 4 +f77call: + dd f77.futex_init ;0 + dd f77.futex_destroy ;1 + dd f77.futex_wait ;2 + dd f77.futex_wake ;3 +.end: +endg + +align 4 +sys_synchronization: +f77: + test ebx, ebx + jz .futex_init + + cmp ebx, (f77call.end-f77call)/4 + jae .fail + + cmp ecx, STDERR_FILENO + jbe .fail + cmp ecx, (PROC.pdt_0 - PROC.htab)/4 + jae .fail + + mov edi, [current_process] + mov ebp, [edi+PROC.htab+ecx*4] + + cmp [ebp+FUTEX.magic], 'FUTX' + jne .fail + cmp [ebp+FUTEX.handle], ecx + jne .fail + + jmp dword [f77call+ebx*4] + +.fail: + mov [esp+SYSCALL_STACK._eax], -1 + ret + +align 4 +.futex_init: + call create_futex + test eax, eax + jz @F + mov eax, [eax+FUTEX.handle] +@@: + mov [esp+SYSCALL_STACK._eax], eax + ret + + +align 4 +;ecx futex handle +;edi current process +;ebp futex object +.futex_destroy: + mov ecx, ebp + call destroy_futex + mov [esp+SYSCALL_STACK._eax], eax + ret + +align 4 +;ecx futex handle +;edx control value +;esi timeout +;edi current process +;ebp futex object +.futex_wait: + test esi, esi + jnz .futex_wait_timeout + mov ecx, [ebp+FUTEX.pointer] + mov eax, edx + lock cmpxchg [ecx], edx ;wait until old_value == new_value + jz .wait_slow + + mov [esp+SYSCALL_STACK._eax], 0 + ret + +.wait_slow: + pushfd + cli + + sub esp, sizeof.MUTEX_WAITER + mov ebx, [TASK_BASE] + mov [esp+MUTEX_WAITER.task], ebx + lea esi, [ebp+FUTEX.wait_list] + + list_add_tail esp, esi ;esp= new waiter, esi= list head + +.again: + mov [ebx+TASKDATA.state], 1 + call change_task + + lock cmpxchg [ecx], edx + jz .again + + list_del esp + add esp, sizeof.MUTEX_WAITER + + popfd + mov [esp+SYSCALL_STACK._eax], 0 + ret + +align 4 +;ecx futex handle +;edx control value +;esi timeout +;edi current process +;ebp futex object + +.futex_wait_timeout: + mov ecx, [ebp+FUTEX.pointer] + mov eax, edx + lock cmpxchg [ecx], edx ;wait until old_value == new_value + jz .wait_slow_timeout + + mov [esp+SYSCALL_STACK._eax], 0 + ret + +align 4 +.wait_test: + xor eax, eax + ret + +.wait_slow_timeout: + pushfd + cli + + sub esp, sizeof.MUTEX_WAITER + + mov ebx, [current_slot] + mov [ebx+APPDATA.wait_test], f77.wait_test + mov [ebx+APPDATA.wait_timeout], esi + mov [ebx+APPDATA.wait_param], ebp + mov eax, [timer_ticks] + mov [ebx+APPDATA.wait_begin], eax + mov eax, [TASK_BASE] + mov [eax+TASKDATA.state], 5 + + mov [esp+MUTEX_WAITER.task], eax + lea esi, [ebp+FUTEX.wait_list] + + list_add_tail esp, esi ;esp= new waiter, esi= list head + +.again_timeout: + call change_task + mov eax, [ebx+APPDATA.wait_param] + test eax, eax + jz .timeout + + lock cmpxchg [ecx], edx + jz .again_timeout +@@: + list_del esp + add esp, sizeof.MUTEX_WAITER + + popfd + mov [esp+SYSCALL_STACK._eax], 0 + ret + +.timeout: + list_del esp + add esp, sizeof.MUTEX_WAITER + + popfd + mov [esp+SYSCALL_STACK._eax], -1 + ret + + +align 4 +;ecx futex handle +;edx number of threads +;edi current process +;ebp futex object +.futex_wake: + + xor ecx, ecx + + pushfd + cli + + lea ebx, [ebp+FUTEX.wait_list] + mov esi, [ebx+LHEAD.next] +.wake: + cmp esi, ebx + je .done + + mov eax, [esi+MUTEX_WAITER.task] + mov [eax+TASKDATA.state], 0 + + mov esi, [esi+MUTEX_WAITER.list.next] + inc ecx + cmp ecx, edx + jb .wake +.done: + popfd + mov [esp+SYSCALL_STACK._eax], ecx + ret + +RWSEM_WAITING_FOR_WRITE equ 0 +RWSEM_WAITING_FOR_READ equ 1 + +;void __fastcall mutex_init(struct mutex *lock) + +align 4 +mutex_init: + mov [ecx+MUTEX.wait_list.next], ecx + mov [ecx+MUTEX.wait_list.prev], ecx + mov [ecx+MUTEX.count], 1 + ret + +;void __fastcall mutex_lock(struct mutex *lock) + +align 4 +mutex_lock: + + dec [ecx+MUTEX.count] + jns .done + + pushfd + cli + + sub esp, sizeof.MUTEX_WAITER + + list_add_tail esp, ecx ;esp= new waiter, ecx= list head + + mov edx, [TASK_BASE] + mov [esp+MUTEX_WAITER.task], edx + +.forever: + + mov eax, -1 + xchg eax, [ecx+MUTEX.count] + dec eax + jz @F + + mov [edx+TASKDATA.state], 1 + call change_task + jmp .forever +@@: + mov eax, ecx + list_del esp + + cmp [eax+MUTEX.wait_list.next], eax + jne @F + + mov [eax+MUTEX.count], 0 +@@: + add esp, sizeof.MUTEX_WAITER + + popfd +.done: + ret + +;void __fastcall mutex_unlock(struct mutex *lock) + +align 4 +mutex_unlock: + + pushfd + cli + + mov eax, [ecx+MUTEX.wait_list.next] + cmp eax, ecx + mov [ecx+MUTEX.count], 1 + je @F + + mov eax, [eax+MUTEX_WAITER.task] + mov [eax+TASKDATA.state], 0 +@@: + popfd + ret + + +;void __fastcall init_rwsem(struct rw_semaphore *sem) + +align 4 +init_rwsem: + mov [ecx+RWSEM.wait_list.next], ecx + mov [ecx+RWSEM.wait_list.prev], ecx + mov [ecx+RWSEM.count], 0 + ret + +;void __fastcall down_read(struct rw_semaphore *sem) + +align 4 +down_read: + pushfd + cli + + mov eax, [ecx+RWSEM.count] + test eax, eax + js @F + + cmp ecx, [ecx+RWSEM.wait_list.next] + je .ok +@@: + sub esp, sizeof.MUTEX_WAITER + + mov eax, [TASK_BASE] + mov [esp+MUTEX_WAITER.task], eax + mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_READ + mov [eax+TASKDATA.state], 1 + + list_add_tail esp, ecx ;esp= new waiter, ecx= list head + + call change_task + + add esp, sizeof.MUTEX_WAITER + popfd + ret +.ok: + inc eax + mov [ecx+RWSEM.count], eax + + popfd + ret + +;void __fastcall down_write(struct rw_semaphore *sem) + +align 4 +down_write: + pushfd + cli + sub esp, sizeof.MUTEX_WAITER + + mov edx, [TASK_BASE] + mov [esp+MUTEX_WAITER.task], edx + mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE + mov [edx+TASKDATA.state], 1 + + list_add_tail esp, ecx ;esp= new waiter, ecx= list head + + xor eax, eax + not eax + +.forever: + test eax, [ecx+RWSEM.count] + jz @F + + mov [edx+TASKDATA.state], 1 + call change_task + jmp .forever +@@: + mov [ecx+RWSEM.count], eax + list_del esp + + add esp, sizeof.MUTEX_WAITER + popfd + ret + +;void __fastcall up_read(struct rw_semaphore *sem) + +align 4 +up_read: + pushfd + cli + + dec [ecx+RWSEM.count] + jnz @F + + mov eax, [ecx+RWSEM.wait_list.next] + cmp eax, ecx + je @F + + mov eax, [eax+MUTEX_WAITER.task] + mov [eax+TASKDATA.state], 0 +@@: + popfd + ret + +;void __fastcall up_write(struct rw_semaphore *sem) + +align 4 +up_write: + + pushfd + cli + + mov eax, [ecx+RWSEM.wait_list.next] + mov [ecx+RWSEM.count], 0 + + cmp ecx, eax + je .done + + mov edx, [eax+MUTEX_WAITER.type] + test edx, edx + jnz .wake + + mov eax, [eax+MUTEX_WAITER.task] + mov [eax+TASKDATA.state], 0 +.done: + popfd + ret + +.wake: + push ebx + push esi + push edi + + xor esi, esi + mov edi, ecx + +.wake_list: + + mov ebx, [eax+MUTEX_WAITER.list.next] + list_del eax + mov edx, [eax+MUTEX_WAITER.task] + mov [edx+TASKDATA.state], 0 + inc esi + cmp edi, ebx + je .wake_done + + mov ecx, [ebx+MUTEX_WAITER.type] + test ecx, ecx + jz .wake_done + + mov eax, ebx + jmp .wake_list + +.wake_done: + add [edi+RWSEM.count], esi + + pop edi + pop esi + pop ebx + popfd + ret + + +purge RWSEM_WAITING_FOR_WRITE +purge RWSEM_WAITING_FOR_READ + if ~defined sync_inc sync_inc_fix: diff --git a/kernel/trunk/core/syscall.inc b/kernel/trunk/core/syscall.inc index 696e662682..7ff76dd9e1 100644 --- a/kernel/trunk/core/syscall.inc +++ b/kernel/trunk/core/syscall.inc @@ -175,6 +175,8 @@ iglobal dd sys_network ; 74-reserved for new stack dd sys_socket ; 75-reserved for new stack dd sys_protocols ; 76-reserved for new stack + dd sys_synchronization ; 77 + times 255 - ( ($-servetable2) /4 ) dd undefined_syscall dd sys_end ; -1-end application diff --git a/kernel/trunk/docs/sysfuncs.txt b/kernel/trunk/docs/sysfuncs.txt index 0fe7fd3a53..edb9a382c5 100644 --- a/kernel/trunk/docs/sysfuncs.txt +++ b/kernel/trunk/docs/sysfuncs.txt @@ -919,7 +919,7 @@ Format of the table: short version: For example, for the standard configuration from one 1.44-drive here will be 40h, and for the case 1.2Mb on A: and 1.44Mb on B: the value is 24h. - + First IDE controller: * +1: byte: information about hard disks and CD-drives, AABBCCDD, where AA corresponds to the controller IDE0, ..., DD - IDE3: @@ -930,7 +930,7 @@ Format of the table: short version: this field contains 48h. * +2: 4 db: number of the retrieved partitions on hard disks at accordingly IDE0,...,IDE3. - + Second IDE controller: * +6: byte: information about hard disks and CD-drives, AABBCCDD, where AA corresponds to the controller IDE4, ..., DD - IDE7: @@ -951,8 +951,8 @@ Format of the table: short version: For example, in the case HD on IDE8 and CD on IDE10 this field contains 48h. * +12: 4 db: number of the retrieved partitions on hard disks - at accordingly IDE8,...,IDE11. - + at accordingly IDE8,...,IDE11. + If the hard disk on IDEx is absent, appropriate byte is zero, otherwise it shows number of the recognized partitions, which can be not presented (if the drive is not formatted or if @@ -1631,7 +1631,7 @@ Returned value: Remarks: * Counter takes modulo 2^32, that correspond to a little more than 497 days. - * To get system time use function 3. + * To get system time use function 3. ---------------------- Constants for registers: ---------------------- eax - SF_SYSTEM_GET (26) @@ -1645,7 +1645,7 @@ Parameters: * ebx = 10 - subfunction number Returned value: * eax = number of nanoseconds since system boot time (lower DWORD) - * edx = number of nanoseconds since system boot time (high DWORD) + * edx = number of nanoseconds since system boot time (high DWORD) Remarks: * The counter is based on HPET, if HPET is not available, resolution will be reduced to 10 000 000 nanoseconds. @@ -2517,7 +2517,7 @@ Returned value: * eax = if successful - pointer to a memory with data * eax = 1 - error * eax = -1 - main list area not found - + ---------------------- Constants for registers: ---------------------- eax - SF_CLIPBOARD (54) ebx - SSF_READ_CB (1) @@ -4665,7 +4665,7 @@ Returned value: * ebx = errorcode Remarks: - Optstruct: + Optstruct: dd level dd optionname dd optlength @@ -4687,7 +4687,7 @@ Returned value: * ebx = errorcode Remarks: - Optstruct: + Optstruct: dd level dd optionname dd optlength @@ -4720,7 +4720,7 @@ Parameters: Ethernet (0) 0 - Read MAC - + IPv4 (1) 0 - Read # IP packets sent 1 - Read # IP packets received @@ -4732,7 +4732,7 @@ IPv4 (1) 7 - Write subnet 8 - Read gateway 9 - Write gateway - + ICMP (2) 0 - Read # ICMP packets sent 1 - Read # ICMP packets received @@ -4744,8 +4744,8 @@ UDP (3) TCP (4) 0 - Read # TCP packets sent - 1 - Read # TCP packets received - + 1 - Read # TCP packets received + ARP (5) 0 - Read # ARP packets sent 1 - Read # ARP packets received @@ -4754,10 +4754,70 @@ ARP (5) 4 - Add static ARP entry 5 - Remove ARP entry (-1 = remove all) 6 - Send ARP announce on specified interface - 7 - Read # ARP conflicts (IP address conflicts) + 7 - Read # ARP conflicts (IP address conflicts) ---------------------- Constants for registers: ---------------------- eax - SF_NETWORK_PROTOCOL (76) + +====================================================================== +========== Function 77, Subfunction 0, Create futex object =========== +====================================================================== +Parameters: + * eax = 77 - function number + * ebx = 0 - subfunction number + * ecx = pointer to futex dword +Returned value: + * eax = futex handle, 0 on error +Remarks: + * Use subfunction 1 to destroy the futex. + The kernel destroys the futexes automatically when the process + terminates. +====================================================================== +========= Function 77, Subfunction 1, Destroy futex object =========== +====================================================================== +Parameters: + * eax = 77 - function number + * ebx = 1 - subfunction number + * ecx = futex handle +Returned value: + * eax = 0 - successfull, -1 on error +Remarks: + * The futex handle must have been created by subfunction 0 + +====================================================================== +=============== Function 77, Subfunction 2, Futex wait =============== +====================================================================== +Parameters: + * eax = 77 - function number + * ebx = 2 - subfunction number + * ecx = futex handle + * edx = control value + * esi = timeout in system ticks or 0 for infinity +Returned value: + * eax = 0 - successfull, -1 on timeout + +Remarks: + * This functionn tests that the value at the futex dword still + contains the expected control value, and if so, then sleeps + waiting for a wake operation on the futex. + * The futex handle must have been created by subfunction 0 + +====================================================================== +=============== Function 77, Subfunction 3, Futex wake =============== +====================================================================== +Parameters: + * eax = 77 - function number + * ebx = 3 - subfunction number + * ecx = futex handle + * edx = number of waiters to wake +Returned value: + * eax = number of waiters that were woken up + +Remarks: + * This function wakes at most edx of the waiters that are + waiting (e.g., inside futex wait) on the futex dword + * The futex handle must have been created by subfunction 0 + ====================================================================== =============== Function -1 - terminate thread/process =============== ====================================================================== diff --git a/kernel/trunk/kernel32.inc b/kernel/trunk/kernel32.inc index 8f14239c9e..6706827c8a 100644 --- a/kernel/trunk/kernel32.inc +++ b/kernel/trunk/kernel32.inc @@ -15,197 +15,6 @@ $Revision$ -struct POINT - x dd ? - y dd ? -ends - -struct RECT - left dd ? - top dd ? - right dd ? - bottom dd ? -ends - -struct BOX - left dd ? - top dd ? - width dd ? - height dd ? -ends - -struct DISPMODE - width dw ? - height dw ? - bpp dw ? - freq dw ? -ends - -; constants definition -WSTATE_NORMAL = 00000000b -WSTATE_MAXIMIZED = 00000001b -WSTATE_MINIMIZED = 00000010b -WSTATE_ROLLEDUP = 00000100b - -WSTATE_REDRAW = 00000001b -WSTATE_WNDDRAWN = 00000010b - -WSTYLE_HASCAPTION = 00010000b -WSTYLE_CLIENTRELATIVE = 00100000b - -struct TASKDATA - event_mask dd ? - pid dd ? - dw ? - state db ? - db ? - dw ? - wnd_number db ? - db ? - mem_start dd ? - counter_sum dd ? - counter_add dd ? - cpu_usage dd ? -ends - -TSTATE_RUNNING = 0 -TSTATE_RUN_SUSPENDED = 1 -TSTATE_WAIT_SUSPENDED = 2 -TSTATE_ZOMBIE = 3 -TSTATE_TERMINATING = 4 -TSTATE_WAITING = 5 -TSTATE_FREE = 9 - -ZPOS_DESKTOP = -2 -ZPOS_ALWAYS_BACK = -1 -ZPOS_NORMAL = 0 -ZPOS_ALWAYS_TOP = 1 ;ZPOS_ALWAYS_TOP is always last and has max number! -; structures definition -struct WDATA - box BOX - cl_workarea dd ? - cl_titlebar dd ? - cl_frames dd ? - z_modif db ? - fl_wstate db ? - fl_wdrawn db ? - fl_redraw db ? -ends - -label WDATA.fl_wstyle byte at WDATA.cl_workarea + 3 - -struct DBG_REGS - dr0 dd ? - dr1 dd ? - dr2 dd ? - dr3 dd ? - dr7 dd ? -ends - -struct PROC - list LHEAD - thr_list LHEAD - heap_lock MUTEX - heap_base rd 1 - heap_top rd 1 - mem_used rd 1 - dlls_list_ptr rd 1 - pdt_0_phys rd 1 - pdt_1_phys rd 1 - io_map_0 rd 1 - io_map_1 rd 1 - - ht_lock rd 1 - ht_free rd 1 ;htab[0] stdin - ht_next rd 1 ;htab[1] stdout - htab rd (4096-$)/4 ;htab[2] stderr - pdt_0 rd 1024 -ends - -struct APPDATA - app_name rb 11 - rb 5 - - list LHEAD ;+16 - process dd ? ;+24 - fpu_state dd ? ;+28 - exc_handler dd ? ;+32 - except_mask dd ? ;+36 - pl0_stack dd ? ;+40 - cursor dd ? ;+44 - fd_ev dd ? ;+48 - bk_ev dd ? ;+52 - fd_obj dd ? ;+56 - bk_obj dd ? ;+60 - saved_esp dd ? ;+64 - io_map rd 2 ;+68 - dbg_state dd ? ;+76 - cur_dir dd ? ;+80 - wait_timeout dd ? ;+84 - saved_esp0 dd ? ;+88 - wait_begin dd ? ;+92 +++ - wait_test dd ? ;+96 +++ - wait_param dd ? ;+100 +++ - tls_base dd ? ;+104 - dd ? ;+108 - event_filter dd ? ;+112 - draw_bgr_x dd ? ;+116 - draw_bgr_y dd ? ;+120 - dd ? ;+124 - - wnd_shape dd ? ;+128 - wnd_shape_scale dd ? ;+132 - dd ? ;+136 - dd ? ;+140 - saved_box BOX ;+144 - ipc_start dd ? ;+160 - ipc_size dd ? ;+164 - event_mask dd ? ;+168 - debugger_slot dd ? ;+172 - terminate_protection dd ? ;+176 - keyboard_mode db ? ;+180 - rb 3 - dd ? ;+184 - dbg_event_mem dd ? ;+188 - dbg_regs DBG_REGS ;+192 - wnd_caption dd ? ;+212 - wnd_clientbox BOX ;+216 - priority dd ? ;+232 - in_schedule LHEAD ;+236 - -ends - -struct IDE_DATA - ProgrammingInterface dd ? - Interrupt dw ? - RegsBaseAddres dw ? - BAR0_val dw ? - BAR1_val dw ? - BAR2_val dw ? - BAR3_val dw ? - dma_hdd_channel_1 db ? - dma_hdd_channel_2 db ? -ends - -struct IDE_CACHE - pointer dd ? - size dd ? ; not use - data_pointer dd ? - system_data_size dd ? ; not use - appl_data_size dd ? ; not use - system_data dd ? - appl_data dd ? - system_sad_size dd ? - appl_sad_size dd ? - search_start dd ? - appl_search_start dd ? -ends - -struct IDE_DEVICE - UDMA_possible_modes db ? - UDMA_set_mode db ? -ends - ; Core functions include "core/sync.inc" ; macros for synhronization objects include "core/sys32.inc" ; process management