Subversion Repositories Kolibri OS

Rev

Rev 9869 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9869 Rev 9871
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2022. 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: 9869 $
8
$Revision: 9871 $
9
 
9
 
10
align 4
10
align 4
11
;struct futex*  __fastcall create_futex(int *ptr)
11
;struct futex*  __fastcall create_futex(int *ptr)
12
create_futex:
12
create_futex:
13
        push    ecx
13
        push    ecx
14
        mov     ecx, sizeof.FUTEX
14
        mov     ecx, sizeof.FUTEX
15
        call    create_object
15
        call    create_object
16
        pop     ecx
16
        pop     ecx
17
        test    eax, eax
17
        test    eax, eax
18
        jz      .fail
18
        jz      .fail
19
 
19
 
20
        mov     [eax + FUTEX.magic], 'FUTX'
20
        mov     [eax + FUTEX.magic], 'FUTX'
21
        mov     [eax + FUTEX.destroy], 0
21
        mov     [eax + FUTEX.destroy], 0
22
        mov     [eax + FUTEX.pointer], ecx
22
        mov     [eax + FUTEX.pointer], ecx
23
        lea     ecx, [eax + FUTEX.wait_list]
23
        lea     ecx, [eax + FUTEX.wait_list]
24
        list_init ecx
24
        list_init ecx
25
        mov     [eax + FUTEX.flags], 0
25
        mov     [eax + FUTEX.flags], 0
26
.fail:
26
.fail:
27
        ret
27
        ret
28
 
28
 
29
align 4
29
align 4
30
;int __fastcall destroy_futex(struct futex *futex)
30
;int __fastcall destroy_futex(struct futex *futex)
31
destroy_futex:
31
destroy_futex:
32
        push    esi
32
        push    esi
33
        mov     esi, [current_process]
33
        mov     esi, [current_process]
34
        mov     edx, [ecx + FUTEX.handle]
34
        mov     edx, [ecx + FUTEX.handle]
35
 
35
 
36
        pushfd
36
        pushfd
37
        cli
37
        cli
38
 
38
 
39
        lea     eax, [ecx + FUTEX.wait_list]
39
        lea     eax, [ecx + FUTEX.wait_list]
40
        cmp     eax, [eax + LHEAD.next]
40
        cmp     eax, [eax + LHEAD.next]
41
        jne     .fail
41
        jne     .fail
42
 
42
 
43
        mov     eax, [esi + PROC.ht_next]
43
        mov     eax, [esi + PROC.ht_next]
44
        mov     [esi + PROC.htab + edx*4], eax
44
        mov     [esi + PROC.htab + edx*4], eax
45
        mov     [esi + PROC.ht_next], edx
45
        mov     [esi + PROC.ht_next], edx
46
        inc     [esi + PROC.ht_free]
46
        inc     [esi + PROC.ht_free]
47
 
47
 
48
        popfd
48
        popfd
49
        pop     esi
49
        pop     esi
50
 
50
 
51
        mov     eax, ecx
51
        mov     eax, ecx
52
        call    free
52
        call    free
53
        xor     eax, eax
53
        xor     eax, eax
54
        ret
54
        ret
55
 
55
 
56
.fail:
56
.fail:
57
        popfd
57
        popfd
58
        pop     esi
58
        pop     esi
59
        mov     eax, -1
59
        mov     eax, -1
60
        ret
60
        ret
61
 
61
 
62
align 4
62
align 4
63
sys_futex:
63
sys_futex:
64
        cmp     ecx, STDERR_FILENO
64
        cmp     ecx, STDERR_FILENO
65
        jbe     .fail
65
        jbe     .fail
66
        cmp     ecx, (PROC.pdt_0 - PROC.htab)/4
66
        cmp     ecx, (PROC.pdt_0 - PROC.htab)/4
67
        jae     .fail
67
        jae     .fail
68
 
68
 
69
        mov     edi, [current_process]
69
        mov     edi, [current_process]
70
        mov     ebp, [edi + PROC.htab + ecx*4]
70
        mov     ebp, [edi + PROC.htab + ecx*4]
71
 
71
 
72
        cmp     [ebp + FUTEX.magic], 'FUTX'
72
        cmp     [ebp + FUTEX.magic], 'FUTX'
73
        jne     .fail
73
        jne     .fail
74
        cmp     [ebp + FUTEX.handle], ecx
74
        cmp     [ebp + FUTEX.handle], ecx
75
        jne     .fail
75
        jne     .fail
76
 
76
 
77
        jmp     dword [sys_futex_call + ebx*4-4]
77
        jmp     dword [sys_futex_call + ebx*4-4]
78
 
78
 
79
.fail:
79
.fail:
80
.requeue:
80
.requeue:
81
.cmp_requeue:
81
.cmp_requeue:
82
.wait_bitset:
82
.wait_bitset:
83
.wake_bitset:
83
.wake_bitset:
84
        mov     [esp + SYSCALL_STACK.eax], -1
