Subversion Repositories Kolibri OS

Rev

Rev 5565 | Rev 5596 | Go to most recent revision | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 5565 Rev 5593
Line 3... Line 3...
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2015. 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
;;                                                              ;;
-
 
9
;;                                                              ;;
-
 
10
;;                                                              ;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
11
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 9... Line 12...
9
 
12
 
-
 
13
$Revision: 5593 $
-
 
14
 
-
 
15
align 4
-
 
16
;struct futex*  __fastcall create_futex(int *ptr)
-
 
17
create_futex:
-
 
18
        push    ecx
-
 
19
        mov     ecx, sizeof.FUTEX
-
 
20
        call    create_object
-
 
21
        pop     ecx
-
 
22
        test    eax, eax
-
 
23
        jz .fail
-
 
24
 
-
 
25
        mov     [eax+FUTEX.magic], 'FUTX'
-
 
26
        mov     [eax+FUTEX.destroy], 0
-
 
27
        mov     [eax+FUTEX.pointer], ecx
-
 
28
        lea     ecx, [eax+FUTEX.wait_list]
-
 
29
        list_init ecx
-
 
30
        mov     [eax+FUTEX.flags], 0
-
 
31
.fail:
-
 
32
        ret
-
 
33
 
-
 
34
iglobal
-
 
35
align 4
-
 
36
f77call:
-
 
37
        dd f77.futex_init     ;0
-
 
38
        dd f77.futex_wait     ;1
-
 
39
        dd f77.futex_wake     ;2
-
 
40
.end:
-
 
41
endg
-
 
42
 
-
 
43
align 4
-
 
44
sys_synchronization:
-
 
45
f77:
-
 
46
        cmp     ebx, (f77call.end-f77call)/4
-
 
47
        jae .fail
-
 
48
 
-
 
49
        jmp     dword [f77call+ebx*4]
-
 
50
 
-
 
51
.fail:
-
 
52
        mov     [esp+SYSCALL_STACK._eax], -1
-
 
53
        ret
-
 
54
 
-
 
55
 
-
 
56
align 4
-
 
57
.futex_init:
-
 
58
        call    create_futex
-
 
59
        test    eax, eax
-
 
60
        jz      @F
-
 
61
        mov     eax, [eax+FUTEX.handle]
-
 
62
@@:
-
 
63
        mov     [esp+SYSCALL_STACK._eax], eax
-
 
64
        ret
-
 
65
 
-
 
66
align 4
-
 
67
;ecx futex handle
-
 
68
;edx control value
-
 
69
.futex_wait:
-
 
70
        cmp     ecx, 3
-
 
71
        jb      .epicfail
-
 
72
        cmp     ecx, (PROC.pdt_0 - PROC.htab)/4
-
 
73
        jae     .epicfail
-
 
74
 
-
 
75
        mov     esi, [current_process]
-
 
76
        mov     edi, [esi+PROC.htab+ecx*4]
-
 
77
 
-
 
78
        cmp     [edi+FUTEX.magic], 'FUTX'
-
 
79
        jne     .epicfail
-
 
80
        cmp     [edi+FUTEX.handle], ecx
-
 
81
        jne     .epicfail
-
 
82
 
-
 
83
        mov     ecx, [edi+FUTEX.pointer]
-
 
84
 
-
 
85
        mov     eax, edx
-
 
86
        lock cmpxchg [ecx], edx         ;wait until old_value == new_value
-
 
87
        jz .wait_slow
-
 
88
 
-
 
89
        mov     [esp+SYSCALL_STACK._eax], 0
-
 
90
        ret
-
 
91
 
-
 
92
.wait_slow:
-
 
93
        pushfd
-
 
94
        cli
-
 
95
 
-
 
96
        sub     esp, sizeof.MUTEX_WAITER
-
 
97
        mov     ebx, [TASK_BASE]
-
 
98
        mov     [ebx+TASKDATA.state], 1
