.
[kopensolaris-gnu/glibc.git] / hurd / hurd / threadvar.h
1 /* Internal per-thread variables for the Hurd.
2    Copyright (C) 1994,95,97,98,99,2001,02 Free Software Foundation, Inc.
3    This file is part of the GNU C Library.
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 #ifndef _HURD_THREADVAR_H
21 #define _HURD_THREADVAR_H
22
23 #include <features.h>
24
25 /* The per-thread variables are found by ANDing this mask
26    with the value of the stack pointer and then adding this offset.
27
28    In the multi-threaded case, cthreads initialization sets
29    __hurd_threadvar_stack_mask to ~(cthread_stack_size - 1), a mask which
30    finds the base of the fixed-size cthreads stack; and
31    __hurd_threadvar_stack_offset to a small offset that skips the data
32    cthreads itself maintains at the base of each thread's stack.
33
34    In the single-threaded case, __hurd_threadvar_stack_mask is zero, so the
35    stack pointer is ignored; and __hurd_threadvar_stack_offset gives the
36    address of a small allocated region which contains the variables for the
37    single thread.  */
38
39 extern unsigned long int __hurd_threadvar_stack_mask;
40 extern unsigned long int __hurd_threadvar_stack_offset;
41
42 /* A special case must always be made for the signal thread.  Even when there
43    is only one user thread and an allocated region can be used for the user
44    thread's variables, the signal thread needs to have its own location for
45    per-thread variables.  The variables __hurd_sigthread_stack_base and
46    __hurd_sigthread_stack_end define the bounds of the stack used by the
47    signal thread, so that thread can always be specifically identified.  */
48
49 extern unsigned long int __hurd_sigthread_stack_base;
50 extern unsigned long int __hurd_sigthread_stack_end;
51 extern unsigned long int *__hurd_sigthread_variables;
52
53
54 /* At the location described by the two variables above,
55    there are __hurd_threadvar_max `unsigned long int's of per-thread data.  */
56 extern unsigned int __hurd_threadvar_max;
57
58 /* These values are the indices for the standard per-thread variables.  */
59 enum __hurd_threadvar_index
60   {
61     _HURD_THREADVAR_MIG_REPLY,  /* Reply port for MiG user stub functions.  */
62     _HURD_THREADVAR_ERRNO,      /* `errno' value for this thread.  */
63     _HURD_THREADVAR_SIGSTATE,   /* This thread's `struct hurd_sigstate'.  */
64     _HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables.  */
65     _HURD_THREADVAR_MALLOC,     /* For use of malloc.  */
66     _HURD_THREADVAR_DL_ERROR,   /* For use of -ldl and dynamic linker.  */
67     _HURD_THREADVAR_RPC_VARS,   /* For state of RPC functions.  */
68     _HURD_THREADVAR_LOCALE,     /* For thread-local locale setting.  */
69     _HURD_THREADVAR_CTYPE_B,    /* Cache of thread-local locale data.  */
70     _HURD_THREADVAR_CTYPE_TOLOWER, /* Cache of thread-local locale data.  */
71     _HURD_THREADVAR_CTYPE_TOUPPER, /* Cache of thread-local locale data.  */
72     _HURD_THREADVAR_MAX         /* Default value for __hurd_threadvar_max.  */
73   };
74
75
76 #ifndef _HURD_THREADVAR_H_EXTERN_INLINE
77 #define _HURD_THREADVAR_H_EXTERN_INLINE extern __inline
78 #endif
79
80 /* Return the location of the value for the per-thread variable with index
81    INDEX used by the thread whose stack pointer is SP.  */
82
83 extern unsigned long int *__hurd_threadvar_location_from_sp
84   (enum __hurd_threadvar_index __index, void *__sp);
85 _HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
86 __hurd_threadvar_location_from_sp (enum __hurd_threadvar_index __index,
87                                    void *__sp)
88 {
89   unsigned long int __stack = (unsigned long int) __sp;
90   return &((__stack >= __hurd_sigthread_stack_base &&
91             __stack < __hurd_sigthread_stack_end)
92            ? __hurd_sigthread_variables
93            : (unsigned long int *) ((__stack & __hurd_threadvar_stack_mask) +
94                                     __hurd_threadvar_stack_offset))[__index];
95 }
96
97 #include <machine-sp.h>         /* Define __thread_stack_pointer.  */
98
99 /* Return the location of the current thread's value for the
100    per-thread variable with index INDEX.  */
101
102 extern unsigned long int *
103 __hurd_threadvar_location (enum __hurd_threadvar_index __index) __THROW
104      /* This declaration tells the compiler that the value is constant
105         given the same argument.  We assume this won't be called twice from
106         the same stack frame by different threads.  */
107      __attribute__ ((__const__));
108
109 _HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
110 __hurd_threadvar_location (enum __hurd_threadvar_index __index)
111 {
112   return __hurd_threadvar_location_from_sp (__index,
113                                             __thread_stack_pointer ());
114 }
115
116
117 #endif  /* hurd/threadvar.h */