84
        mov     [esp + SYSCALL_STACK.eax], -1
85
        ret
85
        ret
86
 
86
 
87
align 4
87
align 4
88
.init:
88
.init:
89
        call    create_futex
89
        call    create_futex
90
        test    eax, eax
90
        test    eax, eax
91
        jz      @F
91
        jz      @F
92
        mov     eax, [eax + FUTEX.handle]
92
        mov     eax, [eax + FUTEX.handle]
93
@@:
93
@@:
94
        mov     [esp + SYSCALL_STACK.eax], eax
94
        mov     [esp + SYSCALL_STACK.eax], eax
95
        ret
95
        ret
96
 
96
 
97
align 4
97
align 4
98
;ecx futex handle
98
;ecx futex handle
99
;edi current process
99
;edi current process
100
;ebp futex object
100
;ebp futex object
101
.destroy:
101
.destroy:
102
        mov     ecx, ebp
102
        mov     ecx, ebp
103
        call    destroy_futex
103
        call    destroy_futex
104
        mov     [esp + SYSCALL_STACK.eax], eax
104
        mov     [esp + SYSCALL_STACK.eax], eax
105
        ret
105
        ret
106
 
106
 
107
align 4
107
align 4
108
;ecx futex handle
108
;ecx futex handle
109
;edx control value
109
;edx control value
110
;esi timeout
110
;esi timeout
111
;edi current process
111
;edi current process
112
;ebp futex object
112
;ebp futex object
113
.wait:
113
.wait:
114
        test    esi, esi
114
        test    esi, esi
115
        jnz     .wait_timeout
115
        jnz     .wait_timeout
116
        mov     ecx, [ebp + FUTEX.pointer]
116
        mov     ecx, [ebp + FUTEX.pointer]
117
        mov     eax, edx
117
        mov     eax, edx
118
        lock cmpxchg [ecx], edx
118
        lock cmpxchg [ecx], edx
119
        je      .wait_slow
119
        je      .wait_slow
120
 
120
 
121
        mov     [esp + SYSCALL_STACK.eax], -2
121
        mov     [esp + SYSCALL_STACK.eax], -2
122
        ret
122
        ret
123
 
123
 
124
.wait_slow:
124
.wait_slow:
125
        pushfd
125
        pushfd
126
        cli
126
        cli
127
 
127
 
128
        sub     esp, sizeof.MUTEX_WAITER
128
        sub     esp, sizeof.MUTEX_WAITER
129
        mov     ebx, [current_slot]
129
        mov     ebx, [current_slot]
130
        mov     [esp + MUTEX_WAITER.task], ebx
130
        mov     [esp + MUTEX_WAITER.task], ebx
131
        lea     esi, [ebp + FUTEX.wait_list]
131
        lea     esi, [ebp + FUTEX.wait_list]
132
 
132
 
133
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
133
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
134
        mov     eax, edx
134
        mov     eax, edx
