~ubuntu-branches/ubuntu/natty/eglibc/natty-security

« back to all changes in this revision

Viewing changes to nptl/sysdeps/unix/sysv/linux/sh/pthread_once.S

  • Committer: Bazaar Package Importer
  • Author(s): Aurelien Jarno
  • Date: 2009-05-05 09:54:14 UTC
  • Revision ID: james.westby@ubuntu.com-20090505095414-c45qsg9ixjheohru
ImportĀ upstreamĀ versionĀ 2.9

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003, 2004, 2007 Free Software Foundation, Inc.
 
2
   This file is part of the GNU C Library.
 
3
 
 
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.
 
8
 
 
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.
 
13
 
 
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
 
17
   02111-1307 USA.  */
 
18
 
 
19
#include <unwindbuf.h>
 
20
#include <sysdep.h>
 
21
#include <kernel-features.h>
 
22
#include <lowlevellock.h>
 
23
#include "lowlevel-atomic.h"
 
24
 
 
25
 
 
26
        .comm   __fork_generation, 4, 4
 
27
 
 
28
        .text
 
29
        .globl  __pthread_once
 
30
        .type   __pthread_once,@function
 
31
        .align  5
 
32
        cfi_startproc
 
33
__pthread_once:
 
34
        mov.l   @r4, r0
 
35
        tst     #2, r0
 
36
        bt      1f
 
37
        rts
 
38
         mov    #0, r0
 
39
 
 
40
1:
 
41
        mov.l   r12, @-r15
 
42
        cfi_adjust_cfa_offset (4)
 
43
        cfi_rel_offset (r12, 0)
 
44
        mov.l   r9, @-r15
 
45
        cfi_adjust_cfa_offset (4)
 
46
        cfi_rel_offset (r9, 0)
 
47
        mov.l   r8, @-r15
 
48
        cfi_adjust_cfa_offset (4)
 
49
        cfi_rel_offset (r8, 0)
 
50
        sts.l   pr, @-r15
 
51
        cfi_adjust_cfa_offset (4)
 
52
        cfi_rel_offset (pr, 0)
 
53
        mov     r5, r8
 
54
        mov     r4, r9
 
55
 
 
56
        /* Not yet initialized or initialization in progress.
 
57
           Get the fork generation counter now.  */
 
58
6:
 
59
        mov.l   @r4, r1
 
60
        mova    .Lgot, r0
 
61
        mov.l   .Lgot, r12
 
62
        add     r0, r12
 
63
 
 
64
5:
 
65
        mov     r1, r0
 
66
 
 
67
        tst     #2, r0
 
68
        bf      4f
 
69
 
 
70
        and     #3, r0
 
71
        mov.l   .Lfgen, r2
 
72
#ifdef PIC
 
73
        add     r12, r2
 
74
#endif
 
75
        mov.l   @r2, r3
 
76
        or      r3, r0  
 
77
        or      #1, r0
 
78
        mov     r0, r3
 
79
        mov     r1, r5
 
80
 
 
81
        CMPXCHG (r5, @r4, r3, r2)
 
82
        bf      5b
 
83
 
 
84
        /* Check whether another thread already runs the initializer.  */
 
85
        mov     r2, r0
 
86
        tst     #1, r0
 
87
        bt      3f      /* No -> do it.  */
 
88
 
 
89
        /* Check whether the initializer execution was interrupted
 
90
           by a fork.  */
 
91
        xor     r3, r0
 
92
        mov     #-4, r1 /* -4 = 0xfffffffc */
 
93
        tst     r1, r0
 
94
        bf      3f      /* Different for generation -> run initializer.  */
 
95
 
 
96
        /* Somebody else got here first.  Wait.  */
 
97
#ifdef __ASSUME_PRIVATE_FUTEX
 
98
        mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAIT), r5
 
99
        extu.b  r5, r5
 
100
#else
 
101
        stc     gbr, r1
 
102
        mov.w   .Lpfoff, r2
 
103
        add     r2, r1
 
104
        mov.l   @r1, r5
 
105
# if FUTEX_WAIT != 0
 
106
        mov     #FUTEX_WAIT, r0
 
107
        or      r0, r5
 
108
# endif
 
109
#endif
 
110
        mov     r3, r6
 
111
        mov     #0, r7
 
112
        mov     #SYS_futex, r3
 
113
        extu.b  r3, r3
 
114
        trapa   #0x14
 
115
        SYSCALL_INST_PAD
 
116
        bra     6b
 
117
         nop
 
118
 
 
119
        .align  2
 
120
.Lgot:
 
121
        .long   _GLOBAL_OFFSET_TABLE_
 
122
#ifdef PIC
 
123
.Lfgen: 
 
124
        .long   __fork_generation@GOTOFF
 
125
#else
 
126
.Lfgen: 
 
127
        .long   __fork_generation
 
128
#endif
 
129
 
 
130
3:
 
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
 
136
           guaranteed.  */
 
137
        add     #-UNWINDBUFSIZE, r15
 
138
        cfi_adjust_cfa_offset (UNWINDBUFSIZE)
 
139
 
 
140
        mov.l   .Lsigsetjmp, r1
 
