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

« back to all changes in this revision

Viewing changes to nptl/sysdeps/unix/sysv/linux/i386/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) 2002, 2003, 2007 Free Software Foundation, Inc.
 
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
#include <unwindbuf.h>
 
21
#include <sysdep.h>
 
22
#include <kernel-features.h>
 
23
#include <lowlevellock.h>
 
24
 
 
25
 
 
26
        .comm   __fork_generation, 4, 4
 
27
 
 
28
        .text
 
29
 
 
30
 
 
31
        .globl  __pthread_once
 
32
        .type   __pthread_once,@function
 
33
        .align  16
 
34
        cfi_startproc
 
35
__pthread_once:
 
36
        movl    4(%esp), %ecx
 
37
        testl   $2, (%ecx)
 
38
        jz      1f
 
39
        xorl    %eax, %eax
 
40
        ret
 
41
 
 
42
1:      pushl   %ebx
 
43
        cfi_adjust_cfa_offset (4)
 
44
        cfi_rel_offset (3, 0)
 
45
        pushl   %esi
 
46
        cfi_adjust_cfa_offset (4)
 
47
        cfi_rel_offset (6, 0)
 
48
        movl    %ecx, %ebx
 
49
        xorl    %esi, %esi
 
50
 
 
51
        /* Not yet initialized or initialization in progress.
 
52
           Get the fork generation counter now.  */
 
53
6:      movl    (%ebx), %eax
 
54
#ifdef PIC
 
55
        call    __i686.get_pc_thunk.cx
 
56
        addl    $_GLOBAL_OFFSET_TABLE_, %ecx
 
57
#endif
 
58
 
 
59
5:      movl    %eax, %edx
 
60
 
 
61
        testl   $2, %eax
 
62
        jnz     4f
 
63
 
 
64
        andl    $3, %edx
 
65
#ifdef PIC
 
66
        orl     __fork_generation@GOTOFF(%ecx), %edx
 
67
#else
 
68
        orl     __fork_generation, %edx
 
69
#endif
 
70
        orl     $1, %edx
 
71
 
 
72
        LOCK
 
73
        cmpxchgl %edx, (%ebx)
 
74
        jnz     5b
 
75
 
 
76
        /* Check whether another thread already runs the initializer.  */
 
77
        testl   $1, %eax
 
78
        jz      3f      /* No -> do it.  */
 
79
 
 
80
        /* Check whether the initializer execution was interrupted
 
81
           by a fork.  */
 
82
        xorl    %edx, %eax
 
83
        testl   $0xfffffffc, %eax
 
84
        jnz     3f      /* Different for generation -> run initializer.  */
 
85
 
 
86
        /* Somebody else got here first.  Wait.  */
 
87
#ifdef __ASSUME_PRIVATE_FUTEX
 
88
        movl    $FUTEX_WAIT|FUTEX_PRIVATE_FLAG, %ecx
 
89
#else
 
90
# if FUTEX_WAIT == 0
 
91
        movl    %gs:PRIVATE_FUTEX, %ecx
 
92
# else
 
93
        movl    $FUTEX_WAIT, %ecx
 
94
        orl     %gs:PRIVATE_FUTEX, %ecx
 
95
# endif
 
96
#endif
 
97
        movl    $SYS_futex, %eax
 
98
        ENTER_KERNEL
 
99
        jmp     6b
 
100
 
 
101
3:      /* Call the initializer function after setting up the
 
102
           cancellation handler.  Note that it is not possible here
 
103
           to use the unwind-based cleanup handling.  This would require
 
104
           that the user-provided function and all the code it calls
 
105
           is compiled with exceptions.  Unfortunately this cannot be
 
106
           guaranteed.  */
 
107
        subl    $UNWINDBUFSIZE+8, %esp
 
108
        cfi_adjust_cfa_offset (UNWINDBUFSIZE+8)
 
109
        movl    %ecx, %ebx              /* PIC register value.  */
 
110
 
 
111
        leal    8+UWJMPBUF(%esp), %eax
 
