1 /* Machine-dependent pthreads configuration and inline functions.
3 Copyright (C) 2000, 2002, 2003 Free Software Foundation, Inc.
4 This file is part of the GNU C Library.
5 Contributed by Richard Henderson <rth@tamu.edu>.
7 The GNU C Library is free software; you can redistribute it and/or
8 modify it under the terms of the GNU Lesser General Public License as
9 published by the Free Software Foundation; either version 2.1 of the
10 License, or (at your option) any later version.
12 The GNU C Library is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public
18 License along with the GNU C Library; see the file COPYING.LIB. If not,
19 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
23 #define _PT_MACHINE_H 1
25 #include <sys/types.h>
26 #include <bits/initspin.h>
29 # define PT_EI extern inline __attribute__ ((always_inline))
32 extern inline long int testandset (__atomic_lock_t
*spinlock
);
33 extern inline int __compare_and_swap (long int *p
, long int oldval
, long int newval
);
34 extern inline int lock_held (__atomic_lock_t
*spinlock
);
35 extern inline int __load_and_clear (__atomic_lock_t
*spinlock
);
37 /* Get some notion of the current stack. Need not be exactly the top
38 of the stack, just something somewhere in the current frame. */
39 #define CURRENT_STACK_FRAME stack_pointer
40 register char * stack_pointer
__asm__ ("%r30");
42 /* Get/Set thread-specific pointer. We have to call into the kernel to
43 * modify it, but we can read it in user mode. */
45 #define THREAD_SELF __get_cr27()
48 #ifndef SET_THREAD_SELF
49 #define SET_THREAD_SELF(descr) __set_cr27(descr)
51 /* Use this to determine type */
52 struct _pthread_descr_struct
*__thread_self
;
54 static inline struct _pthread_descr_struct
* __get_cr27(void)
57 asm ("mfctl %%cr27, %0" : "=r" (cr27
) : );
58 return (struct _pthread_descr_struct
*) cr27
;
61 #ifndef INIT_THREAD_SELF
62 #define INIT_THREAD_SELF(descr, nr) __set_cr27(descr)
65 static inline void __set_cr27(struct _pthread_descr_struct
* cr27
)
67 asm ( "ble 0xe0(%%sr2, %%r0)\n\t"
69 : : "r" (cr27
) : "r26" );
72 /* We want the OS to assign stack addresses. */
73 #define FLOATING_STACKS 1
74 #define ARCH_STACK_MAX_SIZE 8*1024*1024
76 /* The hppa only has one atomic read and modify memory operation,
77 load and clear, so hppa spinlocks must use zero to signify that
78 someone is holding the lock. The address used for the ldcw
79 semaphore must be 16-byte aligned. */
83 __asm__ __volatile__("ldcw 0(%1),%0" \
84 : "=r" (__ret) : "r" (a) : "memory"); \
88 /* Strongly ordered lock reset */
89 #define __lock_reset(lock_addr, tmp) \
91 __asm__ __volatile__ ("stw,ma %1,0(%0)" \
92 : : "r" (lock_addr), "r" (tmp) : "memory"); \
95 /* Because malloc only guarantees 8-byte alignment for malloc'd data,
96 and GCC only guarantees 8-byte alignment for stack locals, we can't
97 be assured of 16-byte alignment for atomic lock data even if we
98 specify "__attribute ((aligned(16)))" in the type declaration. So,
99 we use a struct containing an array of four ints for the atomic lock
100 type and dynamically select the 16-byte aligned int from the array
101 for the semaphore. */
102 #define __PA_LDCW_ALIGNMENT 16
103 #define __ldcw_align(a) ({ \
104 volatile unsigned int __ret = (unsigned int) a; \
105 if ((__ret & ~(__PA_LDCW_ALIGNMENT - 1)) < (unsigned int) a) \
106 __ret = (__ret & ~(__PA_LDCW_ALIGNMENT - 1)) + __PA_LDCW_ALIGNMENT; \
107 (unsigned int *) __ret; \
110 /* Spinlock implementation; required. */
112 __load_and_clear (__atomic_lock_t
*spinlock
)
114 volatile unsigned int *a
= __ldcw_align (spinlock
);
119 /* Emulate testandset */
121 testandset (__atomic_lock_t
*spinlock
)
123 return (__load_and_clear(spinlock
) == 0);
127 lock_held (__atomic_lock_t
*spinlock
)
129 volatile unsigned int *a
= __ldcw_align (spinlock
);
134 #endif /* pt-machine.h */