Subversion Repositories Kolibri OS

Rev

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

Rev 5363 Rev 6079
Line 5... Line 5...
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
 
-
 
10
$Revision: 6079 $
-
 
11
 
-
 
12
align 4
-
 
13
;struct futex*  __fastcall create_futex(int *ptr)
-
 
14
create_futex:
-
 
15
        push    ecx
-
 
16
        mov     ecx, sizeof.FUTEX
-
 
17
        call    create_object
-
 
18
        pop     ecx
-
 
19
        test    eax, eax
-
 
20
        jz      .fail
-
 
21
 
-
 
22
        mov     [eax+FUTEX.magic], 'FUTX'
-
 
23
        mov     [eax+FUTEX.destroy], 0
-
 
24
        mov     [eax+FUTEX.pointer], ecx
-
 
25
        lea     ecx, [eax+FUTEX.wait_list]
-
 
26
        list_init ecx
-
 
27
        mov     [eax+FUTEX.flags], 0
-
 
28
.fail:
-
 
29
        ret
-
 
30
 
-
 
31
align 4
-
 
32
;int __fastcall destroy_futex(struct futex *futex)
-
 
33
destroy_futex:
-
 
34
        push    esi
-
 
35
        mov     esi, [current_process]
-
 
36
        mov     edx, [ecx+FUTEX.handle]
-
 
37
 
-
 
38
        pushfd
-
 
39
        cli
-
 
40
 
-
 
41
        lea     eax, [ecx+FUTEX.wait_list]
-
 
42
        cmp     eax, [eax+LHEAD.next]
-
 
43
        jne     .fail
-
 
44
 
-
 
45
        mov     eax, [esi+PROC.ht_next]
-
 
46
        mov     [esi+PROC.htab+edx*4], eax
-
 
47
        mov     [esi+PROC.ht_next], edx
-
 
48
        inc     [esi+PROC.ht_free]
-
 
49
 
-
 
50
        popfd
-
 
51
        pop     esi
-
 
52
 
-
 
53
        mov     eax, ecx
-
 
54
        call    free
-
 
55
        xor     eax, eax
-
 
56
        ret
-
 
57
 
-
 
58
.fail:
-
 
59
        popfd
-
 
60
        pop     esi
-
 
61
        mov     eax, -1
-
 
62
        ret
-
 
63
 
-
 
64
 
-
 
65
iglobal
-
 
66
align 4
-
 
67
f77call:
-
 
68
        dd f77.futex_init     ;0
-
 
69
        dd f77.futex_destroy  ;1
-
 
70
        dd f77.futex_wait     ;2
-
 
71
        dd f77.futex_wake     ;3
-
 
72
.end:
-
 
73
endg
-
 
74
 
-
 
75
align 4
-
 
76
sys_synchronization:
-
 
77
f77:
-
 
78
        test    ebx, ebx
-
 
79
        jz      .futex_init
-
 
80
 
-
 
81
        cmp     ebx, (f77call.end-f77call)/4
-
 
82
        jae     .fail
-
 
83
 
-
 
84
        cmp     ecx, STDERR_FILENO
-
 
85
        jbe     .fail
-
 
86
        cmp     ecx, (PROC.pdt_0 - PROC.htab)/4
-
 
87
        jae     .fail
-
 
88
 
-
 
89
        mov     edi, [current_process]
-
 
90
        mov     ebp, [edi+PROC.htab+ecx*4]
-
 
91
 
-
 
92
        cmp     [ebp+FUTEX.magic], 'FUTX'
-
 
93
        jne     .fail
-
 
94
        cmp     [ebp+FUTEX.handle], ecx
-
 
95
        jne     .fail
-
 
96
 
-
 
97
        jmp     dword [f77call+ebx*4]
-
 
98
 
-
 
99
.fail:
-
 
100
        mov     [esp+SYSCALL_STACK._eax], -1
-
 
101
        ret
