forked from KolibriOS/kolibrios
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', \
|
release_pages, 'ReleasePages', \
|
||||||
alloc_dma24, 'AllocDMA24', \ ; stdcall
|
alloc_dma24, 'AllocDMA24', \ ; stdcall
|
||||||
\
|
\
|
||||||
|
init_rwsem, 'InitRwsem', \ ; gcc fastcall
|
||||||
down_read, 'DownRead', \ ; gcc fastcall
|
down_read, 'DownRead', \ ; gcc fastcall
|
||||||
down_write, 'DownWrite', \ ; gcc fastcall
|
down_write, 'DownWrite', \ ; gcc fastcall
|
||||||
|
up_read, 'UpRead', \ ; gcc fastcall
|
||||||
|
up_write, 'UpWrite', \ ; gcc fastacll
|
||||||
mutex_init, 'MutexInit', \ ; gcc fastcall
|
mutex_init, 'MutexInit', \ ; gcc fastcall
|
||||||
mutex_lock, 'MutexLock', \ ; gcc fastcall
|
mutex_lock, 'MutexLock', \ ; gcc fastcall
|
||||||
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
|
mutex_unlock, 'MutexUnlock', \ ; gcc fastcall
|
||||||
|
@ -155,13 +155,15 @@ do_change_task:
|
|||||||
;end.
|
;end.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
struct MUTEX_WAITER
|
struct MUTEX_WAITER
|
||||||
list LHEAD
|
list LHEAD
|
||||||
task dd ?
|
task dd ?
|
||||||
type dd ?
|
type dd ?
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
RWSEM_WAITING_FOR_WRITE equ 0
|
||||||
|
RWSEM_WAITING_FOR_READ equ 1
|
||||||
|
|
||||||
;void __fastcall mutex_init(struct mutex *lock)
|
;void __fastcall mutex_init(struct mutex *lock)
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -234,6 +236,15 @@ mutex_unlock:
|
|||||||
ret
|
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)
|
;void __fastcall down_read(struct rw_semaphore *sem)
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
@ -252,7 +263,7 @@ down_read:
|
|||||||
|
|
||||||
mov eax, [TASK_BASE]
|
mov eax, [TASK_BASE]
|
||||||
mov [esp+MUTEX_WAITER.task], eax
|
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
|
mov [eax+TASKDATA.state], 1
|
||||||
|
|
||||||
list_add_tail esp, ecx ;esp= new waiter, ecx= list head
|
list_add_tail esp, ecx ;esp= new waiter, ecx= list head
|
||||||
@ -279,7 +290,7 @@ down_write:
|
|||||||
|
|
||||||
mov edx, [TASK_BASE]
|
mov edx, [TASK_BASE]
|
||||||
mov [esp+MUTEX_WAITER.task], edx
|
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
|
mov [edx+TASKDATA.state], 1
|
||||||
|
|
||||||
list_add_tail esp, ecx ;esp= new waiter, ecx= list head
|
list_add_tail esp, ecx ;esp= new waiter, ecx= list head
|
||||||
@ -302,7 +313,89 @@ down_write:
|
|||||||
popfd
|
popfd
|
||||||
ret
|
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 MUTEX_WAITER
|
||||||
|
purge RWSEM_WAITING_FOR_WRITE
|
||||||
|
purge RWSEM_WAITING_FOR_READ
|
||||||
|
|
||||||
|
|
||||||
MAX_PRIORITY = 0 ; highest, used for kernel tasks
|
MAX_PRIORITY = 0 ; highest, used for kernel tasks
|
||||||
USER_PRIORITY = 1 ; default
|
USER_PRIORITY = 1 ; default
|
||||||
|
Loading…
Reference in New Issue
Block a user