]>
Commit | Line | Data |
---|---|---|
a334319f | 1 | /* Copyright (C) 2002, 2003 Free Software Foundation, Inc. |
654dff90 UD |
2 | This file is part of the GNU C Library. |
3 | Contributed by Ulrich Drepper <drepper@redhat.com>, 2002. | |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public | |
7 | License as published by the Free Software Foundation; either | |
8 | version 2.1 of the License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; if not, write to the Free | |
17 | Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | |
18 | 02111-1307 USA. */ | |
19 | ||
20 | #ifndef UP | |
21 | # define LOCK lock | |
22 | #else | |
23 | # define LOCK | |
24 | #endif | |
25 | ||
26 | #define SYS_futex 202 | |
27 | #define FUTEX_WAKE 1 | |
28 | ||
29 | .comm __fork_generation, 4, 4 | |
30 | ||
31 | .text | |
32 | ||
33 | ||
34 | .globl __pthread_once | |
35 | .type __pthread_once,@function | |
36 | .align 16 | |
37 | __pthread_once: | |
3b985826 | 38 | .LSTARTCODE: |
654dff90 UD |
39 | testl $2, (%rdi) |
40 | jz 1f | |
41 | xorl %eax, %eax | |
c2e5e085 | 42 | retq |
654dff90 | 43 | |
c2e5e085 UD |
44 | /* Preserve the function pointer. */ |
45 | 1: pushq %rsi | |
3b985826 | 46 | .Lpush_rsi: |
c2e5e085 | 47 | xorq %r10, %r10 |
654dff90 UD |
48 | |
49 | /* Not yet initialized or initialization in progress. | |
50 | Get the fork generation counter now. */ | |
51 | 6: movl (%rdi), %eax | |
52 | ||
c2e5e085 | 53 | 5: movl %eax, %edx |
654dff90 UD |
54 | |
55 | testl $2, %eax | |
c2e5e085 | 56 | jnz 4f |
654dff90 UD |
57 | |
58 | andl $3, %edx | |
59 | orl __fork_generation(%rip), %edx | |
60 | orl $1, %edx | |
61 | ||
62 | LOCK | |
63 | cmpxchgl %edx, (%rdi) | |
64 | jnz 5b | |
65 | ||
66 | /* Check whether another thread already runs the initializer. */ | |
67 | testl $1, %eax | |
68 | jz 3f /* No -> do it. */ | |
69 | ||
70 | /* Check whether the initializer execution was interrupted | |
71 | by a fork. */ | |
72 | xorl %edx, %eax | |
73 | testl $0xfffffffc, %eax | |
74 | jnz 3f /* Different for generation -> run initializer. */ | |
75 | ||
76 | /* Somebody else got here first. Wait. */ | |
a334319f UD |
77 | movq %r10, %rsi /* movq $FUTEX_WAIT, %rsi */ |
78 | movq $SYS_futex, %rax | |
654dff90 UD |
79 | syscall |
80 | jmp 6b | |
81 | ||
82 | /* Preserve the pointer to the control variable. */ | |
83 | 3: pushq %rdi | |
3b985826 | 84 | .Lpush_rdi: |
654dff90 | 85 | |
3b985826 | 86 | .LcleanupSTART: |
a334319f | 87 | callq *8(%rsp) |
3b985826 | 88 | .LcleanupEND: |
654dff90 UD |
89 | |
90 | /* Get the control variable address back. */ | |
91 | popq %rdi | |
3b985826 | 92 | .Lpop_rdi: |
654dff90 UD |
93 | |
94 | /* Sucessful run of the initializer. Signal that we are done. */ | |
95 | LOCK | |
96 | incl (%rdi) | |
97 | ||
98 | /* Wake up all other threads. */ | |
99 | movl $0x7fffffff, %edx | |
100 | movl $FUTEX_WAKE, %esi | |
a334319f | 101 | movq $SYS_futex, %rax |
654dff90 UD |
102 | syscall |
103 | ||
8b4a0b2f | 104 | 4: addq $8, %rsp |
a334319f UD |
105 | .Ladd: |
106 | xorq %rax, %rax | |
c2e5e085 | 107 | retq |
654dff90 UD |
108 | |
109 | .size __pthread_once,.-__pthread_once | |
110 | ||
7588880f UD |
111 | |
112 | .globl __pthread_once_internal | |
113 | __pthread_once_internal = __pthread_once | |
114 | ||
654dff90 UD |
115 | .globl pthread_once |
116 | pthread_once = __pthread_once | |
117 | ||
118 | ||
119 | .type clear_once_control,@function | |
120 | .align 16 | |
121 | clear_once_control: | |
3b985826 UD |
122 | movq (%rsp), %rdi |
123 | movq %rax, %r8 | |
654dff90 UD |
124 | movl $0, (%rdi) |
125 | ||
654dff90 | 126 | movl $0x7fffffff, %edx |
a334319f UD |
127 | movq $FUTEX_WAKE, %rsi |
128 | movq $SYS_futex, %rax | |
654dff90 UD |
129 | syscall |
130 | ||
3b985826 UD |
131 | movq %r8, %rdi |
132 | .LcallUR: | |
133 | call _Unwind_Resume@PLT | |
134 | hlt | |
135 | .LENDCODE: | |
654dff90 | 136 | .size clear_once_control,.-clear_once_control |
3b985826 UD |
137 | |
138 | ||
139 | .section .gcc_except_table,"a",@progbits | |
140 | .LexceptSTART: | |
141 | .byte 0xff # @LPStart format (omit) | |
142 | .byte 0xff # @TType format (omit) | |
143 | .byte 0x01 # call-site format | |
144 | # DW_EH_PE_uleb128 | |
145 | .uleb128 .Lcstend-.Lcstbegin | |
146 | .Lcstbegin: | |
147 | .uleb128 .LcleanupSTART-.LSTARTCODE | |
148 | .uleb128 .LcleanupEND-.LcleanupSTART | |
149 | .uleb128 clear_once_control-.LSTARTCODE | |
150 | .uleb128 0 | |
151 | .uleb128 .LcallUR-.LSTARTCODE | |
152 | .uleb128 .LENDCODE-.LcallUR | |
153 | .uleb128 0 | |
154 | .uleb128 0 | |
155 | .Lcstend: | |
156 | ||
157 | ||
158 | .section .eh_frame,"a",@progbits | |
159 | .LSTARTFRAME: | |
160 | .long .LENDCIE-.LSTARTCIE # Length of the CIE. | |
161 | .LSTARTCIE: | |
162 | .long 0 # CIE ID. | |
163 | .byte 1 # Version number. | |
164 | #ifdef SHARED | |
165 | .string "zPLR" # NUL-terminated augmentation | |
166 | # string. | |
167 | #else | |
168 | .string "zPL" # NUL-terminated augmentation | |
169 | # string. | |
170 | #endif | |
171 | .uleb128 1 # Code alignment factor. | |
172 | .sleb128 -8 # Data alignment factor. | |
173 | .byte 16 # Return address register | |
174 | # column. | |
175 | #ifdef SHARED | |
176 | .uleb128 7 # Augmentation value length. | |
177 | .byte 0x9b # Personality: DW_EH_PE_pcrel | |
178 | # + DW_EH_PE_sdata4 | |
179 | # + DW_EH_PE_indirect | |
180 | .long DW.ref.__gcc_personality_v0-. | |
181 | .byte 0x1b # LSDA Encoding: DW_EH_PE_pcrel | |
182 | # + DW_EH_PE_sdata4. | |
183 | .byte 0x1b # FDE Encoding: DW_EH_PE_pcrel | |
184 | # + DW_EH_PE_sdata4. | |
185 | #else | |
186 | .uleb128 10 # Augmentation value length. | |
187 | .byte 0x0 # Personality: absolute | |
188 | .quad __gcc_personality_v0 | |
189 | .byte 0x0 # LSDA Encoding: absolute | |
190 | #endif | |
191 | .byte 0x0c # DW_CFA_def_cfa | |
192 | .uleb128 7 | |
193 | .uleb128 8 | |
194 | .byte 0x90 # DW_CFA_offset, column 0x10 | |
195 | .uleb128 1 | |
196 | .align 8 | |
197 | .LENDCIE: | |
198 | ||
199 | .long .LENDFDE-.LSTARTFDE # Length of the FDE. | |
200 | .LSTARTFDE: | |
201 | .long .LSTARTFDE-.LSTARTFRAME # CIE pointer. | |
202 | #ifdef SHARED | |
203 | .long .LSTARTCODE-. # PC-relative start address | |
204 | # of the code. | |
205 | .long .LENDCODE-.LSTARTCODE # Length of the code. | |
206 | .uleb128 4 # Augmentation size | |
207 | .long .LexceptSTART-. | |
208 | #else | |
209 | .quad .LSTARTCODE # Start address of the code. | |
210 | .quad .LENDCODE-.LSTARTCODE # Length of the code. | |
211 | .uleb128 8 # Augmentation size | |
212 | .quad .LexceptSTART | |
213 | #endif | |
214 | .byte 4 # DW_CFA_advance_loc4 | |
215 | .long .Lpush_rsi-.LSTARTCODE | |
216 | .byte 14 # DW_CFA_def_cfa_offset | |
217 | .uleb128 16 | |
218 | .byte 4 # DW_CFA_advance_loc4 | |
219 | .long .Lpush_rdi-.Lpush_rsi | |
220 | .byte 14 # DW_CFA_def_cfa_offset | |
221 | .uleb128 24 | |
222 | .byte 4 # DW_CFA_advance_loc4 | |
a334319f | 223 | .long .Lpop_rdi-.Lpush_rdi |
3b985826 UD |
224 | .byte 14 # DW_CFA_def_cfa_offset |
225 | .uleb128 16 | |
226 | .byte 4 # DW_CFA_advance_loc4 | |
a334319f | 227 | .long .Ladd-.Lpop_rdi |
3b985826 UD |
228 | .byte 14 # DW_CFA_def_cfa_offset |
229 | .uleb128 8 | |
230 | .byte 4 # DW_CFA_advance_loc4 | |
a334319f | 231 | .long clear_once_control-.Ladd |
3b985826 | 232 | .byte 14 # DW_CFA_def_cfa_offset |
a334319f | 233 | .uleb128 24 |
3b985826 UD |
234 | #if 0 |
235 | .byte 4 # DW_CFA_advance_loc4 | |
a334319f | 236 | .long .Lpop_rdi2-clear_once_control |
3b985826 UD |
237 | .byte 14 # DW_CFA_def_cfa_offset |
238 | .uleb128 16 | |
239 | #endif | |
240 | .align 8 | |
241 | .LENDFDE: | |
242 | ||
243 | ||
244 | #ifdef SHARED | |
245 | .hidden DW.ref.__gcc_personality_v0 | |
246 | .weak DW.ref.__gcc_personality_v0 | |
247 | .section .gnu.linkonce.d.DW.ref.__gcc_personality_v0,"aw",@progbits | |
248 | .align 8 | |
249 | .type DW.ref.__gcc_personality_v0, @object | |
250 | .size DW.ref.__gcc_personality_v0, 8 | |
251 | DW.ref.__gcc_personality_v0: | |
252 | .quad __gcc_personality_v0 | |
253 | #endif |