-
 
99
        mov     [esp+MUTEX_WAITER.task], ebx
-
 
100
        lea     esi, [edi+FUTEX.wait_list]
-
 
101
 
-
 
102
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
-
 
103
 
-
 
104
.again:
-
 
105
        call    change_task
-
 
106
 
-
 
107
        lock cmpxchg [ecx], edx
-
 
108
        jz .again
-
 
109
 
-
 
110
        list_del esp
-
 
111
        add     esp, sizeof.MUTEX_WAITER
-
 
112
 
-
 
113
        popfd
-
 
114
        mov     [esp+SYSCALL_STACK._eax], 0
-
 
115
        ret
-
 
116
 
-
 
117
.epicfail:
-
 
118
        mov     [esp+SYSCALL_STACK._eax], -1
-
 
119
        ret
-
 
120
 
-
 
121
align 4
-
 
122
;ecx futex handle
-
 
123
;edx threads count
-
 
124
.futex_wake:
-
 
125
        cmp     ecx, 3
-
 
126
        jb      .epicfail
-
 
127
        cmp     ecx, (PROC.pdt_0 - PROC.htab)/4
-
 
128
        jae     .epicfail
-
 
129
 
-
 
130
        mov     esi, [current_process]
-
 
131
        mov     edi, [esi+PROC.htab+ecx*4]
-
 
132
 
-
 
133
        cmp     [edi+FUTEX.magic], 'FUTX'
-
 
134
        jne     .epicfail
-
 
135
        cmp     [edi+FUTEX.handle], ecx
-
 
136
        jne     .epicfail
-
 
137
 
-
 
138
        xor     ecx, ecx
-
 
139
 
-
 
140
        pushfd
-
 
141
        cli
-
 
142
 
-
 
143
        lea     ebx, [edi+FUTEX.wait_list]
-
 
144
        mov     esi, [edi+FUTEX.wait_list.next]
-
 
145
@@:
-
 
146
        cmp     esi, ebx
-
 
147
        je      @F
-
 
148
 
-
 
149
        mov     eax, [esi+MUTEX_WAITER.task]
-
 
150
        mov     [eax+TASKDATA.state], 0
-
 
151
 
-
 
152
        mov     esi, [esi+MUTEX_WAITER.list.next]
-
 
153
        inc     ecx
-
 
154
        cmp     ecx, edx
-
 
155
        jb      @B
-
 
156
@@:
-
 
157
        popfd
-
 
158
        mov     [esp+SYSCALL_STACK._eax], ecx
-
 
159
        ret
-
 
160
 
-
 
161
RWSEM_WAITING_FOR_WRITE equ 0
-
 
162
RWSEM_WAITING_FOR_READ  equ 1
-
 
163
 
-
 
164
;void  __fastcall mutex_init(struct mutex *lock)
-
 
165
 
-
 
166
align 4
-
 
167
mutex_init:
-
 
168
        mov     [ecx+MUTEX.wait_list.next], ecx
-
 
169
        mov     [ecx+MUTEX.wait_list.prev], ecx
-
 
170
        mov     [ecx+MUTEX.count], 1
-
 
171
        ret
-
 
172
 
-
 
173
;void  __fastcall mutex_lock(struct mutex *lock)
-
 
174
 
-
 
175
align 4
-
 
176
mutex_lock:
-
 
177
 
-
 
178
        dec     [ecx+MUTEX.count]
-
 
179
        jns     .done
-
 
180
 
-
 
181
        pushfd
-
 
182
        cli
-
 
183
 
-
 
184
        sub     esp, sizeof.MUTEX_WAITER
-
 
185
 
-
 
186
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
-
 
187
 
-
 
188
        mov     edx, [TASK_BASE]
-
 
189
        mov     [esp+MUTEX_WAITER.task], edx
-
 
190
 
-
 
191
.forever:
-
 
192
 
-
 
193
        mov     eax, -1
-
 
