Subversion Repositories Kolibri OS

Rev

Rev 6926 | Rev 9709 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2288 clevermous 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
5363 yogev_ezra 3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
2288 clevermous 4
;; Distributed under terms of the GNU General Public License    ;;
5
;;                                                              ;;
6
;; Synhronization for MenuetOS.                                 ;;
7
;; Author: Halyavin Andrey, halyavin@land.ru                    ;;
8
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
9
 
10
$Revision: 7136 $
11
 
12
 
6079 serge 13
 
7136 dunkaist 14
RWSEM_WAITING_FOR_WRITE = 0
15
RWSEM_WAITING_FOR_READ  = 1
6079 serge 16
 
17
;void  __fastcall mutex_init(struct mutex *lock)
18
 
19
align 4
20
mutex_init:
21
        mov     [ecx+MUTEX.wait_list.next], ecx
22
        mov     [ecx+MUTEX.wait_list.prev], ecx
23
        mov     [ecx+MUTEX.count], 1
24
        ret
25
 
26
;void  __fastcall mutex_lock(struct mutex *lock)
27
 
28
align 4
29
mutex_lock:
30
 
31
        dec     [ecx+MUTEX.count]
32
        jns     .done
33
 
34
        pushfd
35
        cli
36
 
37
        sub     esp, sizeof.MUTEX_WAITER
38
 
39
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
40
 
41
        mov     edx, [TASK_BASE]
42
        mov     [esp+MUTEX_WAITER.task], edx
43
 
44
.forever:
45
 
46
        mov     eax, -1
47
        xchg    eax, [ecx+MUTEX.count]
48
        dec     eax
49
        jz      @F
50
 
51
        mov     [edx+TASKDATA.state], 1
52
        call    change_task
53
        jmp     .forever
54
@@:
55
        mov     eax, ecx
56
        list_del esp
57
 
58
        cmp     [eax+MUTEX.wait_list.next], eax
59
        jne     @F
60
 
61
        mov     [eax+MUTEX.count], 0
62
@@:
63
        add     esp, sizeof.MUTEX_WAITER
64
 
65
        popfd
66
.done:
67
        ret
68
 
69
;void  __fastcall mutex_unlock(struct mutex *lock)
70
 
71
align 4
72
mutex_unlock:
73
 
74
        pushfd
75
        cli
76
 
77
        mov     eax, [ecx+MUTEX.wait_list.next]
78
        cmp     eax, ecx
79
        mov     [ecx+MUTEX.count], 1
80
        je      @F
81
 
82
        mov     eax, [eax+MUTEX_WAITER.task]
83
        mov     [eax+TASKDATA.state], 0
84
@@:
85
        popfd
86
        ret
87
 
88
 
89
;void __fastcall init_rwsem(struct rw_semaphore *sem)
90
 
91
align 4
92
init_rwsem:
93
        mov     [ecx+RWSEM.wait_list.next], ecx
94
        mov     [ecx+RWSEM.wait_list.prev], ecx
95
        mov     [ecx+RWSEM.count], 0
96
        ret
97
 
98
;void __fastcall down_read(struct rw_semaphore *sem)
99
 
100
align 4
101
down_read:
102
        pushfd
103
        cli
104
 
105
        mov     eax, [ecx+RWSEM.count]
106
        test    eax, eax
107
        js      @F
108
 
109
        cmp     ecx, [ecx+RWSEM.wait_list.next]
110
        je      .ok
111
@@:
112
        sub     esp, sizeof.MUTEX_WAITER
113
 
114
        mov     eax, [TASK_BASE]
115
        mov     [esp+MUTEX_WAITER.task], eax