141
        mov     #UWJMPBUF, r4
 
142
        add     r15, r4
 
143
        bsrf    r1
 
144
         mov    #0, r5
 
145
.Lsigsetjmp0:
 
146
        tst     r0, r0
 
147
        bf      7f
 
148
 
 
149
        mov.l   .Lcpush, r1
 
150
        bsrf    r1
 
151
         mov    r15, r4
 
152
.Lcpush0:
 
153
 
 
154
        /* Call the user-provided initialization function.  */
 
155
        jsr     @r8
 
156
         nop
 
157
 
 
158
        /* Pop the cleanup handler.  */
 
159
        mov.l   .Lcpop, r1
 
160
        bsrf    r1
 
161
         mov    r15, r4
 
162
.Lcpop0:
 
163
 
 
164
        add     #UNWINDBUFSIZE, r15
 
165
        cfi_adjust_cfa_offset (-UNWINDBUFSIZE)
 
166
 
 
167
        /* Sucessful run of the initializer.  Signal that we are done.  */
 
168
        INC (@r9, r2)
 
169
        /* Wake up all other threads.  */
 
170
        mov     r9, r4
 
171
#ifdef __ASSUME_PRIVATE_FUTEX
 
172
        mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
 
173
        extu.b  r5, r5
 
174
#else
 
175
        stc     gbr, r1
 
176
        mov.w   .Lpfoff, r2
 
177
        add     r2, r1
 
178
        mov.l   @r1, r5
 
179
        mov     #FUTEX_WAKE, r0
 
180
        or      r0, r5
 
181
#endif
 
182
        mov     #-1, r6
 
183
        shlr    r6              /* r6 = 0x7fffffff */
 
184
        mov     #0, r7
 
185
        mov     #SYS_futex, r3
 
186
        extu.b  r3, r3
 
187
        trapa   #0x14
 
188
        SYSCALL_INST_PAD
 
189
 
 
190
4:
 
191
        lds.l   @r15+, pr
 
192
        cfi_adjust_cfa_offset (-4)
 
193
        cfi_restore (pr)
 
194
        mov.l   @r15+, r8
 
195
        cfi_adjust_cfa_offset (-4)
 
196
        cfi_restore (r8)
 
197
        mov.l   @r15+, r9
 
198
        cfi_adjust_cfa_offset (-4)
 
199
        cfi_restore (r9)
 
200
        mov.l   @r15+, r12
 
201
        cfi_adjust_cfa_offset (-4)
 
202
        cfi_restore (r12)
 
203
        rts
 
204
         mov    #0, r0
 
205
 
 
206
7:
 
207
        /* __sigsetjmp returned for the second time.  */
 
208
        cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
 
209
        cfi_offset (r12, -4)
 
210
        cfi_offset (r9, -8)
 
211
        cfi_offset (r8, -12)
 
212
        cfi_offset (pr, -16)
 
213
        mov     #0, r7
 
214
        mov.l   r7, @r9
 
215
        mov     r9, r4
 
216
#ifdef __ASSUME_PRIVATE_FUTEX
 
217
        mov     #(FUTEX_PRIVATE_FLAG|FUTEX_WAKE), r5
 
218
#else
 
219
        stc     gbr, r1
 
220
        mov.w   .Lpfoff, r2
 
221
        add     r2, r1
 
222
        mov.l   @r1, r5
 
223
        mov     #FUTEX_WAKE, r0
 
224
        or      r0, r5
 
225
#endif
 
226
        extu.b  r5, r5
 
227
        mov     #-1, r6
 
228
        shlr    r6              /* r6 = 0x7fffffff */
 
229
        mov     #SYS_futex, r3
 
230
        extu.b  r3, r3
 
231
        trapa   #0x14
 
232
        SYSCALL_INST_PAD
 
233
 
 
234
        mov.l   .Lunext, r1
 
235
        bsrf    r1
 
236
         mov    r15, r4
 
237
.Lunext0:
 
238
        /* NOTREACHED */
 
239
        sleep
 
240
        cfi_endproc
 
241
 
 
242
#ifndef __ASSUME_PRIVATE_FUTEX
 
243
.Lpfoff:
 
244
        .word   PRIVATE_FUTEX - TLS_PRE_TCB_SIZE
 
245
#endif
 
246
        .align  2
 
247
.Lsigsetjmp:
 
248
        .long   __sigsetjmp@PLT-(.Lsigsetjmp0-.)
 
249
.Lcpush:
 
250
        .long   HIDDEN_JUMPTARGET(__pthread_register_cancel)-.Lcpush0
 
251
.Lcpop:
 
252
        .long   HIDDEN_JUMPTARGET(__pthread_unregister_cancel)-.Lcpop0
 
253
.Lunext:
 
254
        .long   HIDDEN_JUMPTARGET(__pthread_unwind_next)-.Lunext0
 
255
        .size   __pthread_once,.-__pthread_once
 
256
 
 
257
        .globl  __pthread_once_internal
 
258
__pthread_once_internal = __pthread_once
 
259
 
 
260
        .globl  pthread_once
 
261
pthread_once = __pthread_once