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 |