112
        movl    $0, 4(%esp)
 
113
        movl    %eax, (%esp)
 
114
        call    __sigsetjmp@PLT
 
115
        testl   %eax, %eax
 
116
        jne     7f
 
117
 
 
118
        leal    8(%esp), %eax
 
119
        call    HIDDEN_JUMPTARGET(__pthread_register_cancel)
 
120
 
 
121
        /* Call the user-provided initialization function.  */
 
122
        call    *24+UNWINDBUFSIZE(%esp)
 
123
 
 
124
        /* Pop the cleanup handler.  */
 
125
        leal    8(%esp), %eax
 
126
        call    HIDDEN_JUMPTARGET(__pthread_unregister_cancel)
 
127
        addl    $UNWINDBUFSIZE+8, %esp
 
128
        cfi_adjust_cfa_offset (-UNWINDBUFSIZE-8)
 
129
 
 
130
        /* Sucessful run of the initializer.  Signal that we are done.  */
 
131
        movl    12(%esp), %ebx
 
132
        LOCK
 
133
        addl    $1, (%ebx)
 
134
 
 
135
        /* Wake up all other threads.  */
 
136
        movl    $0x7fffffff, %edx
 
137
#ifdef __ASSUME_PRIVATE_FUTEX
 
138
        movl    $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
 
139
#else
 
140
        movl    $FUTEX_WAKE, %ecx
 
141
        orl     %gs:PRIVATE_FUTEX, %ecx
 
142
#endif
 
143
        movl    $SYS_futex, %eax
 
144
        ENTER_KERNEL
 
145
 
 
146
4:      popl    %esi
 
147
        cfi_adjust_cfa_offset (-4)
 
148
        cfi_restore (6)
 
149
        popl    %ebx
 
150
        cfi_adjust_cfa_offset (-4)
 
151
        cfi_restore (3)
 
152
        xorl    %eax, %eax
 
153
        ret
 
154
 
 
155
7:      /* __sigsetjmp returned for the second time.  */
 
156
        movl    20+UNWINDBUFSIZE(%esp), %ebx
 
157
        cfi_adjust_cfa_offset (UNWINDBUFSIZE+16)
 
158
        cfi_offset (3, -8)
 
159
        cfi_offset (6, -12)
 
160
        movl    $0, (%ebx)
 
161
 
 
162
        movl    $0x7fffffff, %edx
 
163
#ifdef __ASSUME_PRIVATE_FUTEX
 
164
        movl    $FUTEX_WAKE|FUTEX_PRIVATE_FLAG, %ecx
 
165
#else
 
166
        movl    $FUTEX_WAKE, %ecx
 
167
        orl     %gs:PRIVATE_FUTEX, %ecx
 
168
#endif
 
169
        movl    $SYS_futex, %eax
 
170
        ENTER_KERNEL
 
171
 
 
172
        leal    8(%esp), %eax
 
173
        call    HIDDEN_JUMPTARGET (__pthread_unwind_next)
 
174
        /* NOTREACHED */
 
175
        hlt
 
176
        cfi_endproc
 
177
        .size   __pthread_once,.-__pthread_once
 
178
 
 
179
        .globl  __pthread_once_internal
 
180
__pthread_once_internal = __pthread_once
 
181
 
 
182
        .globl  pthread_once
 
183
pthread_once = __pthread_once
 
184
 
 
185
 
 
186
#ifdef PIC
 
187
        .section .gnu.linkonce.t.__i686.get_pc_thunk.cx,"ax",@progbits
 
188
        .globl  __i686.get_pc_thunk.cx
 
189
        .hidden __i686.get_pc_thunk.cx
 
190
        .type   __i686.get_pc_thunk.cx,@function
 
191
__i686.get_pc_thunk.cx:
 
192
        movl (%esp), %ecx;
 
193
        ret
 
194
        .size   __i686.get_pc_thunk.cx,.-__i686.get_pc_thunk.cx
 
195
#endif