Subversion Repositories Kolibri OS

Rev

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

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