Back to index

glibc  2.9
threadvar.h
Go to the documentation of this file.
00001 /* Internal per-thread variables for the Hurd.
00002    Copyright (C) 1994,95,97,98,99,2001,02,06,07 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #ifndef _HURD_THREADVAR_H
00021 #define       _HURD_THREADVAR_H
00022 
00023 #include <features.h>
00024 
00025 /* The per-thread variables are found by ANDing this mask
00026    with the value of the stack pointer and then adding this offset.
00027 
00028    In the multi-threaded case, cthreads initialization sets
00029    __hurd_threadvar_stack_mask to ~(cthread_stack_size - 1), a mask which
00030    finds the base of the fixed-size cthreads stack; and
00031    __hurd_threadvar_stack_offset to a small offset that skips the data
00032    cthreads itself maintains at the base of each thread's stack.
00033 
00034    In the single-threaded case, __hurd_threadvar_stack_mask is zero, so the
00035    stack pointer is ignored; and __hurd_threadvar_stack_offset gives the
00036    address of a small allocated region which contains the variables for the
00037    single thread.  */
00038 
00039 extern unsigned long int __hurd_threadvar_stack_mask;
00040 extern unsigned long int __hurd_threadvar_stack_offset;
00041 
00042 /* A special case must always be made for the signal thread.  Even when there
00043    is only one user thread and an allocated region can be used for the user
00044    thread's variables, the signal thread needs to have its own location for
00045    per-thread variables.  The variables __hurd_sigthread_stack_base and
00046    __hurd_sigthread_stack_end define the bounds of the stack used by the
00047    signal thread, so that thread can always be specifically identified.  */
00048 
00049 extern unsigned long int __hurd_sigthread_stack_base;
00050 extern unsigned long int __hurd_sigthread_stack_end;
00051 extern unsigned long int *__hurd_sigthread_variables;
00052 
00053 
00054 /* At the location described by the two variables above,
00055    there are __hurd_threadvar_max `unsigned long int's of per-thread data.  */
00056 extern unsigned int __hurd_threadvar_max;
00057 
00058 /* These values are the indices for the standard per-thread variables.  */
00059 enum __hurd_threadvar_index
00060   {
00061     _HURD_THREADVAR_MIG_REPLY,     /* Reply port for MiG user stub functions.  */
00062     _HURD_THREADVAR_ERRNO,  /* `errno' value for this thread.  */
00063     _HURD_THREADVAR_SIGSTATE,      /* This thread's `struct hurd_sigstate'.  */
00064     _HURD_THREADVAR_DYNAMIC_USER, /* Dynamically-assigned user variables.  */
00065     _HURD_THREADVAR_MALLOC, /* For use of malloc.  */
00066     _HURD_THREADVAR_DL_ERROR,      /* For use of -ldl and dynamic linker.  */
00067     _HURD_THREADVAR_RPC_VARS,      /* For state of RPC functions.  */
00068     _HURD_THREADVAR_LOCALE, /* For thread-local locale setting.  */
00069     _HURD_THREADVAR_CTYPE_B,       /* Cache of thread-local locale data.  */
00070     _HURD_THREADVAR_CTYPE_TOLOWER, /* Cache of thread-local locale data.  */
00071     _HURD_THREADVAR_CTYPE_TOUPPER, /* Cache of thread-local locale data.  */
00072     _HURD_THREADVAR_MAX            /* Default value for __hurd_threadvar_max.  */
00073   };
00074 
00075 
00076 #ifndef _HURD_THREADVAR_H_EXTERN_INLINE
00077 #define _HURD_THREADVAR_H_EXTERN_INLINE __extern_inline
00078 #endif
00079 
00080 /* Return the location of the value for the per-thread variable with index
00081    INDEX used by the thread whose stack pointer is SP.  */
00082 
00083 extern unsigned long int *__hurd_threadvar_location_from_sp
00084   (enum __hurd_threadvar_index __index, void *__sp);
00085 _HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
00086 __hurd_threadvar_location_from_sp (enum __hurd_threadvar_index __index,
00087                                void *__sp)
00088 {
00089   unsigned long int __stack = (unsigned long int) __sp;
00090   return &((__stack >= __hurd_sigthread_stack_base &&
00091            __stack < __hurd_sigthread_stack_end)
00092           ? __hurd_sigthread_variables
00093           : (unsigned long int *) ((__stack & __hurd_threadvar_stack_mask) +
00094                                 __hurd_threadvar_stack_offset))[__index];
00095 }
00096 
00097 #include <machine-sp.h>            /* Define __thread_stack_pointer.  */
00098 
00099 /* Return the location of the current thread's value for the
00100    per-thread variable with index INDEX.  */
00101 
00102 extern unsigned long int *
00103 __hurd_threadvar_location (enum __hurd_threadvar_index __index) __THROW
00104      /* This declaration tells the compiler that the value is constant
00105        given the same argument.  We assume this won't be called twice from
00106        the same stack frame by different threads.  */
00107      __attribute__ ((__const__));
00108 
00109 _HURD_THREADVAR_H_EXTERN_INLINE unsigned long int *
00110 __hurd_threadvar_location (enum __hurd_threadvar_index __index)
00111 {
00112   return __hurd_threadvar_location_from_sp (__index,
00113                                        __thread_stack_pointer ());
00114 }
00115 
00116 
00117 #endif /* hurd/threadvar.h */