]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libpthread/linuxthreads/sysdeps/x86_64/pt-machine.h
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libpthread / linuxthreads / sysdeps / x86_64 / pt-machine.h
1 /* Machine-dependent pthreads configuration and inline functions.
2    x86-64 version.
3    Copyright (C) 2001, 2002, 2003, 2004 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5
6    The GNU C Library is free software; you can redistribute it and/or
7    modify it under the terms of the GNU Lesser General Public
8    License as published by the Free Software Foundation; either
9    version 2.1 of the License, or (at your option) any later version.
10
11    The GNU C Library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with the GNU C Library; if not, see
18    <http://www.gnu.org/licenses/>.  */
19
20 #ifndef _PT_MACHINE_H
21 #define _PT_MACHINE_H   1
22
23 # include <features.h>
24
25 #ifndef __ASSEMBLER__
26 # include <stddef.h>    /* For offsetof.  */
27 # include <stdlib.h>    /* For abort().  */
28 # include <asm/prctl.h>
29
30
31 # ifndef PT_EI
32 #  define PT_EI __extern_always_inline
33 # endif
34
35 /* Get some notion of the current stack.  Need not be exactly the top
36    of the stack, just something somewhere in the current frame.  */
37 # define CURRENT_STACK_FRAME  stack_pointer
38 register char * stack_pointer __asm__ ("%rsp") __attribute_used__;
39
40
41 /* Spinlock implementation; required.  */
42 PT_EI long int
43 testandset (int *spinlock)
44 {
45   long int ret;
46
47   __asm__ __volatile__ (
48         "xchgl %k0, %1"
49         : "=r"(ret), "=m"(*spinlock)
50         : "0"(1), "m"(*spinlock)
51         : "memory");
52
53   return ret;
54 }
55
56
57 /* Compare-and-swap for semaphores.  */
58 # define HAS_COMPARE_AND_SWAP
59
60 PT_EI int
61 __compare_and_swap (long int *p, long int oldval, long int newval)
62 {
63   char ret;
64   long int readval;
65
66   __asm__ __volatile__ ("lock; cmpxchgq %3, %1; sete %0"
67                         : "=q" (ret), "=m" (*p), "=a" (readval)
68                         : "r" (newval), "m" (*p), "a" (oldval)
69                         : "memory");
70   return ret;
71 }
72
73 /* Return the thread descriptor for the current thread.
74
75    The contained asm must *not* be marked volatile since otherwise
76    assignments like
77         pthread_descr self = thread_self();
78    do not get optimized away.  */
79 # define THREAD_SELF \
80 ({                                                                            \
81   register pthread_descr __self;                                              \
82   __asm__ ("movq %%fs:%c1,%0" : "=r" (__self)                                 \
83            : "i" (offsetof (struct _pthread_descr_struct,                     \
84                             p_header.data.self)));                            \
85   __self;                                                                     \
86 })
87
88 /* Prototype for the system call.  */
89 extern int arch_prctl (int __code, unsigned long __addr);
90
91 /* Initialize the thread-unique value.  */
92 # define INIT_THREAD_SELF(descr, nr) \
93 {                                                                             \
94   if (arch_prctl (ARCH_SET_FS, (unsigned long)descr) != 0)                    \
95     abort ();                                                                 \
96 }
97
98 /* Read member of the thread descriptor directly.  */
99 # define THREAD_GETMEM(descr, member) \
100 ({                                                                            \
101   __typeof__ (descr->member) __value;                                         \
102   if (sizeof (__value) == 1)                                                  \
103     __asm__ __volatile__ ("movb %%fs:%P2,%b0"                                 \
104                           : "=q" (__value)                                    \
105                           : "0" (0),                                          \
106                             "i" (offsetof (struct _pthread_descr_struct,      \
107                                            member)));                         \
108   else if (sizeof (__value) == 4)                                             \
109     __asm__ __volatile__ ("movl %%fs:%P2,%k0"                                 \
110                           : "=r" (__value)                                    \
111                           : "0" (0),                                          \
112                             "i" (offsetof (struct _pthread_descr_struct,      \
113                                            member)));                         \
114   else                                                                        \
115     {                                                                         \
116       if (sizeof (__value) != 8)                                              \
117         /* There should not be any value with a size other than 1, 4 or 8.  */\
118         abort ();                                                             \
119                                                                               \
120       __asm__ __volatile__ ("movq %%fs:%P1,%0"                                \
121                             : "=r" (__value)                                  \
122                             : "i" (offsetof (struct _pthread_descr_struct,    \
123                                              member)));                       \
124     }                                                                         \
125   __value;                                                                    \
126 })
127
128 /* Same as THREAD_GETMEM, but the member offset can be non-constant.  */
129 # define THREAD_GETMEM_NC(descr, member) \
130 ({                                                                            \
131   __typeof__ (descr->member) __value;                                         \
132   if (sizeof (__value) == 1)                                                  \
133     __asm__ __volatile__ ("movb %%fs:(%2),%b0"                                \
134                           : "=q" (__value)                                    \
135                           : "0" (0),                                          \
136                             "r" (offsetof (struct _pthread_descr_struct,      \
137                                            member)));                         \
138   else if (sizeof (__value) == 4)                                             \
139     __asm__ __volatile__ ("movl %%fs:(%2),%k0"                                \
140                           : "=r" (__value)                                    \
141                           : "0" (0),                                          \
142                             "r" (offsetof (struct _pthread_descr_struct,      \
143                                            member)));                         \
144   else                                                                        \
145     {                                                                         \
146       if (sizeof (__value) != 8)                                              \
147         /* There should not be any value with a size other than 1, 4 or 8.  */\
148         abort ();                                                             \
149                                                                               \
150       __asm__ __volatile__ ("movq %%fs:(%1),%0"                               \
151                             : "=r" (__value)                                  \
152                             : "r" (offsetof (struct _pthread_descr_struct,    \
153                                              member)));                       \
154     }                                                                         \
155   __value;                                                                    \
156 })
157
158 /* Set member of the thread descriptor directly.  */
159 # define THREAD_SETMEM(descr, member, value) \
160 ({                                                                            \
161   __typeof__ (descr->member) __value = (value);                               \
162   if (sizeof (__value) == 1)                                                  \
163     __asm__ __volatile__ ("movb %0,%%fs:%P1" :                                \
164                           : "q" (__value),                                    \
165                             "i" (offsetof (struct _pthread_descr_struct,      \
166                                            member)));                         \
167   else if (sizeof (__value) == 4)                                             \
168     __asm__ __volatile__ ("movl %k0,%%fs:%P1" :                               \
169                           : "r" (__value),                                    \
170                             "i" (offsetof (struct _pthread_descr_struct,      \
171                                            member)));                         \
172   else                                                                        \
173     {                                                                         \
174       if (sizeof (__value) != 8)                                              \
175         /* There should not be any value with a size other than 1, 4 or 8.  */\
176         abort ();                                                             \
177                                                                               \
178       __asm__ __volatile__ ("movq %0,%%fs:%P1" :                              \
179                             : "r" (__value),                                  \
180                               "i" (offsetof (struct _pthread_descr_struct,    \
181                                              member)));                       \
182     }                                                                         \
183 })
184
185 /* Same as THREAD_SETMEM, but the member offset can be non-constant.  */
186 # define THREAD_SETMEM_NC(descr, member, value) \
187 ({                                                                            \
188   __typeof__ (descr->member) __value = (value);                               \
189   if (sizeof (__value) == 1)                                                  \
190     __asm__ __volatile__ ("movb %0,%%fs:(%1)" :                               \
191                           : "q" (__value),                                    \
192                             "r" (offsetof (struct _pthread_descr_struct,      \
193                                            member)));                         \
194   else if (sizeof (__value) == 4)                                             \
195     __asm__ __volatile__ ("movl %k0,%%fs:(%1)" :                              \
196                           : "r" (__value),                                    \
197                             "r" (offsetof (struct _pthread_descr_struct,      \
198                                            member)));                         \
199   else                                                                        \
200     {                                                                         \
201       if (sizeof (__value) != 8)                                              \
202         /* There should not be any value with a size other than 1, 4 or 8.  */\
203         abort ();                                                             \
204                                                                               \
205       __asm__ __volatile__ ("movq %0,%%fs:(%1)" :                             \
206                             : "r" (__value),                                  \
207                               "r" (offsetof (struct _pthread_descr_struct,    \
208                                              member)));                       \
209     }                                                                         \
210 })
211
212 #endif /* !__ASSEMBLER__ */
213
214 /* We want the OS to assign stack addresses.  */
215 #define FLOATING_STACKS 1
216
217 /* Maximum size of the stack if the rlimit is unlimited.  */
218 #define ARCH_STACK_MAX_SIZE     32*1024*1024
219
220 /* The ia32e really want some help to prevent overheating.  */
221 #define BUSY_WAIT_NOP   __asm__ ("rep; nop")
222
223 #endif /* pt-machine.h */