1
/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
2
This file is part of the GNU C Library.
4
The GNU C Library is free software; you can redistribute it and/or
5
modify it under the terms of the GNU Lesser General Public
6
License as published by the Free Software Foundation; either
7
version 2.1 of the License, or (at your option) any later version.
9
The GNU C Library is distributed in the hope that it will be useful,
10
but WITHOUT ANY WARRANTY; without even the implied warranty of
11
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12
Lesser General Public License for more details.
14
You should have received a copy of the GNU Lesser General Public
15
License along with the GNU C Library; if not, write to the Free
16
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19
#include <unwindbuf.h>
21
#include <kernel-features.h>
22
#include <lowlevellock.h>
23
#include "lowlevel-atomic.h"
26
.comm __fork_generation, 4, 4
30
.type __pthread_once,@function
42
cfi_adjust_cfa_offset (4)
43
cfi_rel_offset (r12, 0)
45
cfi_adjust_cfa_offset (4)
46
cfi_rel_offset (r9, 0)
48
cfi_adjust_cfa_offset (4)
49
cfi_rel_offset (r8, 0)
51
cfi_adjust_cfa_offset (4)
52
cfi_rel_offset (pr, 0)
56
/* Not yet initialized or initialization in progress.
57
Get the fork generation counter now. */
81
CMPXCHG (r5, @r4, r3, r2)
84
/* Check whether another thread already runs the initializer. */
87
bt 3f /* No -> do it. */
89
/* Check whether the initializer execution was interrupted
92
mov #-4, r1 /* -4 = 0xfffffffc */
94
bf 3f /* Different for generation -> run initializer. */
96
/* Somebody else got here first. Wait. */
97
#ifdef __ASSUME_PRIVATE_FUTEX
98
mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5
121
.long _GLOBAL_OFFSET_TABLE_
124
.long __fork_generation@GOTOFF
127
.long __fork_generation
131
/* Call the initializer function after setting up the
132
cancellation handler. Note that it is not possible here
133
to use the unwind-based cleanup handling. This would require
134
that the user-provided function and all the code it calls
135
is compiled with exceptions. Unfortunately this cannot be
137
add #-UNWINDBUFSIZE, r15
138
cfi_adjust_cfa_offset (UNWINDBUFSIZE)
140
mov.l .Lsigsetjmp, r1
154
/* Call the user-provided initialization function. */
158
/* Pop the cleanup handler. */
164
add #UNWINDBUFSIZE, r15
165
cfi_adjust_cfa_offset (-UNWINDBUFSIZE)
167
/* Sucessful run of the initializer. Signal that we are done. */
169
/* Wake up all other threads. */
171
#ifdef __ASSUME_PRIVATE_FUTEX
172
mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
183
shlr r6 /* r6 = 0x7fffffff */
192
cfi_adjust_cfa_offset (-4)
195
cfi_adjust_cfa_offset (-4)
198
cfi_adjust_cfa_offset (-4)
201
cfi_adjust_cfa_offset (-4)
207
/* __sigsetjmp returned for the second time. */
208
cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
216
#ifdef __ASSUME_PRIVATE_FUTEX
217
mov #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
228
shlr r6 /* r6 = 0x7fffffff */
242
#ifndef __ASSUME_PRIVATE_FUTEX
244
.word PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
248
.long __sigsetjmp@PLT-(.Lsigsetjmp0-.)
250
.long HIDDEN_JUMPTARGET(__pthread_register_cancel)-.Lcpush0
252
.long HIDDEN_JUMPTARGET(__pthread_unregister_cancel)-.Lcpop0
254
.long HIDDEN_JUMPTARGET(__pthread_unwind_next)-.Lunext0
255
.size __pthread_once,.-__pthread_once
257
.globl __pthread_once_internal
258
__pthread_once_internal = __pthread_once
261
pthread_once = __pthread_once