Define PT_EI as extern inline is not yet defined. Use PT_EI in extern
[kopensolaris-gnu/glibc.git] / linuxthreads / sysdeps / alpha / pt-machine.h
1 /* Machine-dependent pthreads configuration and inline functions.
2    Alpha version.
3    Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
4    This file is part of the GNU C Library.
5    Contributed by Richard Henderson <rth@tamu.edu>.
6
7    The GNU C Library is free software; you can redistribute it and/or
8    modify it under the terms of the GNU Library General Public License as
9    published by the Free Software Foundation; either version 2 of the
10    License, or (at your option) any later version.
11
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    Library General Public License for more details.
16
17    You should have received a copy of the GNU Library 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.  */
21
22 #ifndef PT_EI
23 # define PT_EI extern inline
24 #endif
25
26 #include <asm/pal.h>
27
28
29 /* Spinlock implementation; required.  */
30 PT_EI long int
31 testandset (int *spinlock)
32 {
33   long int ret, temp;
34
35   __asm__ __volatile__(
36         "/* Inline spinlock test & set */\n"
37         "1:\t"
38         "ldl_l %0,%3\n\t"
39         "bne %0,2f\n\t"
40         "or $31,1,%1\n\t"
41         "stl_c %1,%2\n\t"
42         "beq %1,1b\n"
43         "2:\tmb\n"
44         "/* End spinlock test & set */"
45         : "=&r"(ret), "=&r"(temp), "=m"(*spinlock)
46         : "m"(*spinlock)
47         : "memory");
48
49   return ret;
50 }
51
52 /* Spinlock release; default is just set to zero.  */
53 #define RELEASE(spinlock) \
54   __asm__ __volatile__("mb" : : : "memory"); \
55   *spinlock = 0
56
57
58 /* Begin allocating thread stacks at this address.  Default is to allocate
59    them just below the initial program stack.  */
60 #define THREAD_STACK_START_ADDRESS  0x40000000000
61
62
63 /* Get some notion of the current stack.  Need not be exactly the top
64    of the stack, just something somewhere in the current frame.  */
65 #define CURRENT_STACK_FRAME  stack_pointer
66 register char *stack_pointer __asm__("$30");
67
68
69 /* Return the thread descriptor for the current thread.  */
70 #define THREAD_SELF \
71 ({                                                                            \
72   register pthread_descr __self __asm__("$0");                                \
73   __asm__ ("call_pal %1" : "=r"(__self) : "i"(PAL_rduniq) : "$0");            \
74   __self;                                                                     \
75 })
76
77 /* Initialize the thread-unique value.  */
78 #define INIT_THREAD_SELF(descr, nr) \
79 {                                                                             \
80   register pthread_descr __self __asm__("$16") = (descr);                     \
81   __asm__ __volatile__ ("call_pal %1" : : "r"(__self), "i"(PAL_wruniq));      \
82 }
83
84
85 /* Compare-and-swap for semaphores. */
86
87 #define HAS_COMPARE_AND_SWAP
88 PT_EI int
89 __compare_and_swap (long int *p, long int oldval, long int newval)
90 {
91   long int ret;
92
93   __asm__ __volatile__ (
94         "/* Inline compare & swap */\n"
95         "1:\t"
96         "ldq_l %0,%4\n\t"
97         "cmpeq %0,%2,%0\n\t"
98         "beq %0,2f\n\t"
99         "mov %3,%0\n\t"
100         "stq_c %0,%1\n\t"
101         "beq %0,1b\n\t"
102         "2:\tmb\n"
103         "/* End compare & swap */"
104         : "=&r"(ret), "=m"(*p)
105         : "r"(oldval), "r"(newval), "m"(*p));
106
107   return ret;
108 }