Subversion Repositories Kolibri OS

Rev

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

Rev Author Line No. Line
6926 serge 1
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
2
;;                                                              ;;
9715 Doczom 3
;; Copyright (C) KolibriOS team 2004-2022. All rights reserved. ;;
6926 serge 4
;;  Distributed under terms of the GNU General Public License.  ;;
5
;;                                                              ;;
6
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
7
 
8130 dunkaist 8
$Revision: 9871 $
6926 serge 9
 
10
align 4
11
;struct futex*  __fastcall create_futex(int *ptr)
12
create_futex:
13
        push    ecx
14
        mov     ecx, sizeof.FUTEX
15
        call    create_object
16
        pop     ecx
17
        test    eax, eax
18
        jz      .fail
19
 
9715 Doczom 20
        mov     [eax + FUTEX.magic], 'FUTX'
21
        mov     [eax + FUTEX.destroy], 0
22
        mov     [eax + FUTEX.pointer], ecx
23
        lea     ecx, [eax + FUTEX.wait_list]
6926 serge 24
        list_init ecx
9715 Doczom 25
        mov     [eax + FUTEX.flags], 0
6926 serge 26
.fail:
27
        ret
28
 
29
align 4
30
;int __fastcall destroy_futex(struct futex *futex)
31
destroy_futex:
32
        push    esi
33
        mov     esi, [current_process]
9715 Doczom 34
        mov     edx, [ecx + FUTEX.handle]
6926 serge 35
 
36
        pushfd
37
        cli
38
 
9715 Doczom 39
        lea     eax, [ecx + FUTEX.wait_list]
40
        cmp     eax, [eax + LHEAD.next]
6926 serge 41
        jne     .fail
42
 
9715 Doczom 43
        mov     eax, [esi + PROC.ht_next]
44
        mov     [esi + PROC.htab + edx*4], eax
45
        mov     [esi + PROC.ht_next], edx
46
        inc     [esi + PROC.ht_free]
6926 serge 47
 
48
        popfd
49
        pop     esi
50
 
51
        mov     eax, ecx
52
        call    free
53
        xor     eax, eax
54
        ret
55
 
56
.fail:
57
        popfd
58
        pop     esi
59
        mov     eax, -1
60
        ret
61
 
62
align 4
63
sys_futex:
64
        cmp     ecx, STDERR_FILENO
65
        jbe     .fail
66
        cmp     ecx, (PROC.pdt_0 - PROC.htab)/4
67
        jae     .fail
68
 
69
        mov     edi, [current_process]
9715 Doczom 70
        mov     ebp, [edi + PROC.htab + ecx*4]
6926 serge 71
 
9715 Doczom 72
        cmp     [ebp + FUTEX.magic], 'FUTX'
6926 serge 73
        jne     .fail
9715 Doczom 74
        cmp     [ebp + FUTEX.handle], ecx
6926 serge 75
        jne     .fail
76
 
9715 Doczom 77
        jmp     dword [sys_futex_call + ebx*4-4]
6926 serge 78
 
79
.fail:
80
.requeue:
81
.cmp_requeue:
82
.wait_bitset:
83
.wake_bitset:
9831 dunkaist 84
        mov     [esp + SYSCALL_STACK.eax], -1
6926 serge 85
        ret
86
 
87
align 4
88
.init:
89
        call    create_futex
90
        test    eax, eax
91
        jz      @F
9715 Doczom 92
        mov     eax, [eax + FUTEX.handle]
6926 serge 93
@@:
9831 dunkaist 94
        mov     [esp + SYSCALL_STACK.eax], eax
6926 serge 95
        ret
96
 
97
align 4
98
;ecx futex handle
99
;edi current process
100
;ebp futex object
101
.destroy:
102
        mov     ecx, ebp
103
        call    destroy_futex
9831 dunkaist 104
        mov     [esp + SYSCALL_STACK.eax], eax
6926 serge 105
        ret
106
 
107
align 4
108
;ecx futex handle
109
;edx control value
110
;esi timeout
111
;edi current process
112
;ebp futex object
113
.wait:
114
        test    esi, esi
115
        jnz     .wait_timeout
9715 Doczom 116
        mov     ecx, [ebp + FUTEX.pointer]
6926 serge 117
        mov     eax, edx
118
        lock cmpxchg [ecx], edx
119
        je      .wait_slow
120
 
9831 dunkaist 121
        mov     [esp + SYSCALL_STACK.eax], -2
6926 serge 122
        ret
123
 
124
.wait_slow:
125
        pushfd
126
        cli
