Rev 9709 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 9709 | Rev 9715 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
1 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
2 | ;; ;; |
2 | ;; ;; |
3 | ;; Copyright (C) KolibriOS team 2004-2015. 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 | ;; Synhronization for MenuetOS. ;; |
6 | ;; Synhronization for MenuetOS. ;; |
7 | ;; Author: Halyavin Andrey, halyavin@land.ru ;; |
7 | ;; Author: Halyavin Andrey, halyavin@land.ru ;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
8 | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
Line 9... | Line 9... | ||
9 | 9 | ||
Line 10... | Line 10... | ||
10 | $Revision: 9709 $ |
10 | $Revision: 9715 $ |
11 | 11 | ||
Line 12... | Line 12... | ||
12 | 12 | ||
Line 13... | Line 13... | ||
13 | 13 | ||
14 | RWSEM_WAITING_FOR_WRITE = 0 |
14 | RWSEM_WAITING_FOR_WRITE = 0 |
15 | RWSEM_WAITING_FOR_READ = 1 |
15 | RWSEM_WAITING_FOR_READ = 1 |
16 | 16 | ||
17 | ;void __fastcall mutex_init(struct mutex *lock) |
17 | ;void __fastcall mutex_init(struct mutex *lock) |
18 | 18 | ||
Line 19... | Line 19... | ||
19 | align 4 |
19 | align 4 |
Line 20... | Line 20... | ||
20 | mutex_init: |
20 | mutex_init: |
21 | mov [ecx+MUTEX.wait_list.next], ecx |
21 | mov [ecx + MUTEX.wait_list.next], ecx |
Line 22... | Line 22... | ||
22 | mov [ecx+MUTEX.wait_list.prev], ecx |
22 | mov [ecx + MUTEX.wait_list.prev], ecx |
23 | mov [ecx+MUTEX.count], 1 |
23 | mov [ecx + MUTEX.count], 1 |
Line 24... | Line 24... | ||
24 | ret |
24 | ret |
25 | 25 | ||
Line 26... | Line 26... | ||
26 | ;void __fastcall mutex_lock(struct mutex *lock) |
26 | ;void __fastcall mutex_lock(struct mutex *lock) |
Line 27... | Line 27... | ||
27 | 27 | ||
Line 28... | Line 28... | ||
28 | align 4 |
28 | align 4 |
29 | mutex_lock: |
29 | mutex_lock: |
Line 30... | Line 30... | ||
30 | 30 | ||
Line 31... | Line 31... | ||
31 | dec [ecx+MUTEX.count] |
31 | dec [ecx + MUTEX.count] |
32 | jns .done |
32 | jns .done |
33 | 33 | ||
34 | pushfd |
34 | pushfd |
Line 35... | Line 35... | ||
35 | cli |
35 | cli |
36 | 36 | ||
37 | sub esp, sizeof.MUTEX_WAITER |
37 | sub esp, sizeof.MUTEX_WAITER |
38 | 38 | ||
39 | list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
39 | list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
40 | 40 | ||
Line 41... | Line 41... | ||
41 | mov edx, [current_slot] |
41 | mov edx, [current_slot] |
42 | mov [esp+MUTEX_WAITER.task], edx |
42 | mov [esp + MUTEX_WAITER.task], edx |
Line 43... | Line 43... | ||
43 | 43 | ||
44 | .forever: |
44 | .forever: |
45 | 45 | ||
Line 46... | Line 46... | ||
46 | mov eax, -1 |
46 | mov eax, -1 |
47 | xchg eax, [ecx+MUTEX.count] |
47 | xchg eax, [ecx + MUTEX.count] |
Line 72... | Line 72... | ||
72 | mutex_unlock: |
72 | mutex_unlock: |
Line 73... | Line 73... | ||
73 | 73 | ||
74 | pushfd |
74 | pushfd |
Line 75... | Line 75... | ||
75 | cli |
75 | cli |
76 | 76 | ||
77 | mov eax, [ecx+MUTEX.wait_list.next] |
77 | mov eax, [ecx + MUTEX.wait_list.next] |
78 | cmp eax, ecx |
78 | cmp eax, ecx |
Line 79... | Line 79... | ||
79 | mov [ecx+MUTEX.count], 1 |
79 | mov [ecx + MUTEX.count], 1 |
80 | je @F |
80 | je @F |
81 | 81 | ||
82 | mov eax, [eax+MUTEX_WAITER.task] |
82 | mov eax, [eax + MUTEX_WAITER.task] |
83 | mov [eax + APPDATA.state], TSTATE_RUNNING |
83 | mov [eax + APPDATA.state], TSTATE_RUNNING |
Line 84... | Line 84... | ||
84 | @@: |
84 | @@: |
Line 85... | Line 85... | ||
85 | popfd |
85 | popfd |
86 | ret |
86 | ret |
87 | 87 | ||
88 | 88 | ||
89 | ;void __fastcall init_rwsem(struct rw_semaphore *sem) |
89 | ;void __fastcall init_rwsem(struct rw_semaphore *sem) |
90 | 90 | ||
Line 91... | Line 91... | ||
91 | align 4 |
91 | align 4 |
Line 92... | Line 92... | ||
92 | init_rwsem: |
92 | init_rwsem: |
93 | mov [ecx+RWSEM.wait_list.next], ecx |
93 | mov [ecx + RWSEM.wait_list.next], ecx |
94 | mov [ecx+RWSEM.wait_list.prev], ecx |
94 | mov [ecx + RWSEM.wait_list.prev], ecx |
95 | mov [ecx+RWSEM.count], 0 |
95 | mov [ecx + RWSEM.count], 0 |
Line 96... | Line 96... | ||
96 | ret |
96 | ret |
97 | 97 | ||
98 | ;void __fastcall down_read(struct rw_semaphore *sem) |
98 | ;void __fastcall down_read(struct rw_semaphore *sem) |
Line 99... | Line 99... | ||
99 | 99 | ||
100 | align 4 |
100 | align 4 |
101 | down_read: |
101 | down_read: |
102 | pushfd |
102 | pushfd |
Line 103... | Line 103... | ||
103 | cli |
103 | cli |
104 | 104 | ||
105 | mov eax, [ecx+RWSEM.count] |
105 | mov eax, [ecx + RWSEM.count] |
106 | test eax, eax |
106 | test eax, eax |
Line 107... | Line 107... | ||
107 | js @F |
107 | js @F |
Line 108... | Line 108... | ||
108 | 108 | ||
Line 123... | Line 123... | ||
123 | add esp, sizeof.MUTEX_WAITER |
123 | add esp, sizeof.MUTEX_WAITER |
124 | popfd |
124 | popfd |
125 | ret |
125 | ret |
126 | .ok: |
126 | .ok: |
127 | inc eax |
127 | inc eax |
128 | mov [ecx+RWSEM.count], eax |
128 | mov [ecx + RWSEM.count], eax |
Line 129... | Line 129... | ||
129 | 129 | ||
130 | popfd |
130 | popfd |
Line 131... | Line 131... | ||
131 | ret |
131 | ret |
Line 137... | Line 137... | ||
137 | pushfd |
137 | pushfd |
138 | cli |
138 | cli |
139 | sub esp, sizeof.MUTEX_WAITER |
139 | sub esp, sizeof.MUTEX_WAITER |
Line 140... | Line 140... | ||
140 | 140 | ||
141 | mov edx, [current_slot] |
141 | mov edx, [current_slot] |
142 | mov [esp+MUTEX_WAITER.task], edx |
142 | mov [esp + MUTEX_WAITER.task], edx |
143 | mov [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE |
143 | mov [esp + MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE |
Line 144... | Line 144... | ||
144 | mov [edx + APPDATA.state], TSTATE_RUN_SUSPENDED |
144 | mov [edx + APPDATA.state], TSTATE_RUN_SUSPENDED |
Line 145... | Line 145... | ||
145 | 145 | ||
146 | list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
146 | list_add_tail esp, ecx ;esp= new waiter, ecx= list head |
Line 147... | Line 147... | ||
147 | 147 | ||
148 | xor eax, eax |
148 | xor eax, eax |
149 | not eax |
149 | not eax |
Line 150... | Line 150... | ||
150 | 150 | ||
151 | .forever: |
151 | .forever: |
152 | test eax, [ecx+RWSEM.count] |
152 | test eax, [ecx + RWSEM.count] |
153 | jz @F |
153 | jz @F |
154 | 154 | ||
155 | mov [edx + APPDATA.state], TSTATE_RUN_SUSPENDED |
155 | mov [edx + APPDATA.state], TSTATE_RUN_SUSPENDED |
Line 156... | Line 156... | ||
156 | call change_task |
156 | call change_task |
157 | jmp .forever |
157 | jmp .forever |
158 | @@: |
158 | @@: |
Line 168... | Line 168... | ||
168 | align 4 |
168 | align 4 |
169 | up_read: |
169 | up_read: |
170 | pushfd |
170 | pushfd |
171 | cli |
171 | cli |
Line 172... | Line 172... | ||
172 | 172 | ||
173 | dec [ecx+RWSEM.count] |
173 | dec [ecx + RWSEM.count] |
Line 174... | Line 174... | ||
174 | jnz @F |
174 | jnz @F |
175 | 175 | ||
176 | mov eax, [ecx+RWSEM.wait_list.next] |
176 | mov eax, [ecx + RWSEM.wait_list.next] |
Line 177... | Line 177... | ||
177 | cmp eax, ecx |
177 | cmp eax, ecx |
178 | je @F |
178 | je @F |
179 | 179 | ||
180 | mov eax, [eax+MUTEX_WAITER.task] |
180 | mov eax, [eax + MUTEX_WAITER.task] |
181 | mov [eax + APPDATA.state], TSTATE_RUNNING |
181 | mov [eax + APPDATA.state], TSTATE_RUNNING |
Line 189... | Line 189... | ||
189 | up_write: |
189 | up_write: |
Line 190... | Line 190... | ||
190 | 190 | ||
191 | pushfd |
191 | pushfd |
Line 192... | Line 192... | ||
192 | cli |
192 | cli |
193 | 193 | ||
Line 194... | Line 194... | ||
194 | mov eax, [ecx+RWSEM.wait_list.next] |
194 | mov eax, [ecx + RWSEM.wait_list.next] |
195 | mov [ecx+RWSEM.count], 0 |
195 | mov [ecx + RWSEM.count], 0 |
Line 196... | Line 196... | ||
196 | 196 | ||
197 | cmp ecx, eax |
197 | cmp ecx, eax |
198 | je .done |
198 | je .done |
Line 199... | Line 199... | ||
199 | 199 | ||
200 | mov edx, [eax+MUTEX_WAITER.type] |
200 | mov edx, [eax + MUTEX_WAITER.type] |
201 | test edx, edx |
201 | test edx, edx |
202 | jnz .wake |
202 | jnz .wake |
203 | 203 | ||
Line 215... | Line 215... | ||
215 | xor esi, esi |
215 | xor esi, esi |
216 | mov edi, ecx |
216 | mov edi, ecx |
Line 217... | Line 217... | ||
217 | 217 | ||
Line 218... | Line 218... | ||
218 | .wake_list: |
218 | .wake_list: |
219 | 219 | ||
220 | mov ebx, [eax+MUTEX_WAITER.list.next] |
220 | mov ebx, [eax + MUTEX_WAITER.list.next] |
221 | list_del eax |
221 | list_del eax |
222 | mov edx, [eax+MUTEX_WAITER.task] |
222 | mov edx, [eax + MUTEX_WAITER.task] |
223 | mov [edx + APPDATA.state], TSTATE_RUNNING |
223 | mov [edx + APPDATA.state], TSTATE_RUNNING |
224 | inc esi |
224 | inc esi |
Line 225... | Line 225... | ||
225 | cmp edi, ebx |
225 | cmp edi, ebx |
226 | je .wake_done |
226 | je .wake_done |
227 | 227 | ||
Line 228... | Line 228... | ||
228 | mov ecx, [ebx+MUTEX_WAITER.type] |
228 | mov ecx, [ebx + MUTEX_WAITER.type] |
229 | test ecx, ecx |
229 | test ecx, ecx |
Line 230... | Line 230... | ||
230 | jz .wake_done |
230 | jz .wake_done |
231 | 231 | ||
Line 232... | Line 232... | ||
232 | mov eax, ebx |
232 | mov eax, ebx |
233 | jmp .wake_list |
233 | jmp .wake_list |
234 | 234 | ||
235 | .wake_done: |
235 | .wake_done: |
Line 268... | Line 268... | ||
268 | sti |
268 | sti |
269 | call change_task |
269 | call change_task |
270 | jmp start_wait |
270 | jmp start_wait |
271 | ok=$ |
271 | ok=$ |
272 | push eax |
272 | push eax |
273 | mov eax, dword [TASK_BASE+second_base_address] |
273 | mov eax, dword [current_slot] |
274 | mov eax, [eax+TASKDATA.pid] |
274 | mov eax, [eax + APPDATA.tid] |
275 | mov [name], eax |
275 | mov [name], eax |
276 | pop eax |
276 | pop eax |
277 | sti |
277 | sti |
278 | } |
278 | } |
279 | macro ReleaseSimpleMutex name |
279 | macro ReleaseSimpleMutex name |
Line 302... | Line 302... | ||
302 | } |
302 | } |
303 | macro WaitSimpleCriticalSection name |
303 | macro WaitSimpleCriticalSection name |
304 | { |
304 | { |
305 | local start_wait,first_wait,inc_counter,end_wait |
305 | local start_wait,first_wait,inc_counter,end_wait |
306 | push eax |
306 | push eax |
307 | mov eax, [TASK_BASE+second_base_address] |
307 | mov eax, [current_slot] |
308 | mov eax, [eax+TASKDATA.pid] |
308 | mov eax, [eax + APPDATA.tid] |
309 | start_wait=$ |
309 | start_wait=$ |
310 | cli |
310 | cli |
311 | cmp [name], dword 0 |
311 | cmp [name], dword 0 |
312 | jz first_wait |
312 | jz first_wait |
313 | cmp [name], eax |
313 | cmp [name], eax |
Line 315... | Line 315... | ||
315 | sti |
315 | sti |
316 | call change_task |
316 | call change_task |
317 | jmp start_wait |
317 | jmp start_wait |
318 | first_wait=$ |
318 | first_wait=$ |
319 | mov [name], eax |
319 | mov [name], eax |
320 | mov [name+4], dword 1 |
320 | mov [name + 4], dword 1 |
321 | jmp end_wait |
321 | jmp end_wait |
322 | inc_counter=$ |
322 | inc_counter=$ |
323 | inc dword [name+4] |
323 | inc dword [name + 4] |
324 | end_wait=$ |
324 | end_wait=$ |
325 | sti |
325 | sti |
326 | pop eax |
326 | pop eax |
327 | } |
327 | } |
328 | macro ReleaseSimpleCriticalSection name |
328 | macro ReleaseSimpleCriticalSection name |
329 | { |
329 | { |
330 | local release_end |
330 | local release_end |
331 | dec dword [name+4] |
331 | dec dword [name + 4] |
332 | jnz release_end |
332 | jnz release_end |
333 | mov [name], dword 0 |
333 | mov [name], dword 0 |
334 | release_end=$ |
334 | release_end=$ |
335 | } |
335 | } |
336 | macro TryWaitSimpleCriticalSection name ;result in eax and in flags |
336 | macro TryWaitSimpleCriticalSection name ;result in eax and in flags |
337 | { |
337 | { |
338 | local ok,try_end |
338 | local ok,try_end |
339 | mov eax, [CURRENT_TASK+second_base_address] |
339 | mov eax, [current_slot] |
340 | mov eax, [eax+TASKDATA.pid] |
340 | mov eax, [eax + APPDATA.tid] |
341 | cmp [name], eax |
341 | cmp [name], eax |
342 | jz ok |
342 | jz ok |
343 | cmp [name], 0 |
343 | cmp [name], 0 |
344 | jz ok |
344 | jz ok |
345 | xor eax, eax |
345 | xor eax, eax |