-
 
102
 
-
 
103
align 4
-
 
104
.futex_init:
-
 
105
        call    create_futex
-
 
106
        test    eax, eax
-
 
107
        jz      @F
-
 
108
        mov     eax, [eax+FUTEX.handle]
-
 
109
@@:
-
 
110
        mov     [esp+SYSCALL_STACK._eax], eax
-
 
111
        ret
-
 
112
 
-
 
113
 
-
 
114
align 4
-
 
115
;ecx futex handle
-
 
116
;edi current process
-
 
117
;ebp futex object
-
 
118
.futex_destroy:
-
 
119
        mov     ecx, ebp
-
 
120
        call    destroy_futex
-
 
121
        mov     [esp+SYSCALL_STACK._eax], eax
-
 
122
        ret
-
 
123
 
-
 
124
align 4
-
 
125
;ecx futex handle
-
 
126
;edx control value
-
 
127
;esi timeout
-
 
128
;edi current process
-
 
129
;ebp futex object
-
 
130
.futex_wait:
-
 
131
        test    esi, esi
-
 
132
        jnz     .futex_wait_timeout
-
 
133
        mov     ecx, [ebp+FUTEX.pointer]
-
 
134
        mov     eax, edx
-
 
135
        lock cmpxchg [ecx], edx         ;wait until old_value == new_value
-
 
136
        jz      .wait_slow
-
 
137
 
-
 
138
        mov     [esp+SYSCALL_STACK._eax], 0
-
 
139
        ret
-
 
140
 
-
 
141
.wait_slow:
-
 
142
        pushfd
-
 
143
        cli
-
 
144
 
-
 
145
        sub     esp, sizeof.MUTEX_WAITER
-
 
146
        mov     ebx, [TASK_BASE]
-
 
147
        mov     [esp+MUTEX_WAITER.task], ebx
-
 
148
        lea     esi, [ebp+FUTEX.wait_list]
-
 
149
 
-
 
150
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
-
 
151
 
-
 
152
.again:
-
 
153
        mov     [ebx+TASKDATA.state], 1
-
 
154
        call    change_task
-
 
155
 
-
 
156
        lock cmpxchg [ecx], edx
-
 
157
        jz      .again
-
 
158
 
-
 
159
        list_del esp
-
 
160
        add     esp, sizeof.MUTEX_WAITER
-
 
161
 
-
 
162
        popfd
-
 
163
        mov     [esp+SYSCALL_STACK._eax], 0
-
 
164
        ret
-
 
165
 
-
 
166
align 4
-
 
167
;ecx futex handle
-
 
168
;edx control value
-
 
169
;esi timeout
-
 
170
;edi current process
-
 
171
;ebp futex object
-
 
172
 
-
 
173
.futex_wait_timeout:
-
 
174
        mov     ecx, [ebp+FUTEX.pointer]
-
 
175
        mov     eax, edx
-
 
176
        lock cmpxchg [ecx], edx         ;wait until old_value == new_value
-
 
177
        jz      .wait_slow_timeout
-
 
178
 
-
 
179
        mov     [esp+SYSCALL_STACK._eax], 0
-
 
180
        ret
-
 
181
 
-
 
182
align 4
-
 
183
.wait_test:
-
 
184
        xor     eax, eax
-
 
185
        ret
-
 
186
 
-
 
187
.wait_slow_timeout:
-
 
188
        pushfd
-
 
189
        cli
-
 
190
 
-
 
191
        sub     esp, sizeof.MUTEX_WAITER
-
 
192
 
-
 
193
        mov     ebx, [current_slot]
-
 
194
        mov     [ebx+APPDATA.wait_test], f77.wait_test
-
 
195
        mov     [ebx+APPDATA.wait_timeout], esi
-
 
196
        mov     [ebx+APPDATA.wait_param], ebp
-
 
197
        mov     eax, [timer_ticks]
-
 
