Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6926 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
9715 Doczom 3
;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
6926 serge 4
;;  Distributed under terms of the GNU General Public License.  ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8130 dunkaist 8
$Revision: 9715 $
6926 serge 9
 
7136 dunkaist 10
F_READ              = 0x0001  ; file opened for reading
11
F_WRITE             = 0x0002  ; file opened for writing
6929 serge 12
 
7136 dunkaist 13
O_CLOEXEC           = 0x40000
14
PIPE_BUFFER_SIZE    = 4096
6926 serge 15
 
16
 
17
iglobal
18
align 4
19
pipe_file_ops:
20
        dd pipe_close       ;0
21
        dd pipe_read        ;1
22
        dd pipe_write       ;2
23
endg
24
 
25
;int pipe2(int pipefd[2], int flags);
26
;ecx pipefd
27
;edx flags
28
 
29
align 4
30
sys_pipe2:
31
.pipeflags equ  esp+16
32
.pipefd    equ  esp+12
33
.fdread    equ  esp+8
34
.fdwrite   equ  esp+4
35
.intpipe   equ  esp
36
 
37
        push    ebp
38
        test    ecx, ecx
39
        mov     ebp, -EFAULT
40
        js      .fail
41
 
42
        test    edx, not O_CLOEXEC
43
        mov     ebp, -EINVAL
44
        jnz     .fail
45
 
6928 serge 46
        push    edx
6926 serge 47
        push    ecx
48
        sub     esp, (5-2)*4
49
 
50
        mov     ecx, sizeof.FILED
51
        call    create_object
52
        mov     [.fdread], eax
53
        test    eax, eax
54
        mov     ebp, -EMFILE
55
        jz      .err_0
56
 
57
        mov     ecx, sizeof.FILED
58
        call    create_object
59
        mov     [.fdwrite], eax
60
        test    eax, eax
61
        jz      .err_1
62
 
63
        mov     eax, sizeof.PIPE
64
        call    malloc
65
        test    eax, eax
66
        mov     ebp, -ENFILE
67
        jz      .err_2
68
 
69
        mov     ebp, eax
70
 
71
        stdcall create_ring_buffer, PIPE_BUFFER_SIZE, PG_SWR
72
        test    eax, eax
73
        jz      .err_3
74
 
9715 Doczom 75
        mov     [ebp + PIPE.pipe_ops], pipe_file_ops
76
        mov     [ebp + PIPE.buffer], eax
6926 serge 77
 
78
        xor     eax, eax
9715 Doczom 79
        mov     [ebp + PIPE.count], eax
80
        mov     [ebp + PIPE.read_end], eax
81
        mov     [ebp + PIPE.write_end], eax
6926 serge 82
 
83
        inc     eax
9715 Doczom 84
        mov     [ebp + PIPE.readers], eax
85
        mov     [ebp + PIPE.writers], eax
6926 serge 86
 
9715 Doczom 87
        lea     ecx, [ebp + PIPE.pipe_lock]
6926 serge 88
        call    mutex_init
89
 
9715 Doczom 90
        lea     ecx, [ebp + PIPE.rlist]
6926 serge 91
        list_init ecx
92
 
9715 Doczom 93
        lea     ecx, [ebp + PIPE.wlist]
6926 serge 94
        list_init ecx
95
 
96
        mov     eax, [.fdread]
97
        mov     edx, [.fdwrite]
98
        mov     ecx, [.pipefd]
99
 
9715 Doczom 100
        mov     [eax + FILED.magic], 'PIPE'
101
        mov     [eax + FILED.destroy], 0
102
        mov     [eax + FILED.mode], F_READ
103
        mov     [eax + FILED.file], ebp
6926 serge 104
 
9715 Doczom 105
        mov     [edx + FILED.magic], 'PIPE'
106
        mov     [edx + FILED.destroy], 0
107
        mov     [edx + FILED.mode], F_WRITE
108
        mov     [edx + FILED.file], ebp
6926 serge 109
 
9715 Doczom 110
        mov     eax, [eax + FILED.handle]
111
        mov     edx, [edx + FILED.handle]
6928 serge 112
 
6926 serge 113
        mov     [ecx], eax
114
        mov     [ecx+4], edx
115
        add     esp, 5*4
116
        pop     ebp
117
        xor     eax, eax
9715 Doczom 118
        mov     [esp + SYSCALL_STACK._eax], eax
6926 serge 119
        ret
120
.err_3:
121
        mov     eax, ebp
122
        call    free
123
        mov     ebp, -ENFILE
124
.err_2:
125
        mov     ecx, [.fdwrite]
