Back to index

glibc  2.9
pt-machine.h
Go to the documentation of this file.
00001 /* Machine-dependent pthreads configuration and inline functions.
00002    IA-64 version.
00003    Copyright (C) 1999, 2000, 2002, 2003, 2004 Free Software Foundation, Inc.
00004    This file is part of the GNU C Library.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public License as
00008    published by the Free Software Foundation; either version 2.1 of the
00009    License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; see the file COPYING.LIB.  If not,
00018    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019    Boston, MA 02111-1307, USA.  */
00020 
00021 #ifndef _PT_MACHINE_H
00022 #define _PT_MACHINE_H   1
00023 
00024 #include <ia64intrin.h>
00025 
00026 #ifndef PT_EI
00027 # define PT_EI extern inline __attribute__ ((always_inline))
00028 #endif
00029 
00030 extern long int testandset (int *spinlock);
00031 extern int __compare_and_swap (long int *p, long int oldval, long int newval);
00032 
00033 /* Make sure gcc doesn't try to be clever and move things around on
00034    us. We need to use _exactly_ the address the user gave us, not some
00035    alias that contains the same information.  */
00036 #define __atomic_fool_gcc(x) (*(volatile struct { int a[100]; } *)x)
00037 
00038 #ifndef ELF_MACHINE_NAME
00039 
00040 #define NEED_SEPARATE_REGISTER_STACK
00041 
00042 /* We want the OS to assign stack addresses.  */
00043 #define FLOATING_STACKS 1
00044 
00045 /* Maximum size of the stack if the rlimit is unlimited.  */
00046 #define ARCH_STACK_MAX_SIZE     32*1024*1024
00047 
00048 /* Get some notion of the current stack.  Need not be exactly the top
00049    of the stack, just something somewhere in the current frame.
00050    r12 (sp) is the stack pointer. */
00051 #define CURRENT_STACK_FRAME  stack_pointer
00052 register char *stack_pointer __asm__ ("sp");
00053 
00054 
00055 /* Register r13 (tp) is reserved by the ABI as "thread pointer". */
00056 struct _pthread_descr_struct;
00057 register struct _pthread_descr_struct *__thread_self __asm__("r13");
00058 
00059 /* Return the thread descriptor for the current thread.  */
00060 #define THREAD_SELF  __thread_self
00061 
00062 /* Initialize the thread-unique value.  */
00063 #define INIT_THREAD_SELF(descr, nr)  (__thread_self = (descr))
00064 
00065 
00066 /* Access to data in the thread descriptor is easy.  */
00067 #define THREAD_GETMEM(descr, member) \
00068   ((void) sizeof (descr), THREAD_SELF->member)
00069 #define THREAD_GETMEM_NC(descr, member) \
00070   ((void) sizeof (descr), THREAD_SELF->member)
00071 #define THREAD_SETMEM(descr, member, value) \
00072   ((void) sizeof (descr), THREAD_SELF->member = (value))
00073 #define THREAD_SETMEM_NC(descr, member, value) \
00074   ((void) sizeof (descr), THREAD_SELF->member = (value))
00075 
00076 
00077 /* Memory barrier */
00078 #define MEMORY_BARRIER() __sync_synchronize ()
00079 
00080 
00081 #define HAS_COMPARE_AND_SWAP_WITH_RELEASE_SEMANTICS
00082 
00083 PT_EI int
00084 __compare_and_swap (long int *p, long int oldval, long int newval)
00085 {
00086   long int readval;
00087 
00088   __asm__ __volatile__
00089        ("mov ar.ccv=%4;;\n\t"
00090        "cmpxchg8.acq %0=%1,%2,ar.ccv"
00091        : "=r" (readval), "=m" (__atomic_fool_gcc (p))
00092        : "r"(newval), "m" (__atomic_fool_gcc (p)), "r" (oldval)
00093        : "memory");
00094   return readval == oldval;
00095 }
00096 
00097 PT_EI int
00098 __compare_and_swap_with_release_semantics (long int *p,
00099                                       long int oldval,
00100                                       long int newval)
00101 {
00102   long int readval;
00103 
00104   __asm__ __volatile__
00105        ("mov ar.ccv=%4;;\n\t"
00106        "cmpxchg8.rel %0=%1,%2,ar.ccv"
00107        : "=r" (readval), "=m" (__atomic_fool_gcc (p))
00108        : "r"(newval), "m" (__atomic_fool_gcc (p)), "r" (oldval)
00109        : "memory");
00110   return readval == oldval;
00111 }
00112 
00113 #endif /* ELF_MACHINE_NAME */
00114 
00115 /* Spinlock implementation; required.  */
00116 PT_EI long int
00117 testandset (int *spinlock)
00118 {
00119   long int ret;
00120 
00121   __asm__ __volatile__(
00122        "xchg4 %0=%1,%2"
00123        : "=r"(ret), "=m"(__atomic_fool_gcc (spinlock))
00124        : "r"(1), "m"(__atomic_fool_gcc (spinlock))
00125        : "memory");
00126 
00127   return ret;
00128 }
00129 
00130 /* Indicate that we are looping.  */
00131 #define BUSY_WAIT_NOP       __asm__ ("hint @pause")
00132 
00133 #endif /* pt-machine.h */