198
        mov     [ebx+APPDATA.wait_begin], eax
-
 
199
        mov     eax, [TASK_BASE]
-
 
200
        mov     [eax+TASKDATA.state], 5
-
 
201
 
-
 
202
        mov     [esp+MUTEX_WAITER.task], eax
-
 
203
        lea     esi, [ebp+FUTEX.wait_list]
-
 
204
 
-
 
205
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
-
 
206
 
-
 
207
.again_timeout:
-
 
208
        call    change_task
-
 
209
        mov     eax, [ebx+APPDATA.wait_param]
-
 
210
        test    eax, eax
-
 
211
        jz      .timeout
-
 
212
 
-
 
213
        lock cmpxchg [ecx], edx
-
 
214
        jz      .again_timeout
-
 
215
@@:
-
 
216
        list_del esp
-
 
217
        add     esp, sizeof.MUTEX_WAITER
-
 
218
 
-
 
219
        popfd
-
 
220
        mov     [esp+SYSCALL_STACK._eax], 0
-
 
221
        ret
-
 
222
 
-
 
223
.timeout:
-
 
224
        list_del esp
-
 
225
        add     esp, sizeof.MUTEX_WAITER
-
 
226
 
-
 
227
        popfd
-
 
228
        mov     [esp+SYSCALL_STACK._eax], -1
-
 
229
        ret
-
 
230
 
-
 
231
 
-
 
232
align 4
-
 
233
;ecx futex handle
-
 
234
;edx number of threads
-
 
235
;edi current process
-
 
236
;ebp futex object
-
 
237
.futex_wake:
-
 
238
 
-
 
239
        xor     ecx, ecx
-
 
240
 
-
 
241
        pushfd
-
 
242
        cli
-
 
243
 
-
 
244
        lea     ebx, [ebp+FUTEX.wait_list]
-
 
245
        mov     esi, [ebx+LHEAD.next]
-
 
246
.wake:
-
 
247
        cmp     esi, ebx
-
 
248
        je      .done
-
 
249
 
-
 
250
        mov     eax, [esi+MUTEX_WAITER.task]
-
 
251
        mov     [eax+TASKDATA.state], 0
-
 
252
 
-
 
253
        mov     esi, [esi+MUTEX_WAITER.list.next]
-
 
254
        inc     ecx
-
 
255
        cmp     ecx, edx
-
 
256
        jb      .wake
-
 
257
.done:
-
 
258
        popfd
-
 
259
        mov     [esp+SYSCALL_STACK._eax], ecx
-
 
260
        ret
-
 
261
 
-
 
262
RWSEM_WAITING_FOR_WRITE equ 0
-
 
263
RWSEM_WAITING_FOR_READ  equ 1
-
 
264
 
-
 
265
;void  __fastcall mutex_init(struct mutex *lock)
-
 
266
 
-
 
267
align 4
-
 
268
mutex_init:
-
 
269
        mov     [ecx+MUTEX.wait_list.next], ecx
-
 
270
        mov     [ecx+MUTEX.wait_list.prev], ecx
-
 
271
        mov     [ecx+MUTEX.count], 1
-
 
272
        ret
-
 
273
 
-
 
274
;void  __fastcall mutex_lock(struct mutex *lock)
-
 
275
 
-
 
276
align 4
-
 
277
mutex_lock:
-
 
278
 
-
 
279
        dec     [ecx+MUTEX.count]
-
 
280
        jns     .done
-
 
281
 
-
 
282
        pushfd
-
 
283
        cli
-
 
284
 
-
 
285
        sub     esp, sizeof.MUTEX_WAITER
-
 
286
 
-
 
287
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
-
 
288
 
-
 
289
        mov     edx, [TASK_BASE]
-
 
290
        mov     [esp+MUTEX_WAITER.task], edx
-
 
291
 
-
 
292
.forever:
-
 
293
 
-
 
294
        mov     eax, -1
-
 