127
 
128
        sub     esp, sizeof.MUTEX_WAITER
9709 Doczom 129
        mov     ebx, [current_slot]
9715 Doczom 130
        mov     [esp + MUTEX_WAITER.task], ebx
131
        lea     esi, [ebp + FUTEX.wait_list]
6926 serge 132
 
133
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
134
        mov     eax, edx
135
.again:
9709 Doczom 136
        mov     [ebx + APPDATA.state], TSTATE_RUN_SUSPENDED
6926 serge 137
        call    change_task
138
 
139
        lock cmpxchg [ecx], edx
140
        je      .again
141
 
142
        list_del esp
143
        add     esp, sizeof.MUTEX_WAITER
144
 
145
        popfd
9831 dunkaist 146
        mov     [esp + SYSCALL_STACK.eax], 0
6926 serge 147
        ret
148
 
149
align 4
150
;ecx futex handle
151
;edx control value
152
;esi timeout
153
;edi current process
154
;ebp futex object
155
 
156
.wait_timeout:
9715 Doczom 157
        mov     ecx, [ebp + FUTEX.pointer]
6926 serge 158
        mov     eax, edx
159
        lock cmpxchg [ecx], edx         ;wait until old_value == new_value
160
        je      .wait_slow_timeout
161
 
9831 dunkaist 162
        mov     [esp + SYSCALL_STACK.eax], -2
6926 serge 163
        ret
164
 
165
align 4
166
.wait_test:
167
        xor     eax, eax
168
        ret
169
 
170
.wait_slow_timeout:
171
        pushfd
172
        cli
173
 
174
        sub     esp, sizeof.MUTEX_WAITER
175
 
176
        mov     ebx, [current_slot]
9715 Doczom 177
        mov     [ebx + APPDATA.wait_test], sys_futex.wait_test
178
        mov     [ebx + APPDATA.wait_timeout], esi
179
        mov     [ebx + APPDATA.wait_param], ebp
6926 serge 180
        mov     eax, [timer_ticks]
9715 Doczom 181
        mov     [ebx + APPDATA.wait_begin], eax
9709 Doczom 182
        mov     [ebx + APPDATA.state], TSTATE_WAITING
6926 serge 183
 
9715 Doczom 184
        mov     [esp + MUTEX_WAITER.task], ebx
185
        lea     esi, [ebp + FUTEX.wait_list]
6926 serge 186
 
187
        list_add_tail esp, esi      ;esp= new waiter, esi= list head
188
.again_timeout:
9871 Doczom 189
        mov     [ebx + APPDATA.state], TSTATE_WAITING
6926 serge 190
        call    change_task
9715 Doczom 191
        mov     eax, [ebx + APPDATA.wait_param]
6926 serge 192
        test    eax, eax
193
        jz      .timeout
194
        mov     eax, edx
195
        lock cmpxchg [ecx], edx
196
        jz      .again_timeout
197
@@:
9869 Doczom 198
        cli
6926 serge 199
        list_del esp
9869 Doczom 200
        sti
6926 serge 201
        add     esp, sizeof.MUTEX_WAITER
202
        popfd
9831 dunkaist 203
        mov     [esp + SYSCALL_STACK.eax], 0
6926 serge 204
        ret
205
 
206
.timeout:
207
        list_del esp
208
        add     esp, sizeof.MUTEX_WAITER
209
        popfd
9831 dunkaist 210
        mov     [esp + SYSCALL_STACK.eax], -1
6926 serge 211
        ret
212
 
213
 
214
align 4
215
;ecx futex handle
216
;edx number of threads
217
;edi current process
218
;ebp futex object
219
.wake:
220
 
221
        xor     ecx, ecx
222
 
223
        pushfd
224
        cli
225
 
9715 Doczom 226
        lea     ebx, [ebp + FUTEX.wait_list]
227
        mov     esi, [ebx + LHEAD.next]
6926 serge 228
.again_wake:
229
        cmp     esi, ebx
230
        je      .done
231
 
9715 Doczom 232
        mov     eax, [esi + MUTEX_WAITER.task]
9709 Doczom 233
        mov     [eax + APPDATA.state], TSTATE_RUNNING
6926 serge 234
 
9715 Doczom 235
        mov     esi, [esi + MUTEX_WAITER.list.next]
6926 serge 236
        inc     ecx
237
        cmp     ecx, edx
238
        jb      .again_wake
239
.done:
240
        popfd
9831 dunkaist 241
        mov     [esp + SYSCALL_STACK.eax], ecx
6926 serge 242
        ret
243