Subversion Repositories Kolibri OS

Rev

Rev 5599 | Rev 6078 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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