Subversion Repositories Kolibri OS

Rev

Rev 6926 | Rev 6928 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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