126
        call    destroy_object
127
.err_1:
128
        mov     ecx, [.fdread]
129
        call    destroy_object
130
.err_0:
131
        add     esp, 5*4
132
.fail:
6929 serge 133
        mov     eax, ebp
6926 serge 134
        pop     ebp
9715 Doczom 135
        mov     [esp + SYSCALL_STACK._eax], eax
6926 serge 136
        ret
137
 
138
purge .pipeflags
139
purge .filefd
140
purge .fdread
141
purge .fdwrite
142
purge .intpipe
143
 
144
 
6929 serge 145
; edx dst_buf
146
; esi read count
6926 serge 147
; ebp pipe
148
 
149
align 4
150
pipe_read:
6929 serge 151
 
6926 serge 152
        mov     edi, edx
6927 serge 153
 
9715 Doczom 154
        lea     ecx, [ebp + PIPE.pipe_lock]
6926 serge 155
        call    mutex_lock
6929 serge 156
.again:
6926 serge 157
        xor     eax, eax
9715 Doczom 158
        cmp     eax, [ebp + PIPE.writers]
6926 serge 159
        je      .eof
160
 
9715 Doczom 161
        mov     ecx, [ebp + PIPE.count]
6926 serge 162
        test    ecx, ecx
163
        jz      .wait
164
 
165
.check_count:
166
        cmp     ecx, esi
167
        jb      .read
168
        mov     ecx, esi
169
.read:
9715 Doczom 170
        mov     esi, [ebp + PIPE.buffer]
171
        add     esi, [ebp + PIPE.read_end]
172
        mov     [esp + SYSCALL_STACK._eax], ecx
173
        sub     [ebp + PIPE.count], ecx
6926 serge 174
        cld
6927 serge 175
        rep movsb
6926 serge 176
        and     esi, 0xFFF
9715 Doczom 177
        mov     [ebp + PIPE.read_end], esi
6926 serge 178
 
9715 Doczom 179
        lea     ecx, [ebp + PIPE.wlist]
180
        cmp     ecx, [ebp + PIPE.wlist.next]
6929 serge 181
        je      @F
182
 
9715 Doczom 183
        mov     ecx, [ecx + MUTEX_WAITER.task]
9709 Doczom 184
        mov     [ecx + APPDATA.state], TSTATE_RUNNING         ;activate writer task
6929 serge 185
@@:
9715 Doczom 186
        cmp     [ebp + PIPE.count], 0
6929 serge 187
        je      @F
188
 
9715 Doczom 189
        lea     eax, [ebp + PIPE.rlist]
190
        cmp     eax, [ebp + PIPE.rlist.next]
6929 serge 191
        je      @F
192
 
9715 Doczom 193
        mov     eax, [eax + MUTEX_WAITER.task]
9709 Doczom 194
        mov     [eax + APPDATA.state], TSTATE_RUNNING         ;activate reader task
6929 serge 195
@@:
9715 Doczom 196
        lea     ecx, [ebp + PIPE.pipe_lock]
6926 serge 197
        call    mutex_unlock
198
        ret
199
 
200
.wait:
6929 serge 201
        pushfd
202
        cli
203
 
6926 serge 204
        sub     esp, sizeof.MUTEX_WAITER
9709 Doczom 205
        mov     ebx, [current_slot]
9715 Doczom 206
        mov     [esp + MUTEX_WAITER.task], ebx
207
        lea     edx, [ebp + PIPE.rlist]
6926 serge 208
 
6929 serge 209
        list_add_tail esp, edx                  ;esp= new waiter, edx= list head
6926 serge 210
 
9715 Doczom 211
        lea     ecx, [ebp + PIPE.pipe_lock]
6926 serge 212
        call    mutex_unlock
213
 
