kernel: read/write locks, part 2

git-svn-id: svn://kolibrios.org@5344 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
Sergey Semyonov (Serge) 2015-01-04 15:21:46 +00:00
parent 92d3d6c2c8
commit 966e9d897b
2 changed files with 99 additions and 3 deletions

View File

@ -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

View File

@ -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