Subversion Repositories Kolibri OS

Rev

Rev 6927 | Rev 6929 | 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
 
6928 serge 43
        push    edx
6926 serge 44
        push    ecx
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
 
6928 serge 105
        mov     eax, [eax+FILED.handle]
106
        mov     edx, [edx+FILED.handle]
107
 
6926 serge 108
        mov     [ecx], eax
109
        mov     [ecx+4], edx
110
        add     esp, 5*4
111
        pop     ebp
112
        xor     eax, eax
113
        mov     [esp+SYSCALL_STACK._eax], eax
114
        ret
115
.err_3:
116
        mov     eax, ebp
117
        call    free
118
        mov     ebp, -ENFILE
119
.err_2:
120
        mov     ecx, [.fdwrite]
121
        call    destroy_object
122
.err_1:
123
        mov     ecx, [.fdread]
124
        call    destroy_object
125
.err_0:
126
        add     esp, 5*4
127
.fail:
128
        mov     [esp+SYSCALL_STACK._eax], ebp
129
        pop     ebp
130
        ret
131
 
132
purge .pipeflags
133
purge .filefd
134
purge .fdread
135
purge .fdwrite
136
purge .intpipe
137
 
138
 
139
; edx buf
140
; esi count
141
; ebp pipe
142
 
143
align 4
144
pipe_read:
145
        mov     edi, edx
6927 serge 146
 
147
.again:
6926 serge 148
        lea     ecx, [ebp+PIPE.pipe_lock]
149
        call    mutex_lock
150
 
151
        xor     eax, eax
152
        cmp     eax, [ebp+PIPE.writers]
153
        je      .eof
154
 
155
        mov     ecx, [ebp+PIPE.count]
156
        test    ecx, ecx
157
        jz      .wait
158
 
159
.check_count:
160
        cmp     ecx, esi
161
        jb      .read
162
        mov     ecx, esi
163
.read:
164
        mov     esi, [ebp+PIPE.buffer]
165
        add     esi, [ebp+PIPE.read_end]
166
        mov     [esp+SYSCALL_STACK._eax], ecx
167
        sub     [ebp+PIPE.count], ecx
168
        cld
6927 serge 169
        rep movsb
6926 serge 170
        and     esi, 0xFFF
6927 serge 171
        mov     [ebp+PIPE.read_end], esi
6926 serge 172
 
173
        lea     ecx, [ebp+PIPE.pipe_lock]
174
        call    mutex_unlock
175
        ret
176
 
177
.wait:
178
        sub     esp, sizeof.MUTEX_WAITER
179
        mov     ebx, [TASK_BASE]
180
        mov     [esp+MUTEX_WAITER.task], ebx
181
        lea     edx, [ebp+PIPE.rlist]
182
 
183
        list_add_tail esp, edx      ;esp= new waiter, edx= list head
184
 
185
        lea     ecx, [ebp+PIPE.pipe_lock]
186
        call    mutex_unlock
187
 
188
        mov     [ebx+TASKDATA.state], 1
189
        call    change_task
190
 
6927 serge 191
        list_del esp
192
        add     esp, sizeof.MUTEX_WAITER
193
        jmp     .again
194
 
195
.eof:
196
        mov     [esp+SYSCALL_STACK._eax], eax
6926 serge 197
        lea     ecx, [ebp+PIPE.pipe_lock]
6927 serge 198
        call    mutex_unlock
199
        ret
200
 
201
; edx buf
202
; esi count
203
; ebp pipe
204
 
205
align 4
206
pipe_write:
207
        mov     edi, edx
208
 
209
.again:
210
        lea     ecx, [ebp+PIPE.pipe_lock]
6926 serge 211
        call    mutex_lock
212
 
6927 serge 213
        xor     eax, eax
214
        cmp     eax, [ebp+PIPE.readers]
215
        je      .epipe
216
 
6926 serge 217
        mov     ecx, [ebp+PIPE.count]
6927 serge 218
        sub     ecx, 4096
219
        jz      .wait
6926 serge 220
 
6927 serge 221
.check_count:
222
        cmp     ecx, esi
223
        jb      .write
224
        mov     ecx, esi
225
.write:
6928 serge 226
        mov     esi, edi
227
        mov     edi, [ebp+PIPE.buffer]
228
        add     edi, [ebp+PIPE.write_end]
6927 serge 229
        mov     [esp+SYSCALL_STACK._eax], ecx
230
        add     [ebp+PIPE.count], ecx
231
        cld
232
        rep movsb
6928 serge 233
        and     edi, 0xFFF
234
        mov     [ebp+PIPE.write_end], edi
6927 serge 235
 
236
        lea     ecx, [ebp+PIPE.pipe_lock]
237
        call    mutex_unlock
238
        ret
239
 
240
.wait:
241
        sub     esp, sizeof.MUTEX_WAITER
242
        mov     ebx, [TASK_BASE]
243
        mov     [esp+MUTEX_WAITER.task], ebx
244
        lea     edx, [ebp+PIPE.wlist]
245
 
246
        list_add_tail esp, edx      ;esp= new waiter, edx= list head
247
 
248
        lea     ecx, [ebp+PIPE.pipe_lock]
249
        call    mutex_unlock
250
 
251
        mov     [ebx+TASKDATA.state], 1
252
        call    change_task
253
 
6926 serge 254
        list_del esp
255
        add     esp, sizeof.MUTEX_WAITER
6927 serge 256
        jmp     .again
6926 serge 257
 
6927 serge 258
.epipe:
259
        mov     [esp+SYSCALL_STACK._eax], -EPIPE
6926 serge 260
        lea     ecx, [ebp+PIPE.pipe_lock]
261
        call    mutex_unlock
262
        ret
263
 
264
align 4
265
pipe_close:
266
        mov     [esp+SYSCALL_STACK._eax], -EBADF
267
        ret