forked from KolibriOS/kolibrios
kernel: pipes - improved synchronization
git-svn-id: svn://kolibrios.org@6929 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
65af271ccd
commit
8b1036ed49
@ -418,6 +418,7 @@ struct FILED
|
|||||||
magic rd 1
|
magic rd 1
|
||||||
handle rd 1
|
handle rd 1
|
||||||
destroy rd 1
|
destroy rd 1
|
||||||
|
mode rd 1
|
||||||
file rd 1
|
file rd 1
|
||||||
ends
|
ends
|
||||||
|
|
||||||
|
@ -7,6 +7,9 @@
|
|||||||
|
|
||||||
$Revision: 6917 $
|
$Revision: 6917 $
|
||||||
|
|
||||||
|
F_READ equ 0x0001 ; file opened for reading
|
||||||
|
F_WRITE equ 0x0002 ; file opened for writing
|
||||||
|
|
||||||
O_CLOEXEC equ 0x40000
|
O_CLOEXEC equ 0x40000
|
||||||
PIPE_BUFFER_SIZE equ 4096
|
PIPE_BUFFER_SIZE equ 4096
|
||||||
|
|
||||||
@ -96,10 +99,12 @@ sys_pipe2:
|
|||||||
|
|
||||||
mov [eax+FILED.magic], 'PIPE'
|
mov [eax+FILED.magic], 'PIPE'
|
||||||
mov [eax+FILED.destroy], 0
|
mov [eax+FILED.destroy], 0
|
||||||
|
mov [eax+FILED.mode], F_READ
|
||||||
mov [eax+FILED.file], ebp
|
mov [eax+FILED.file], ebp
|
||||||
|
|
||||||
mov [edx+FILED.magic], 'PIPE'
|
mov [edx+FILED.magic], 'PIPE'
|
||||||
mov [edx+FILED.destroy], 0
|
mov [edx+FILED.destroy], 0
|
||||||
|
mov [edx+FILED.mode], F_WRITE
|
||||||
mov [edx+FILED.file], ebp
|
mov [edx+FILED.file], ebp
|
||||||
|
|
||||||
mov eax, [eax+FILED.handle]
|
mov eax, [eax+FILED.handle]
|
||||||
@ -125,8 +130,9 @@ sys_pipe2:
|
|||||||
.err_0:
|
.err_0:
|
||||||
add esp, 5*4
|
add esp, 5*4
|
||||||
.fail:
|
.fail:
|
||||||
mov [esp+SYSCALL_STACK._eax], ebp
|
mov eax, ebp
|
||||||
pop ebp
|
pop ebp
|
||||||
|
mov [esp+SYSCALL_STACK._eax], eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
purge .pipeflags
|
purge .pipeflags
|
||||||
@ -136,18 +142,18 @@ purge .fdwrite
|
|||||||
purge .intpipe
|
purge .intpipe
|
||||||
|
|
||||||
|
|
||||||
; edx buf
|
; edx dst_buf
|
||||||
; esi count
|
; esi read count
|
||||||
; ebp pipe
|
; ebp pipe
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
pipe_read:
|
pipe_read:
|
||||||
|
|
||||||
mov edi, edx
|
mov edi, edx
|
||||||
|
|
||||||
.again:
|
|
||||||
lea ecx, [ebp+PIPE.pipe_lock]
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
call mutex_lock
|
call mutex_lock
|
||||||
|
.again:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
cmp eax, [ebp+PIPE.writers]
|
cmp eax, [ebp+PIPE.writers]
|
||||||
je .eof
|
je .eof
|
||||||
@ -170,11 +176,31 @@ pipe_read:
|
|||||||
and esi, 0xFFF
|
and esi, 0xFFF
|
||||||
mov [ebp+PIPE.read_end], esi
|
mov [ebp+PIPE.read_end], esi
|
||||||
|
|
||||||
|
lea ecx, [ebp+PIPE.wlist]
|
||||||
|
cmp ecx, [ebp+PIPE.wlist.next]
|
||||||
|
je @F
|
||||||
|
|
||||||
|
mov ecx, [ecx+MUTEX_WAITER.task]
|
||||||
|
mov [ecx+TASKDATA.state], 0 ;activate writer task
|
||||||
|
@@:
|
||||||
|
cmp [ebp+PIPE.count], 0
|
||||||
|
je @F
|
||||||
|
|
||||||
|
lea eax, [ebp+PIPE.rlist]
|
||||||
|
cmp eax, [ebp+PIPE.rlist.next]
|
||||||
|
je @F
|
||||||
|
|
||||||
|
mov eax, [eax+MUTEX_WAITER.task]
|
||||||
|
mov [eax+TASKDATA.state], 0 ;activate reader task
|
||||||
|
@@:
|
||||||
lea ecx, [ebp+PIPE.pipe_lock]
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.wait:
|
.wait:
|
||||||
|
pushfd
|
||||||
|
cli
|
||||||
|
|
||||||
sub esp, sizeof.MUTEX_WAITER
|
sub esp, sizeof.MUTEX_WAITER
|
||||||
mov ebx, [TASK_BASE]
|
mov ebx, [TASK_BASE]
|
||||||
mov [esp+MUTEX_WAITER.task], ebx
|
mov [esp+MUTEX_WAITER.task], ebx
|
||||||
@ -188,8 +214,12 @@ pipe_read:
|
|||||||
mov [ebx+TASKDATA.state], 1
|
mov [ebx+TASKDATA.state], 1
|
||||||
call change_task
|
call change_task
|
||||||
|
|
||||||
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
|
call mutex_lock
|
||||||
|
|
||||||
list_del esp
|
list_del esp
|
||||||
add esp, sizeof.MUTEX_WAITER
|
add esp, sizeof.MUTEX_WAITER
|
||||||
|
popfd
|
||||||
jmp .again
|
jmp .again
|
||||||
|
|
||||||
.eof:
|
.eof:
|
||||||
@ -198,49 +228,85 @@ pipe_read:
|
|||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
ret
|
ret
|
||||||
|
|
||||||
; edx buf
|
; edx src_buf
|
||||||
; esi count
|
; esi write count
|
||||||
; ebp pipe
|
; ebp pipe
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
pipe_write:
|
pipe_write:
|
||||||
mov edi, edx
|
|
||||||
|
|
||||||
.again:
|
.written equ esp
|
||||||
|
|
||||||
|
push 0 ;written
|
||||||
|
mov ebx, esi ;ebx = write count
|
||||||
|
mov esi, edx ;esi = src
|
||||||
|
|
||||||
lea ecx, [ebp+PIPE.pipe_lock]
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
call mutex_lock
|
call mutex_lock
|
||||||
|
.again:
|
||||||
xor eax, eax
|
xor eax, eax
|
||||||
cmp eax, [ebp+PIPE.readers]
|
cmp eax, [ebp+PIPE.readers]
|
||||||
je .epipe
|
je .epipe
|
||||||
|
|
||||||
mov ecx, [ebp+PIPE.count]
|
mov ecx, 4096
|
||||||
sub ecx, 4096
|
sub ecx, [ebp+PIPE.count]
|
||||||
jz .wait
|
jz .wait ;wait if buffer full
|
||||||
|
|
||||||
.check_count:
|
.check_count:
|
||||||
cmp ecx, esi
|
cmp ecx, ebx
|
||||||
jb .write
|
jb .write
|
||||||
mov ecx, esi
|
mov ecx, ebx
|
||||||
.write:
|
.write:
|
||||||
mov esi, edi
|
|
||||||
mov edi, [ebp+PIPE.buffer]
|
mov edi, [ebp+PIPE.buffer]
|
||||||
add edi, [ebp+PIPE.write_end]
|
add edi, [ebp+PIPE.write_end]
|
||||||
mov [esp+SYSCALL_STACK._eax], ecx
|
add [.written], ecx
|
||||||
|
sub ebx, ecx
|
||||||
add [ebp+PIPE.count], ecx
|
add [ebp+PIPE.count], ecx
|
||||||
|
|
||||||
cld
|
cld
|
||||||
rep movsb
|
rep movsb
|
||||||
and edi, 0xFFF
|
and edi, 0xFFF
|
||||||
mov [ebp+PIPE.write_end], edi
|
mov [ebp+PIPE.write_end], edi
|
||||||
|
|
||||||
|
pushfd
|
||||||
|
cli
|
||||||
|
|
||||||
|
lea eax, [ebp+PIPE.rlist]
|
||||||
|
cmp eax, [ebp+PIPE.rlist.next]
|
||||||
|
je @F
|
||||||
|
|
||||||
|
mov eax, [eax+MUTEX_WAITER.task]
|
||||||
|
mov [eax+TASKDATA.state], 0 ;activate reader task
|
||||||
|
@@:
|
||||||
|
cmp [ebp+PIPE.count], 4096
|
||||||
|
je @F
|
||||||
|
|
||||||
|
lea ecx, [ebp+PIPE.wlist]
|
||||||
|
cmp ecx, [ebp+PIPE.wlist.next]
|
||||||
|
je @F
|
||||||
|
|
||||||
|
mov ecx, [eax+MUTEX_WAITER.task]
|
||||||
|
mov [ecx+TASKDATA.state], 0 ;activate writer task
|
||||||
|
@@:
|
||||||
|
popfd
|
||||||
|
|
||||||
lea ecx, [ebp+PIPE.pipe_lock]
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
|
|
||||||
|
test ebx, ebx
|
||||||
|
jnz .again
|
||||||
|
|
||||||
|
pop eax ; written
|
||||||
|
mov [esp+SYSCALL_STACK._eax], eax
|
||||||
ret
|
ret
|
||||||
|
|
||||||
.wait:
|
.wait:
|
||||||
|
pushfd
|
||||||
|
cli
|
||||||
|
|
||||||
sub esp, sizeof.MUTEX_WAITER
|
sub esp, sizeof.MUTEX_WAITER
|
||||||
mov ebx, [TASK_BASE]
|
mov ecx, [TASK_BASE]
|
||||||
mov [esp+MUTEX_WAITER.task], ebx
|
mov [esp+MUTEX_WAITER.task], ecx
|
||||||
lea edx, [ebp+PIPE.wlist]
|
lea edx, [ebp+PIPE.wlist]
|
||||||
|
|
||||||
list_add_tail esp, edx ;esp= new waiter, edx= list head
|
list_add_tail esp, edx ;esp= new waiter, edx= list head
|
||||||
@ -248,17 +314,23 @@ pipe_write:
|
|||||||
lea ecx, [ebp+PIPE.pipe_lock]
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
|
|
||||||
mov [ebx+TASKDATA.state], 1
|
mov [ecx+TASKDATA.state], 1
|
||||||
call change_task
|
call change_task
|
||||||
|
|
||||||
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
|
call mutex_lock
|
||||||
|
|
||||||
list_del esp
|
list_del esp
|
||||||
add esp, sizeof.MUTEX_WAITER
|
add esp, sizeof.MUTEX_WAITER
|
||||||
|
popfd
|
||||||
jmp .again
|
jmp .again
|
||||||
|
|
||||||
.epipe:
|
.epipe:
|
||||||
mov [esp+SYSCALL_STACK._eax], -EPIPE
|
|
||||||
lea ecx, [ebp+PIPE.pipe_lock]
|
lea ecx, [ebp+PIPE.pipe_lock]
|
||||||
call mutex_unlock
|
call mutex_unlock
|
||||||
|
|
||||||
|
add esp, 4
|
||||||
|
mov [esp+SYSCALL_STACK._eax], -EPIPE
|
||||||
ret
|
ret
|
||||||
|
|
||||||
align 4
|
align 4
|
||||||
|
@ -88,6 +88,9 @@ sys_read:
|
|||||||
cmp [ebp+FILED.handle], ecx
|
cmp [ebp+FILED.handle], ecx
|
||||||
jne .fail
|
jne .fail
|
||||||
|
|
||||||
|
test [ebp+FILED.mode], F_READ
|
||||||
|
jz .fail
|
||||||
|
|
||||||
mov ebp, [ebp+FILED.file]
|
mov ebp, [ebp+FILED.file]
|
||||||
mov eax, [ebp]
|
mov eax, [ebp]
|
||||||
jmp dword [eax+FILEOP_READ*4]
|
jmp dword [eax+FILEOP_READ*4]
|
||||||
@ -114,6 +117,8 @@ sys_write:
|
|||||||
jne .fail
|
jne .fail
|
||||||
cmp [ebp+FILED.handle], ecx
|
cmp [ebp+FILED.handle], ecx
|
||||||
jne .fail
|
jne .fail
|
||||||
|
test [ebp+FILED.mode], F_WRITE
|
||||||
|
jz .fail
|
||||||
|
|
||||||
mov ebp, [ebp+FILED.file]
|
mov ebp, [ebp+FILED.file]
|
||||||
mov eax, [ebp]
|
mov eax, [ebp]
|
||||||
|
Loading…
Reference in New Issue
Block a user