116
        mov     [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_READ
117
        mov     [eax+TASKDATA.state], 1
118
 
119
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
120
 
121
        call    change_task
122
 
123
        add     esp, sizeof.MUTEX_WAITER
124
        popfd
125
        ret
126
.ok:
127
        inc     eax
128
        mov     [ecx+RWSEM.count], eax
129
 
130
        popfd
131
        ret
132
 
133
;void __fastcall down_write(struct rw_semaphore *sem)
134
 
135
align 4
136
down_write:
137
        pushfd
138
        cli
139
        sub     esp, sizeof.MUTEX_WAITER
140
 
141
        mov     edx, [TASK_BASE]
142
        mov     [esp+MUTEX_WAITER.task], edx
143
        mov     [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE
144
        mov     [edx+TASKDATA.state], 1
145
 
146
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
147
 
148
        xor     eax, eax
149
        not     eax
150
 
151
.forever:
152
        test    eax, [ecx+RWSEM.count]
153
        jz      @F
154
 
155
        mov     [edx+TASKDATA.state], 1
156
        call    change_task
157
        jmp     .forever
158
@@:
159
        mov     [ecx+RWSEM.count], eax
160
        list_del esp
161
 
162
        add     esp, sizeof.MUTEX_WAITER
163
        popfd
164
        ret
165
 
166
;void __fastcall up_read(struct rw_semaphore *sem)
167
 
168
align 4
169
up_read:
170
        pushfd
171
        cli
172
 
173
        dec     [ecx+RWSEM.count]
174
        jnz     @F
175
 
176
        mov     eax, [ecx+RWSEM.wait_list.next]
177
        cmp     eax, ecx
178
        je      @F
179
 
180
        mov     eax, [eax+MUTEX_WAITER.task]
181
        mov     [eax+TASKDATA.state], 0
182
@@:
183
        popfd
184
        ret
185
 
186
;void __fastcall up_write(struct rw_semaphore *sem)
187
 
188
align 4
189
up_write:
190
 
191
        pushfd
192
        cli
193
 
194
        mov     eax, [ecx+RWSEM.wait_list.next]
195
        mov     [ecx+RWSEM.count], 0
196
 
197
        cmp     ecx, eax
198
        je      .done
199
 
200
        mov     edx, [eax+MUTEX_WAITER.type]
201
        test    edx, edx
202
        jnz     .wake
203
 
204
        mov     eax, [eax+MUTEX_WAITER.task]
205
        mov     [eax+TASKDATA.state], 0
206
.done:
207
        popfd
208
        ret
209
 
210
.wake:
211
        push    ebx
212
        push    esi
213
        push    edi
214
 
215
        xor     esi, esi
216
        mov     edi, ecx
217
 
218
.wake_list:
219
 
220
        mov     ebx, [eax+MUTEX_WAITER.list.next]
221
        list_del eax
222
        mov     edx, [eax+MUTEX_WAITER.task]
223
        mov     [edx+TASKDATA.state], 0
224
        inc     esi
225
        cmp     edi, ebx
226
        je      .wake_done
227
 
228
        mov     ecx, [ebx+MUTEX_WAITER.type]
229
        test    ecx, ecx
230
        jz      .wake_done
231
 
232
        mov     eax, ebx
233
        jmp     .wake_list
234
 
235
.wake_done:
236
        add     [edi+RWSEM.count], esi
237
 
238
        pop     edi
239
        pop     esi
240
        pop     ebx
241
        popfd
242
        ret
243
 
244
 
245
purge RWSEM_WAITING_FOR_WRITE
246
purge RWSEM_WAITING_FOR_READ
247
 
248
 
2288 clevermous 249
if ~defined sync_inc
250
sync_inc_fix:
251
sync_inc fix sync_inc_fix
252
 
253
;simplest mutex.
254
macro SimpleMutex name
255
{
256
;  iglobal
257
    name dd 0
258
    name#.type = 1
259
;  endg
260
}
261
macro WaitSimpleMutex name
262
{
263
  local start_wait,ok
264
start_wait=$
265
        cli
266
        cmp     [name], dword 0
267
        jz      ok
268
        sti
269
        call    change_task
270
        jmp     start_wait
271
ok=$
272
        push    eax
273
        mov     eax, dword [TASK_BASE+second_base_address]
274
        mov     eax, [eax+TASKDATA.pid]
275
        mov     [name], eax
276
        pop     eax
277
        sti
278
}
279
macro ReleaseSimpleMutex name
280
{
281
        mov     [name], dword 0
282
}
283
macro TryWaitSimpleMutex name  ;result in eax and in flags
284
{
285
  local ok,try_end
286
        cmp     [name], dword 0
287
        jz      ok
288
        xor     eax, eax
289
        jmp     try_end
290
ok=$
291
        xor     eax, eax
292
        inc     eax
293
try_end=$
294
}
295
macro SimpleCriticalSection name
296
{
297
;  iglobal
298
    name  dd 0
299
          dd 0
300
    name#.type=2
301
;  endg
302
}
303
macro WaitSimpleCriticalSection name
304
{
305
  local start_wait,first_wait,inc_counter,end_wait
306
        push    eax
307
        mov     eax, [TASK_BASE+second_base_address]
308
        mov     eax, [eax+TASKDATA.pid]
309
start_wait=$
310
        cli
311
        cmp     [name], dword 0
312
        jz      first_wait
313
        cmp     [name], eax
314
        jz      inc_counter
315
        sti
316
        call    change_task
317
        jmp     start_wait
318
first_wait=$
319
        mov     [name], eax
320
        mov     [name+4], dword 1
321
        jmp     end_wait
322
inc_counter=$
323
        inc     dword [name+4]
324
end_wait=$
325
        sti
326
        pop     eax
327
}
328
macro ReleaseSimpleCriticalSection name
329
{
330
  local release_end
331
        dec     dword [name+4]
332
        jnz     release_end
333
        mov     [name], dword 0
334
release_end=$
335
}
336
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
337
{
338
  local ok,try_end
339
        mov     eax, [CURRENT_TASK+second_base_address]
340
        mov     eax, [eax+TASKDATA.pid]
341
        cmp     [name], eax
342
        jz      ok
343
        cmp     [name], 0
344
        jz      ok
345
        xor     eax, eax
346
        jmp     try_end
347
ok=$
348
        xor     eax, eax
349
        inc     eax
350
try_end=$
351
}
352
_cli equ call MEM_HeapLock
353
_sti equ call MEM_HeapUnLock
354
end if
355