135
.again:
135
.again:
136
        mov     [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
136
        mov     [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
137
        call    change_task
137
        call    change_task
138
 
138
 
139
        lock cmpxchg [ecx], edx
139
        lock cmpxchg [ecx], edx
140
        je      .again
140
        je      .again
141
 
141
 
142
        list_del esp
142
        list_del esp
143
        add     esp, sizeof.MUTEX_WAITER
143
        add     esp, sizeof.MUTEX_WAITER
144
 
144
 
145
        popfd
145
        popfd
146
        mov     [esp + SYSCALL_STACK.eax], 0
146
        mov     [esp + SYSCALL_STACK.eax], 0
147
        ret
147
        ret
148
 
148
 
149
align 4
149
align 4
150
;ecx futex handle
150
;ecx futex handle
151
;edx control value
151
;edx control value
152
;esi timeout
152
;esi timeout
153
;edi current process
153
;edi current process
154
;ebp futex object
154
;ebp futex object
155
 
155
 
156
.wait_timeout:
156
.wait_timeout:
157
        mov     ecx, [ebp + FUTEX.pointer]
157
        mov     ecx, [ebp + FUTEX.pointer]
158
        mov     eax, edx
158
        mov     eax, edx
159
        lock cmpxchg [ecx], edx         ;wait until old_value == new_value
159
        lock cmpxchg [ecx], edx         ;wait until old_value == new_value
160
        je      .wait_slow_timeout
160
        je      .wait_slow_timeout
161
 
161
 
162
        mov     [esp + SYSCALL_STACK.eax], -2
162
        mov     [esp + SYSCALL_STACK.eax], -2
163
        ret
163
        ret
164
 
164
 
165
align 4
165
align 4
166
.wait_test:
166
.wait_test:
167
        xor     eax, eax
167
        xor     eax, eax
168
        ret
168
        ret
169
 
169
 
170
.wait_slow_timeout:
170
.wait_slow_timeout:
171
        pushfd
171
        pushfd
172
        cli
172
        cli
173
 
173
 
174
        sub     esp, sizeof.MUTEX_WAITER
174
        sub     esp, sizeof.MUTEX_WAITER
175
 
175
 
176
        mov     ebx, [current_slot]
176
        mov     ebx, [current_slot]
177
        mov     [ebx + APPDATA.wait_test], sys_futex.wait_test
177
        mov     [ebx + APPDATA.wait_test], sys_futex.wait_test
178
        mov     [ebx + APPDATA.wait_timeout], esi
178
        mov     [ebx + APPDATA.wait_timeout], esi
179
        mov     [ebx + APPDATA.wait_param], ebp
179
        mov     [ebx + APPDATA.wait_param], ebp
180
        mov     eax, [timer_ticks]
180
        mov     eax, [timer_ticks]
181
        mov     [ebx + APPDATA.wait_begin], eax
181
        mov     [ebx + APPDATA.wait_begin], eax
182
        mov     [ebx + APPDATA.state], TSTATE_WAITING
182
        mov     [ebx + APPDATA.state], TSTATE_WAITING
183
 
183
 
184
        mov     [esp + MUTEX_WAITER.task], ebx
184
        mov     [esp + MUTEX_WAITER.task], ebx
185
        lea     esi, [ebp + FUTEX.wait_list]
185
        lea     esi, [ebp + FUTEX.wait_list]
186
 
186
 
187
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
187
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
188
        sti
-
 
189
.again_timeout:
188
.again_timeout:
-
 
189
        mov     [ebx + APPDATA.state], TSTATE_WAITING
190
        call    change_task
190
        call    change_task
191
        mov     eax, [ebx + APPDATA.wait_param]
191
        mov     eax, [ebx + APPDATA.wait_param]
192
        test    eax, eax
192
        test    eax, eax
193
        jz      .timeout
193
        jz      .timeout
194
        DEBUGF  1, "FUTEX no timeout [ecx]=%x edx=%x\n", [ecx], edx
-
 
195
        mov     eax, edx
194
        mov     eax, edx
196
        lock cmpxchg [ecx], edx
195
        lock cmpxchg [ecx], edx
197
        jz      .again_timeout
196
        jz      .again_timeout
198
@@:
197
@@:
199
        cli
198
        cli
200
        list_del esp
199
        list_del esp
201
        sti
200
        sti
202
        add     esp, sizeof.MUTEX_WAITER
201
        add     esp, sizeof.MUTEX_WAITER
203
        popfd
202
        popfd
204
        mov     [esp + SYSCALL_STACK.eax], 0
203
        mov     [esp + SYSCALL_STACK.eax], 0
205
        ret
204
        ret
206
 
205
 
207
.timeout:
206
.timeout:
208
        cli
-
 
209
        list_del esp
207
        list_del esp
210
        sti
-
 
211
        add     esp, sizeof.MUTEX_WAITER
208
        add     esp, sizeof.MUTEX_WAITER
212
        DEBUGF  1, "FUTEX timeout\n"
-
 
213
        popfd
209
        popfd
214
        mov     [esp + SYSCALL_STACK.eax], -1
210
        mov     [esp + SYSCALL_STACK.eax], -1
215
        ret
211
        ret
216
 
212
 
217
 
213
 
218
align 4
214
align 4
219
;ecx futex handle
215
;ecx futex handle
220
;edx number of threads
216
;edx number of threads
221
;edi current process
217
;edi current process
222
;ebp futex object
218
;ebp futex object
223
.wake:
219
.wake:
224
 
220
 
225
        xor     ecx, ecx
221
        xor     ecx, ecx
226
 
222
 
227
        pushfd
223
        pushfd
228
        cli
224
        cli
229
 
225
 
230
        lea     ebx, [ebp + FUTEX.wait_list]
226
        lea     ebx, [ebp + FUTEX.wait_list]
231
        mov     esi, [ebx + LHEAD.next]
227
        mov     esi, [ebx + LHEAD.next]
232
.again_wake:
228
.again_wake:
233
        cmp     esi, ebx
229
        cmp     esi, ebx
234
        je      .done
230
        je      .done
235
 
231
 
236
        mov     eax, [esi + MUTEX_WAITER.task]
232
        mov     eax, [esi + MUTEX_WAITER.task]
237
        mov     [eax + APPDATA.state], TSTATE_RUNNING
233
        mov     [eax + APPDATA.state], TSTATE_RUNNING
238
 
234
 
239
        mov     esi, [esi + MUTEX_WAITER.list.next]
235
        mov     esi, [esi + MUTEX_WAITER.list.next]
240
        inc     ecx
236
        inc     ecx
241
        cmp     ecx, edx
237
        cmp     ecx, edx
242
        jb      .again_wake
238
        jb      .again_wake
243
.done:
239
.done:
244
        popfd
240
        popfd
245
        mov     [esp + SYSCALL_STACK.eax], ecx
241
        mov     [esp + SYSCALL_STACK.eax], ecx
246
        ret
242
        ret