Subversion Repositories Kolibri OS

Rev

Rev 9709 | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 9709 Rev 9715
Line 1... Line 1...
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
2
;;                                                              ;;
3
;; Copyright (C) KolibriOS team 2004-2015. All rights reserved. ;;
3
;; Copyright (C) KolibriOS team 2004-2022. 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
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Line 9... Line 9...
9
 
9
 
Line 10... Line 10...
10
$Revision: 9709 $
10
$Revision: 9715 $
11
 
11
 
Line 12... Line 12...
12
 
12
 
Line 13... Line 13...
13
 
13
 
14
RWSEM_WAITING_FOR_WRITE = 0
14
RWSEM_WAITING_FOR_WRITE = 0
15
RWSEM_WAITING_FOR_READ  = 1
15
RWSEM_WAITING_FOR_READ  = 1
16
 
16
 
17
;void  __fastcall mutex_init(struct mutex *lock)
17
;void  __fastcall mutex_init(struct mutex *lock)
18
 
18
 
Line 19... Line 19...
19
align 4
19
align 4
Line 20... Line 20...
20
mutex_init:
20
mutex_init:
21
        mov     [ecx+MUTEX.wait_list.next], ecx
21
        mov     [ecx + MUTEX.wait_list.next], ecx
Line 22... Line 22...
22
        mov     [ecx+MUTEX.wait_list.prev], ecx
22
        mov     [ecx + MUTEX.wait_list.prev], ecx
23
        mov     [ecx+MUTEX.count], 1
23
        mov     [ecx + MUTEX.count], 1
Line 24... Line 24...
24
        ret
24
        ret
25
 
25
 
Line 26... Line 26...
26
;void  __fastcall mutex_lock(struct mutex *lock)
26
;void  __fastcall mutex_lock(struct mutex *lock)
Line 27... Line 27...
27
 
27
 
Line 28... Line 28...
28
align 4
28
align 4
29
mutex_lock:
29
mutex_lock:
Line 30... Line 30...
30
 
30
 
Line 31... Line 31...
31
        dec     [ecx+MUTEX.count]
31
        dec     [ecx + MUTEX.count]
32
        jns     .done
32
        jns     .done
33
 
33
 
34
        pushfd
34
        pushfd
Line 35... Line 35...
35
        cli
35
        cli
36
 
36
 
37
        sub     esp, sizeof.MUTEX_WAITER
37
        sub     esp, sizeof.MUTEX_WAITER
38
 
38
 
39
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
39
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
40
 
40
 
Line 41... Line 41...
41
        mov     edx, [current_slot]
41
        mov     edx, [current_slot]
42
        mov     [esp+MUTEX_WAITER.task], edx
42
        mov     [esp + MUTEX_WAITER.task], edx
Line 43... Line 43...
43
 
43
 
44
.forever:
44
.forever:
45
 
45
 
Line 46... Line 46...
46
        mov     eax, -1
46
        mov     eax, -1
47
        xchg    eax, [ecx+MUTEX.count]
47
        xchg    eax, [ecx + MUTEX.count]
Line 72... Line 72...
72
mutex_unlock:
72
mutex_unlock:
Line 73... Line 73...
73
 
73
 
74
        pushfd
74
        pushfd
Line 75... Line 75...
75
        cli
75
        cli
76
 
76
 
77
        mov     eax, [ecx+MUTEX.wait_list.next]
77
        mov     eax, [ecx + MUTEX.wait_list.next]
78
        cmp     eax, ecx
78
        cmp     eax, ecx
Line 79... Line 79...
79
        mov     [ecx+MUTEX.count], 1
79
        mov     [ecx + MUTEX.count], 1
80
        je      @F
80
        je      @F
81
 
81
 
82
        mov     eax, [eax+MUTEX_WAITER.task]
82
        mov     eax, [eax + MUTEX_WAITER.task]
83
        mov     [eax + APPDATA.state], TSTATE_RUNNING
83
        mov     [eax + APPDATA.state], TSTATE_RUNNING
Line 84... Line 84...
84
@@:
84
@@:
Line 85... Line 85...
85
        popfd
85
        popfd
86
        ret
86
        ret
87
 
87
 
88
 
88
 
89
;void __fastcall init_rwsem(struct rw_semaphore *sem)
89
;void __fastcall init_rwsem(struct rw_semaphore *sem)
90
 
90
 
Line 91... Line 91...
91
align 4
91
align 4
Line 92... Line 92...
92
init_rwsem:
92
init_rwsem:
93
        mov     [ecx+RWSEM.wait_list.next], ecx
93
        mov     [ecx + RWSEM.wait_list.next], ecx
94
        mov     [ecx+RWSEM.wait_list.prev], ecx
94
        mov     [ecx + RWSEM.wait_list.prev], ecx
95
        mov     [ecx+RWSEM.count], 0
95
        mov     [ecx + RWSEM.count], 0
Line 96... Line 96...
96
        ret