295
        xchg    eax, [ecx+MUTEX.count]
-
 
296
        dec     eax
-
 
297
        jz      @F
-
 
298
 
-
 
299
        mov     [edx+TASKDATA.state], 1
-
 
300
        call    change_task
-
 
301
        jmp     .forever
-
 
302
@@:
-
 
303
        mov     eax, ecx
-
 
304
        list_del esp
-
 
305
 
-
 
306
        cmp     [eax+MUTEX.wait_list.next], eax
-
 
307
        jne     @F
-
 
308
 
-
 
309
        mov     [eax+MUTEX.count], 0
-
 
310
@@:
-
 
311
        add     esp, sizeof.MUTEX_WAITER
-
 
312
 
-
 
313
        popfd
-
 
314
.done:
-
 
315
        ret
-
 
316
 
-
 
317
;void  __fastcall mutex_unlock(struct mutex *lock)
-
 
318
 
-
 
319
align 4
-
 
320
mutex_unlock:
-
 
321
 
-
 
322
        pushfd
-
 
323
        cli
-
 
324
 
-
 
325
        mov     eax, [ecx+MUTEX.wait_list.next]
-
 
326
        cmp     eax, ecx
-
 
327
        mov     [ecx+MUTEX.count], 1
-
 
328
        je      @F
-
 
329
 
-
 
330
        mov     eax, [eax+MUTEX_WAITER.task]
-
 
331
        mov     [eax+TASKDATA.state], 0
-
 
332
@@:
-
 
333
        popfd
-
 
334
        ret
-
 
335
 
-
 
336
 
-
 
337
;void __fastcall init_rwsem(struct rw_semaphore *sem)
-
 
338
 
-
 
339
align 4
-
 
340
init_rwsem:
-
 
341
        mov     [ecx+RWSEM.wait_list.next], ecx
-
 
342
        mov     [ecx+RWSEM.wait_list.prev], ecx
-
 
343
        mov     [ecx+RWSEM.count], 0
-
 
344
        ret
-
 
345
 
-
 
346
;void __fastcall down_read(struct rw_semaphore *sem)
-
 
347
 
-
 
348
align 4
-
 
349
down_read:
-
 
350
        pushfd
-
 
351
        cli
-
 
352
 
-
 
353
        mov     eax, [ecx+RWSEM.count]
-
 
354
        test    eax, eax
-
 
355
        js      @F
-
 
356
 
-
 
357
        cmp     ecx, [ecx+RWSEM.wait_list.next]
-
 
358
        je      .ok
-
 
359
@@:
-
 
360
        sub     esp, sizeof.MUTEX_WAITER
-
 
361
 
-
 
362
        mov     eax, [TASK_BASE]
-
 
363
        mov     [esp+MUTEX_WAITER.task], eax
-
 
