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