96
        ret
97
 
97
 
98
;void __fastcall down_read(struct rw_semaphore *sem)
98
;void __fastcall down_read(struct rw_semaphore *sem)
Line 99... Line 99...
99
 
99
 
100
align 4
100
align 4
101
down_read:
101
down_read:
102
        pushfd
102
        pushfd
Line 103... Line 103...
103
        cli
103
        cli
104
 
104
 
105
        mov     eax, [ecx+RWSEM.count]
105
        mov     eax, [ecx + RWSEM.count]
106
        test    eax, eax
106
        test    eax, eax
Line 107... Line 107...
107
        js      @F
107
        js      @F
Line 108... Line 108...
108
 
108
 
Line 123... Line 123...
123
        add     esp, sizeof.MUTEX_WAITER
123
        add     esp, sizeof.MUTEX_WAITER
124
        popfd
124
        popfd
125
        ret
125
        ret
126
.ok:
126
.ok:
127
        inc     eax
127
        inc     eax
128
        mov     [ecx+RWSEM.count], eax
128
        mov     [ecx + RWSEM.count], eax
Line 129... Line 129...
129
 
129
 
130
        popfd
130
        popfd
Line 131... Line 131...
131
        ret
131
        ret
Line 137... Line 137...
137
        pushfd
137
        pushfd
138
        cli
138
        cli
139
        sub     esp, sizeof.MUTEX_WAITER
139
        sub     esp, sizeof.MUTEX_WAITER
Line 140... Line 140...
140
 
140
 
141
        mov     edx, [current_slot]
141
        mov     edx, [current_slot]
142
        mov     [esp+MUTEX_WAITER.task], edx
142
        mov     [esp + MUTEX_WAITER.task], edx