194
        xchg    eax, [ecx+MUTEX.count]
-
 
195
        dec     eax
-
 
196
        jz      @F
-
 
197
 
-
 
198
        mov     [edx+TASKDATA.state], 1
-
 
199
        call    change_task
-
 
200
        jmp     .forever
-
 
201
@@:
-
 
202
        mov     eax, ecx
-
 
203
        list_del esp
-
 
204
 
-
 
205
        cmp     [eax+MUTEX.wait_list.next], eax
-
 
206
        jne     @F
-
 
207
 
-
 
208
        mov     [eax+MUTEX.count], 0
-
 
209
@@:
-
 
210
        add     esp, sizeof.MUTEX_WAITER
-
 
211
 
-
 
212
        popfd
-
 
213
.done:
-
 
214
        ret
-
 
215
 
-
 
216
;void  __fastcall mutex_unlock(struct mutex *lock)
-
 
217
 
-
 
218
align 4
-
 
219
mutex_unlock:
-
 
220
 
-
 
221
        pushfd
-
 
222
        cli
-
 
223
 
-
 
224
        mov     eax, [ecx+MUTEX.wait_list.next]
-
 
225
        cmp     eax, ecx
-
 
226
        mov     [ecx+MUTEX.count], 1
-
 
227
        je      @F
-
 
228
 
-
 
229
        mov     eax, [eax+MUTEX_WAITER.task]
-
 
230
        mov     [eax+TASKDATA.state], 0
-
 
231
@@:
-
 
232
        popfd
-
 
233
        ret
-
 
234
 
-
 
235
 
-
 
236
;void __fastcall init_rwsem(struct rw_semaphore *sem)
-
 
237
 
-
 
238
align 4
-
 
239
init_rwsem:
-
 
240
        mov     [ecx+RWSEM.wait_list.next], ecx
-
 
241
        mov     [ecx+RWSEM.wait_list.prev], ecx
-
 
242
        mov     [ecx+RWSEM.count], 0
-
 
243
        ret
-
 
244
 
-
 
245
;void __fastcall down_read(struct rw_semaphore *sem)
-
 
246
 
-
 
247
align 4
-
 
248
down_read:
-
 
249
        pushfd
-
 
250
        cli
-
 
251
 
-
 
252
        mov     eax, [ecx+RWSEM.count]
-
 
253
        test    eax, eax
-
 
254
        js      @F
-
 
255
 
-
 
256
        cmp     ecx, [ecx+RWSEM.wait_list.next]
-
 
257
        je      .ok
-
 
258
@@:
-
 
259
        sub     esp, sizeof.MUTEX_WAITER
-
 
260
 
-
 
261
        mov     eax, [TASK_BASE]
-
 
262
        mov     [esp+MUTEX_WAITER.task], eax
-
 
