Subversion Repositories Kolibri OS

Rev

Rev 6926 | Rev 6928 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6926 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2017. All rights reserved. ;;
4
;;  Distributed under terms of the GNU General Public License.  ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8
$Revision: 6917 $
9
 
10
O_CLOEXEC           equ 0x40000
11
PIPE_BUFFER_SIZE    equ 4096
12
 
13
 
14
iglobal
15
align 4
16
pipe_file_ops:
17
        dd pipe_close       ;0
18
        dd pipe_read        ;1
19
        dd pipe_write       ;2
20
endg
21
 
22
;int pipe2(int pipefd[2], int flags);
23
;ecx pipefd
24
;edx flags
25
 
26
align 4
27
sys_pipe2:
28
.pipeflags equ  esp+16
29
.pipefd    equ  esp+12
30
.fdread    equ  esp+8
31
.fdwrite   equ  esp+4
32
.intpipe   equ  esp
33
 
34
        push    ebp
35
        test    ecx, ecx
36
        mov     ebp, -EFAULT
37
        js      .fail
38
 
39
        test    edx, not O_CLOEXEC
40
        mov     ebp, -EINVAL
41
        jnz     .fail
42
 
43
        push    ecx
44
        push    edx
45
        sub     esp, (5-2)*4
46
 
47
        mov     ecx, sizeof.FILED
48
        call    create_object
49
        mov     [.fdread], eax
50
        test    eax, eax
51
        mov     ebp, -EMFILE
52
        jz      .err_0
53
 
54
        mov     ecx, sizeof.FILED
55
        call    create_object
56
        mov     [.fdwrite], eax
57
        test    eax, eax
58
        jz      .err_1
59
 
60
        mov     eax, sizeof.PIPE
61
        call    malloc
62
        test    eax, eax
63
        mov     ebp, -ENFILE
64
        jz      .err_2
65
 
66
        mov     ebp, eax
67
 
68
        stdcall create_ring_buffer, PIPE_BUFFER_SIZE, PG_SWR
69
        test    eax, eax
70
        jz      .err_3
71
 
72
        mov     [ebp+PIPE.pipe_ops], pipe_file_ops
73
        mov     [ebp+PIPE.buffer], eax
74
 
75
        xor     eax, eax
76
        mov     [ebp+PIPE.count], eax
77
        mov     [ebp+PIPE.read_end], eax
78
        mov     [ebp+PIPE.write_end], eax
79
 
80
        inc     eax
81
        mov     [ebp+PIPE.readers], eax
82
        mov     [ebp+PIPE.writers], eax
83
 
84
        lea     ecx, [ebp+PIPE.pipe_lock]
85
        call    mutex_init
86
 
87
        lea     ecx, [ebp+PIPE.rlist]
88
        list_init ecx
89
 
90
        lea     ecx, [ebp+PIPE.wlist]
91
        list_init ecx
92
 
93
        mov     eax, [.fdread]
94
        mov     edx, [.fdwrite]
95
        mov     ecx, [.pipefd]
96
 
97
        mov     [eax+FILED.magic], 'PIPE'
98
        mov     [eax+FILED.destroy], 0
99
        mov     [eax+FILED.file], ebp
100
 
101
        mov     [edx+FILED.magic], 'PIPE'
102
        mov     [edx+FILED.destroy], 0
103
        mov     [edx+FILED.file], ebp
104
 
105
        mov     [ecx], eax
106
        mov     [ecx+4], edx
107
        add     esp, 5*4
108
        pop     ebp
109
        xor     eax, eax
110
        mov     [esp+SYSCALL_STACK._eax], eax
111
        ret
112
.err_3:
113
        mov     eax, ebp
114
        call    free
115
        mov     ebp, -ENFILE
116
.err_2:
117
        mov     ecx, [.fdwrite]
118
        call    destroy_object
119
.err_1:
120
        mov     ecx, [.fdread]
121
        call    destroy_object
122
.err_0:
123
        add     esp, 5*4
124
.fail:
125
        mov     [esp+SYSCALL_STACK._eax], ebp
126
        pop     ebp
127
        ret
128
 
129
purge .pipeflags
130
purge .filefd
131
purge .fdread
132
purge .fdwrite
133
purge .intpipe
134
 
135
 
136
; edx buf
137
; esi count
138
; ebp pipe
139
 
140
align 4
141
pipe_read:
142
        mov     edi, edx
6927 serge 143
 