9709 Doczom 214
        mov     [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
6926 serge 215
        call    change_task
216
 
9715 Doczom 217
        lea     ecx, [ebp + PIPE.pipe_lock]
6929 serge 218
        call    mutex_lock
219
 
6927 serge 220
        list_del esp
221
        add     esp, sizeof.MUTEX_WAITER
6929 serge 222
        popfd
6927 serge 223
        jmp     .again
224
 
225
.eof:
9715 Doczom 226
        mov     [esp + SYSCALL_STACK._eax], eax
227
        lea     ecx, [ebp + PIPE.pipe_lock]
6927 serge 228
        call    mutex_unlock
229
        ret
230
 
6929 serge 231
; edx src_buf
232
; esi write count
6927 serge 233
; ebp pipe
234
 
235
align 4
236
pipe_write:
237
 
6929 serge 238
.written    equ esp
239
 
240
        push    0                               ;written
241
        mov     ebx, esi                        ;ebx = write count
242
        mov     esi, edx                        ;esi = src
243
 
9715 Doczom 244
        lea     ecx, [ebp + PIPE.pipe_lock]
6926 serge 245
        call    mutex_lock
6929 serge 246
.again:
6927 serge 247
        xor     eax, eax
9715 Doczom 248
        cmp     eax, [ebp + PIPE.readers]
6927 serge 249
        je      .epipe
250
 
6929 serge 251
        mov     ecx, 4096
9715 Doczom 252
        sub     ecx, [ebp + PIPE.count]
6929 serge 253
        jz      .wait                           ;wait if buffer full
6926 serge 254
 
6927 serge 255
.check_count:
6929 serge 256
        cmp     ecx, ebx
6927 serge 257
        jb      .write
6929 serge 258
        mov     ecx, ebx
6927 serge 259
.write:
9715 Doczom 260
        mov     edi, [ebp + PIPE.buffer]
261
        add     edi, [ebp + PIPE.write_end]
6929 serge 262
        add     [.written], ecx
263
        sub     ebx, ecx
9715 Doczom 264
        add     [ebp + PIPE.count], ecx
6929 serge 265
 
6927 serge 266
        cld
267
        rep movsb
6928 serge 268
        and     edi, 0xFFF
9715 Doczom 269
        mov     [ebp + PIPE.write_end], edi
6927 serge 270
 
6929 serge 271
        pushfd
272
        cli
273
 
9715 Doczom 274
        lea     eax, [ebp + PIPE.rlist]
275
        cmp     eax, [ebp + PIPE.rlist.next]
6929 serge 276
        je      @F
277
 
9715 Doczom 278
        mov     eax, [eax + MUTEX_WAITER.task]
9709 Doczom 279
        mov     [eax + APPDATA.state], TSTATE_RUNNING         ;activate reader task
6929 serge 280
@@:
9715 Doczom 281
        cmp     [ebp + PIPE.count], 4096
6929 serge 282
        je      @F
283
 
9715 Doczom 284
        lea     ecx, [ebp + PIPE.wlist]
285
        cmp     ecx, [ebp + PIPE.wlist.next]
6929 serge 286
        je      @F
287
 
9715 Doczom 288
        mov     ecx, [eax + MUTEX_WAITER.task]
9709 Doczom 289
        mov     [ecx + APPDATA.state], TSTATE_RUNNING         ;activate writer task
6929 serge 290
@@:
291
        popfd
292
 
9715 Doczom 293
        lea     ecx, [ebp + PIPE.pipe_lock]
6927 serge 294
        call    mutex_unlock
6929 serge 295
 
296
        test    ebx, ebx
297
        jnz     .again
298
 
299
        pop     eax                             ; written
9715 Doczom 300
        mov     [esp + SYSCALL_STACK._eax], eax
6927 serge 301
        ret
302
 
303
.wait:
6929 serge 304
        pushfd
305
        cli
306
 
6927 serge 307
        sub     esp, sizeof.MUTEX_WAITER
9709 Doczom 308
        mov     ecx, [current_slot]
9715 Doczom 309
        mov     [esp + MUTEX_WAITER.task], ecx
6927 serge 310
        lea     edx, [ebp+PIPE.wlist]
311
 
6929 serge 312
        list_add_tail esp, edx                  ;esp= new waiter, edx= list head
6927 serge 313
 
9715 Doczom 314
        lea     ecx, [ebp + PIPE.pipe_lock]
6927 serge 315
        call    mutex_unlock
316
 
9709 Doczom 317
        mov     [ecx + APPDATA.state], TSTATE_RUN_SUSPENDED
6927 serge 318
        call    change_task
319
 
9715 Doczom 320
        lea     ecx, [ebp + PIPE.pipe_lock]
6929 serge 321
        call    mutex_lock
322
 
6926 serge 323
        list_del esp
324
        add     esp, sizeof.MUTEX_WAITER
6929 serge 325
        popfd
6927 serge 326
        jmp     .again
6926 serge 327
 
6927 serge 328
.epipe:
9715 Doczom 329
        lea     ecx, [ebp + PIPE.pipe_lock]
6926 serge 330
        call    mutex_unlock
6929 serge 331
 
332
        add     esp, 4
9715 Doczom 333
        mov     [esp + SYSCALL_STACK._eax], -EPIPE
6926 serge 334
        ret
335
 
336
align 4
337
pipe_close:
9715 Doczom 338
        mov     [esp + SYSCALL_STACK._eax], -EBADF
6926 serge 339
        ret