364
        mov     [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_READ
-
 
365
        mov     [eax+TASKDATA.state], 1
-
 
366
 
-
 
367
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
-
 
368
 
-
 
369
        call    change_task
-
 
370
 
-
 
371
        add     esp, sizeof.MUTEX_WAITER
-
 
372
        popfd
-
 
373
        ret
-
 
374
.ok:
-
 
375
        inc     eax
-
 
376
        mov     [ecx+RWSEM.count], eax
-
 
377
 
-
 
378
        popfd
-
 
379
        ret
-
 
380
 
-
 
381
;void __fastcall down_write(struct rw_semaphore *sem)
-
 
382
 
-
 
383
align 4
-
 
384
down_write:
-
 
385
        pushfd
-
 
386
        cli
-
 
387
        sub     esp, sizeof.MUTEX_WAITER
-
 
388
 
-
 
389
        mov     edx, [TASK_BASE]
-
 
390
        mov     [esp+MUTEX_WAITER.task], edx
-
 
391
        mov     [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE
-
 
392
        mov     [edx+TASKDATA.state], 1
-
 
393
 
-
 
394
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
-
 
395
 
-
 
396
        xor     eax, eax
-
 
397
        not     eax
-
 
398
 
-
 
399
.forever:
-
 
400
        test    eax, [ecx+RWSEM.count]
-
 
401
        jz      @F
-
 
402
 
-
 
403
        mov     [edx+TASKDATA.state], 1
-
 
404
        call    change_task
-
 
405
        jmp     .forever
-
 
406
@@:
-
 
407
        mov     [ecx+RWSEM.count], eax
-
 
408
        list_del esp
-
 
409
 
-
 
410
        add     esp, sizeof.MUTEX_WAITER
-
 
411
        popfd
-
 
412
        ret
-
 
413
 
-
 
414
;void __fastcall up_read(struct rw_semaphore *sem)
-
 
415
 
-
 
416
align 4
-
 
417
up_read:
-
 
418
        pushfd
-
 
419
        cli
-
 
420
 
-
 
421
        dec     [ecx+RWSEM.count]
-
 
422
        jnz     @F
-
 
423
 
-
 
424
        mov     eax, [ecx+RWSEM.wait_list.next]
-
 
425
        cmp     eax, ecx
-
 
426
        je      @F
-
 
427
 
-
 
428
        mov     eax, [eax+MUTEX_WAITER.task]
-
 
429
        mov     [eax+TASKDATA.state], 0
-
 
430
@@:
-
 
431
        popfd
-
 
432
        ret
-
 
433
 
-
 
434
;void __fastcall up_write(struct rw_semaphore *sem)
-
 
435
 
-
 
436
align 4
-
 
437
up_write:
-
 
438
 
-
 
439
        pushfd
-
 
440
        cli
-
 
441
 
-
 
442
        mov     eax, [ecx+RWSEM.wait_list.next]
-
 
443
        mov     [ecx+RWSEM.count], 0
-
 
444
 
-
 
445
        cmp     ecx, eax
-
 
446
        je      .done
-
 
447
 
-
 
448
        mov     edx, [eax+MUTEX_WAITER.type]
-
 
449
        test    edx, edx
-
 
450
        jnz     .wake
-
 
451
 
-
 
452
        mov     eax, [eax+MUTEX_WAITER.task]
-
 
453
        mov     [eax+TASKDATA.state], 0
-
 
454
.done:
-
 
455
        popfd
-
 
456
        ret
-
 
457
 
-
 
458
.wake:
-
 
459
        push    ebx
-
 
460
        push    esi
-
 
461
        push    edi
-
 
462
 
-
 
463
        xor     esi, esi
-
 
464
        mov     edi, ecx
-
 
465
 
-
 
466
.wake_list:
-
 
467
 
-
 
468
        mov     ebx, [eax+MUTEX_WAITER.list.next]
-
 
469
        list_del eax
-
 
470
        mov     edx, [eax+MUTEX_WAITER.task]
-
 
471
        mov     [edx+TASKDATA.state], 0
-
 
472
        inc     esi
-
 
473
        cmp     edi, ebx
-
 
474
        je      .wake_done
-
 
475
 
-
 
476
        mov     ecx, [ebx+MUTEX_WAITER.type]
-
 
477
        test    ecx, ecx
-
 
478
        jz      .wake_done
-
 
479
 
-
 
480
        mov     eax, ebx
-
 
481
        jmp     .wake_list
-
 
482
 
-
 
483
.wake_done:
-
 
484
        add     [edi+RWSEM.count], esi
-
 
485
 
-
 
486
        pop     edi
-
 
487
        pop     esi
-
 
488
        pop     ebx
-
 
489
        popfd
-
 
490
        ret
-
 
491
 
-
 
492
 
-
 
493
purge RWSEM_WAITING_FOR_WRITE
Line 10... Line 494...
10
$Revision: 5363 $
494
purge RWSEM_WAITING_FOR_READ
11
 
495
 
12
 
496