144
.again:
6926 serge 145
        lea     ecx, [ebp+PIPE.pipe_lock]
146
        call    mutex_lock
147
 
148
        xor     eax, eax
149
        cmp     eax, [ebp+PIPE.writers]
150
        je      .eof
151
 
152
        mov     ecx, [ebp+PIPE.count]
153
        test    ecx, ecx
154
        jz      .wait
155
 
156
.check_count:
157
        cmp     ecx, esi
158
        jb      .read
159
        mov     ecx, esi
160
.read:
161
        mov     esi, [ebp+PIPE.buffer]
162
        add     esi, [ebp+PIPE.read_end]
163
        mov     [esp+SYSCALL_STACK._eax], ecx
164
        sub     [ebp+PIPE.count], ecx
165
        cld
6927 serge 166
        rep movsb
6926 serge 167
        and     esi, 0xFFF
6927 serge 168
        mov     [ebp+PIPE.read_end], esi
6926 serge 169
 
170
        lea     ecx, [ebp+PIPE.pipe_lock]
171
        call    mutex_unlock
172
        ret
173
 
174
.wait:
175
        sub     esp, sizeof.MUTEX_WAITER
176
        mov     ebx, [TASK_BASE]
177
        mov     [esp+MUTEX_WAITER.task], ebx
178
        lea     edx, [ebp+PIPE.rlist]
179
 
180
        list_add_tail esp, edx      ;esp= new waiter, edx= list head
181
 
182
        lea     ecx, [ebp+PIPE.pipe_lock]
183
        call    mutex_unlock
184
 
185
        mov     [ebx+TASKDATA.state], 1
186
        call    change_task
187
 
6927 serge 188
        list_del esp
189
        add     esp, sizeof.MUTEX_WAITER
190
        jmp     .again
191
 
192
.eof:
193
        mov     [esp+SYSCALL_STACK._eax], eax
6926 serge 194
        lea     ecx, [ebp+PIPE.pipe_lock]
6927 serge 195
        call    mutex_unlock
196
        ret
197
 
198
; edx buf
199
; esi count
200
; ebp pipe
201
 
202
align 4
203
pipe_write:
204
        mov     edi, edx
205
 
206
.again:
207
        lea     ecx, [ebp+PIPE.pipe_lock]
6926 serge 208
        call    mutex_lock
209
 
6927 serge 210
        xor     eax, eax
211
        cmp     eax, [ebp+PIPE.readers]
212
        je      .epipe
213
 
6926 serge 214
        mov     ecx, [ebp+PIPE.count]
6927 serge 215
        sub     ecx, 4096
216
        jz      .wait
6926 serge 217
 
6927 serge 218
.check_count:
219
        cmp     ecx, esi
220
        jb      .write
221
        mov     ecx, esi
222
.write:
223
        mov     esi, [ebp+PIPE.buffer]
224
        add     esi, [ebp+PIPE.write_end]
225
        mov     [esp+SYSCALL_STACK._eax], ecx
226
        add     [ebp+PIPE.count], ecx
227
        cld
228
        rep movsb
229
        and     esi, 0xFFF
230
        mov     [ebp+PIPE.write_end], esi
231
 
232
        lea     ecx, [ebp+PIPE.pipe_lock]
233
        call    mutex_unlock
234
        ret
235
 
236
.wait:
237
        sub     esp, sizeof.MUTEX_WAITER
238
        mov     ebx, [TASK_BASE]
239
        mov     [esp+MUTEX_WAITER.task], ebx
240
        lea     edx, [ebp+PIPE.wlist]
241
 
242
        list_add_tail esp, edx      ;esp= new waiter, edx= list head
243
 
244
        lea     ecx, [ebp+PIPE.pipe_lock]
245
        call    mutex_unlock
246
 
247
        mov     [ebx+TASKDATA.state], 1
248
        call    change_task
249
 
6926 serge 250
        list_del esp
251
        add     esp, sizeof.MUTEX_WAITER
6927 serge 252
        jmp     .again
6926 serge 253
 
6927 serge 254
.epipe:
255
        mov     [esp+SYSCALL_STACK._eax], -EPIPE
6926 serge 256
        lea     ecx, [ebp+PIPE.pipe_lock]
257
        call    mutex_unlock
258
        ret
259
 
260
align 4
261
pipe_close:
262
        mov     [esp+SYSCALL_STACK._eax], -EBADF
263
        ret