Subversion Repositories Kolibri OS

Rev

Rev 9715 | Details | Compare with Previous | Last modification | View Log | RSS feed

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