263
        mov     [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_READ
-
 
264
        mov     [eax+TASKDATA.state], 1
-
 
265
 
-
 
266
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
-
 
267
 
-
 
268
        call    change_task
-
 
269
 
-
 
270
        add     esp, sizeof.MUTEX_WAITER
-
 
271
        popfd
-
 
272
        ret
-
 
273
.ok:
-
 
274
        inc     eax
-
 
275
        mov     [ecx+RWSEM.count], eax
-
 
276
 
-
 
277
        popfd
-
 
278
        ret
-
 
279
 
-
 
280
;void __fastcall down_write(struct rw_semaphore *sem)
-
 
281
 
-
 
282
align 4
-
 
283
down_write:
-
 
284
        pushfd
-
 
285
        cli
-
 
286
        sub     esp, sizeof.MUTEX_WAITER
-
 
287
 
-
 
288
        mov     edx, [TASK_BASE]
-
 
289
        mov     [esp+MUTEX_WAITER.task], edx
-
 
290
        mov     [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE
-
 
291
        mov     [edx+TASKDATA.state], 1
-
 
292
 
-
 
293
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
-
 
294
 
-
 
295
        xor     eax, eax
-
 
296
        not     eax
-
 
297
 
-
 
298
.forever:
-
 
299
        test    eax, [ecx+RWSEM.count]
-
 
300
        jz      @F
-
 
301
 
-
 
302
        mov     [edx+TASKDATA.state], 1
-
 
303
        call    change_task
-
 
304
        jmp     .forever
-
 
305
@@:
-
 
306
        mov     [ecx+RWSEM.count], eax
-
 
307
        list_del esp
-
 
308
 
-
 
309
        add     esp, sizeof.MUTEX_WAITER
-
 
310
        popfd
-
 
311
        ret
-
 
312
 
-
 
313
;void __fastcall up_read(struct rw_semaphore *sem)
-
 
314
 
-
 
315
align 4
-
 
316
up_read:
-
 
317
        pushfd
-
 
318
        cli
-
 
319
 
-
 
320
        dec     [ecx+RWSEM.count]
-
 
321
        jnz     @F
-
 
322
 
-
 
323
        mov     eax, [ecx+RWSEM.wait_list.next]
-
 
324
        cmp     eax, ecx
-
 
325
        je      @F
-
 
326
 
-
 
327
        mov     eax, [eax+MUTEX_WAITER.task]
-
 
328
        mov     [eax+TASKDATA.state], 0
-
 
329
@@:
-
 
330
        popfd
-
 
331
        ret
-
 
332
 
-
 
333
;void __fastcall up_write(struct rw_semaphore *sem)
-
 
334
 
-
 
335
align 4
-
 
336
up_write:
-
 
337
 
-
 
338
        pushfd
-
 
339
        cli
-
 
340
 
-
 
341
        mov     eax, [ecx+RWSEM.wait_list.next]
-
 
342
        mov     [ecx+RWSEM.count], 0
-
 
343
 
-
 
344
        cmp     ecx, eax
-
 
345
        je      .done
-
 
346
 
-
 
347
        mov     edx, [eax+MUTEX_WAITER.type]
-
 
348
        test    edx, edx
-
 
349
        jnz     .wake
-
 
350
 
-
 
351
        mov     eax, [eax+MUTEX_WAITER.task]
-
 
352
        mov     [eax+TASKDATA.state], 0
-
 
353
.done:
-
 
354
        popfd
-
 
355
        ret
-
 
356
 
-
 
357
.wake:
-
 
358
        push    ebx
-
 
359
        push    esi
-
 
360
        push    edi
-
 
361
 
-
 
362
        xor     esi, esi
-
 
363
        mov     edi, ecx
-
 
364
 
-
 
365
.wake_list:
-
 
366
 
-
 
367
        mov     ebx, [eax+MUTEX_WAITER.list.next]
-
 
368
        list_del eax
-
 
369
        mov     edx, [eax+MUTEX_WAITER.task]
-
 
370
        mov     [edx+TASKDATA.state], 0
-
 
371
        inc     esi
-
 
372
        cmp     edi, ebx
-
 
373
        je      .wake_done
-
 
374
 
-
 
375
        mov     ecx, [ebx+MUTEX_WAITER.type]
-
 
376
        test    ecx, ecx
-
 
377
        jz      .wake_done
-
 
378
 
-
 
379
        mov     eax, ebx
-
 
380
        jmp     .wake_list
-
 
381
 
-
 
382
.wake_done:
-
 
383
        add     [edi+RWSEM.count], esi
-
 
384
 
-
 
385
        pop     edi
-
 
386
        pop     esi
-
 
387
        pop     ebx
-
 
388
        popfd
-
 
389
        ret
-
 
390
 
-
 
391
 
-
 
392
purge MUTEX_WAITER
-
 
393
purge RWSEM_WAITING_FOR_WRITE
Line 10... Line 394...
10
$Revision: 5565 $
394
purge RWSEM_WAITING_FOR_READ
11
 
395
 
12
 
396