mirror of
https://github.com/KolibriOS/kolibrios.git
synced 2024-12-24 23:56:49 +03:00
kernel: read/write locks, part 2
git-svn-id: svn://kolibrios.org@5344 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
92d3d6c2c8
commit
966e9d897b
@ -45,8 +45,11 @@ __exports:
|
||||
release_pages, 'ReleasePages', \
|
||||
alloc_dma24, 'AllocDMA24', \ ; stdcall
|
||||
\
|
||||
init_rwsem, 'InitRwsem', \ ; gcc fastcall
|
||||
down_read, 'DownRead', \ ; gcc fastcall
|
||||
down_write, 'DownWrite', \ ; gcc fastcall
|
||||
up_read, 'UpRead', \ ; gcc fastcall
|
||||
up_write, 'UpWrite', \ ; gcc fastacll
|
||||
mutex_init, 'MutexInit', \ ; gcc fastcall
|
||||
mutex_lock, 'MutexLock', \ ; gcc fastcall
|
||||
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
|
||||
|
@ -155,13 +155,15 @@ 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
|
||||
@ -234,6 +236,15 @@ mutex_unlock:
|
||||
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
|
||||
@ -252,7 +263,7 @@ down_read:
|
||||
|
||||
mov eax, [TASK_BASE]
|
||||
mov [esp+MUTEX_WAITER.task], eax
|
||||
mov [esp+MUTEX_WAITER.type], 1; RWSEM_WAITING_FOR_READ
|
||||
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
|
||||
@ -279,7 +290,7 @@ down_write:
|
||||
|
||||
mov edx, [TASK_BASE]
|
||||
mov [esp+MUTEX_WAITER.task], edx
|
||||
mov [esp+MUTEX_WAITER.type], 2; RWSEM_WAITING_FOR_WRITE
|
||||
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
|
||||
@ -302,7 +313,89 @@ down_write:
|
||||
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
|
||||
USER_PRIORITY = 1 ; default
|
||||
|
Loading…
Reference in New Issue
Block a user