Subversion Repositories Kolibri OS

Rev

Rev 6926 | Rev 8876 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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