143
        mov     [esp+MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE
143
        mov     [esp + MUTEX_WAITER.type], RWSEM_WAITING_FOR_WRITE
Line 144... Line 144...
144
        mov     [edx + APPDATA.state], TSTATE_RUN_SUSPENDED
144
        mov     [edx + APPDATA.state], TSTATE_RUN_SUSPENDED
Line 145... Line 145...
145
 
145
 
146
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
146
        list_add_tail esp, ecx      ;esp= new waiter, ecx= list head
Line 147... Line 147...
147
 
147
 
148
        xor     eax, eax
148
        xor     eax, eax
149
        not     eax
149
        not     eax
Line 150... Line 150...
150
 
150
 
151
.forever:
151
.forever:
152
        test    eax, [ecx+RWSEM.count]
152
        test    eax, [ecx + RWSEM.count]
153
        jz      @F
153
        jz      @F
154
 
154
 
155
        mov     [edx + APPDATA.state], TSTATE_RUN_SUSPENDED
155
        mov     [edx + APPDATA.state], TSTATE_RUN_SUSPENDED
Line 156... Line 156...
156
        call    change_task
156
        call    change_task
157
        jmp     .forever
157
        jmp     .forever
158
@@:
158
@@:
Line 168... Line 168...
168
align 4
168
align 4
169
up_read:
169
up_read:
170
        pushfd
170
        pushfd
171
        cli
171
        cli
Line 172... Line 172...
172
 
172
 
173
        dec     [ecx+RWSEM.count]
173
        dec     [ecx + RWSEM.count]
Line 174... Line 174...
174
        jnz     @F
174
        jnz     @F
175
 
175
 
176
        mov     eax, [ecx+RWSEM.wait_list.next]
176
        mov     eax, [ecx + RWSEM.wait_list.next]
Line 177... Line 177...
177
        cmp     eax, ecx
177
        cmp     eax, ecx
178
        je      @F
178
        je      @F
179
 
179
 
180
        mov     eax, [eax+MUTEX_WAITER.task]
180
        mov     eax, [eax + MUTEX_WAITER.task]
181
        mov     [eax + APPDATA.state], TSTATE_RUNNING
181
        mov     [eax + APPDATA.state], TSTATE_RUNNING
Line 189... Line 189...
189
up_write:
189
up_write:
Line 190... Line 190...
190
 
190
 
191
        pushfd
191
        pushfd
Line 192... Line 192...
192
        cli
192
        cli
193
 
193
 
Line 194... Line 194...
194
        mov     eax, [ecx+RWSEM.wait_list.next]
194
        mov     eax, [ecx + RWSEM.wait_list.next]
195
        mov     [ecx+RWSEM.count], 0
195
        mov     [ecx + RWSEM.count], 0
Line 196... Line 196...
196
 
196
 
197
        cmp     ecx, eax
197
        cmp     ecx, eax
198
        je      .done
198
        je      .done
Line 199... Line 199...
199
 
199
 
200
        mov     edx, [eax+MUTEX_WAITER.type]
200
        mov     edx, [eax + MUTEX_WAITER.type]
201
        test    edx, edx
201
        test    edx, edx
202
        jnz     .wake
202
        jnz     .wake
203
 
203
 
Line 215... Line 215...
215
        xor     esi, esi
215
        xor     esi, esi
216
        mov     edi, ecx
216
        mov     edi, ecx
Line 217... Line 217...
217
 
217
 
Line 218... Line 218...
218
.wake_list:
218
.wake_list:
219
 
219
 
220
        mov     ebx, [eax+MUTEX_WAITER.list.next]
220
        mov     ebx, [eax + MUTEX_WAITER.list.next]
221
        list_del eax
221
        list_del eax
222
        mov     edx, [eax+MUTEX_WAITER.task]
222
        mov     edx, [eax + MUTEX_WAITER.task]
223
        mov     [edx + APPDATA.state], TSTATE_RUNNING
223
        mov     [edx + APPDATA.state], TSTATE_RUNNING
224
        inc     esi
224
        inc     esi
Line 225... Line 225...
225
        cmp     edi, ebx
225
        cmp     edi, ebx
226
        je      .wake_done
226
        je      .wake_done
227
 
227
 
Line 228... Line 228...
228
        mov     ecx, [ebx+MUTEX_WAITER.type]
228
        mov     ecx, [ebx + MUTEX_WAITER.type]
229
        test    ecx, ecx
229
        test    ecx, ecx
Line 230... Line 230...
230
        jz      .wake_done
230
        jz      .wake_done
231
 
231
 
Line 232... Line 232...
232
        mov     eax, ebx
232
        mov     eax, ebx
233
        jmp     .wake_list
233
        jmp     .wake_list
234
 
234
 
235
.wake_done:
235
.wake_done:
Line 268... Line 268...
268
        sti
268
        sti
269
        call    change_task
269
        call    change_task
270
        jmp     start_wait
270
        jmp     start_wait
271
ok=$
271
ok=$
272
        push    eax
272
        push    eax
273
        mov     eax, dword [TASK_BASE+second_base_address]
273
        mov     eax, dword [current_slot]
274
        mov     eax, [eax+TASKDATA.pid]
274
        mov     eax, [eax + APPDATA.tid]
275
        mov     [name], eax
275
        mov     [name], eax
276
        pop     eax
276
        pop     eax
277
        sti
277
        sti
278
}
278
}
279
macro ReleaseSimpleMutex name
279
macro ReleaseSimpleMutex name
Line 302... Line 302...
302
}
302
}
303
macro WaitSimpleCriticalSection name
303
macro WaitSimpleCriticalSection name
304
{
304
{
305
  local start_wait,first_wait,inc_counter,end_wait
305
  local start_wait,first_wait,inc_counter,end_wait
306
        push    eax
306
        push    eax
307
        mov     eax, [TASK_BASE+second_base_address]
307
        mov     eax, [current_slot]
308
        mov     eax, [eax+TASKDATA.pid]
308
        mov     eax, [eax + APPDATA.tid]
309
start_wait=$
309
start_wait=$
310
        cli
310
        cli
311
        cmp     [name], dword 0
311
        cmp     [name], dword 0
312
        jz      first_wait
312
        jz      first_wait
313
        cmp     [name], eax
313
        cmp     [name], eax
Line 315... Line 315...
315
        sti
315
        sti
316
        call    change_task
316
        call    change_task
317
        jmp     start_wait
317
        jmp     start_wait
318
first_wait=$
318
first_wait=$
319
        mov     [name], eax
319
        mov     [name], eax
320
        mov     [name+4], dword 1
320
        mov     [name + 4], dword 1
321
        jmp     end_wait
321
        jmp     end_wait
322
inc_counter=$
322
inc_counter=$
323
        inc     dword [name+4]
323
        inc     dword [name + 4]
324
end_wait=$
324
end_wait=$
325
        sti
325
        sti
326
        pop     eax
326
        pop     eax
327
}
327
}
328
macro ReleaseSimpleCriticalSection name
328
macro ReleaseSimpleCriticalSection name
329
{
329
{
330
  local release_end
330
  local release_end
331
        dec     dword [name+4]
331
        dec     dword [name + 4]
332
        jnz     release_end
332
        jnz     release_end
333
        mov     [name], dword 0
333
        mov     [name], dword 0
334
release_end=$
334
release_end=$
335
}
335
}
336
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
336
macro TryWaitSimpleCriticalSection name ;result in eax and in flags
337
{
337
{
338
  local ok,try_end
338
  local ok,try_end
339
        mov     eax, [CURRENT_TASK+second_base_address]
339
        mov     eax, [current_slot]
340
        mov     eax, [eax+TASKDATA.pid]
340
        mov     eax, [eax + APPDATA.tid]
341
        cmp     [name], eax
341
        cmp     [name], eax
342
        jz      ok
342
        jz      ok
343
        cmp     [name], 0
343
        cmp     [name], 0
344
        jz      ok
344
        jz      ok
345
        xor     eax, eax
345
        xor     eax, eax