1 /*
2  *                        Copyright (C) 2004-2009
3  *                    Green Hills Software, Inc.
4  *
5  *    This program is the property of Green Hills Software, Inc,
6  *    its contents are proprietary information and no part of it
7  *    is to be disclosed to anyone except employees of Green Hills
8  *    Software, Inc., or as agreed in writing signed by the President
9  *    of Green Hills Software, Inc.
10  *
11  */
12 
13 #ifndef _THREAD_H_
14 #define _THREAD_H_
15 
16 #include <signal.h>
17 #include <stdio.h>
18 #include <time.h>
19 #include <setjmp.h>
20 
21 #if !defined(_SIGMAX)
22 #  if defined(SOLARIS20)
23 #    define _SIGMAX MAXSIG
24 #  elif defined(__linux) || defined(MSW) || defined(__LYNX)
25 #    define _SIGMAX (NSIG-1)
26 #  endif
27 #endif
28 
29 #if defined(_SIGMAX)
30 typedef void (*SignalHandler)(int);
31 
32 /*
33   The following specifiers are used when calling
34   __ghs_GetThreadLocalStorageItem.
35 
36   If __ghs_GetThreadLocalStorageItem is customized to
37   return a per-thread errno value, define the preprocessor symbol
38   USE_THREAD_LOCAL_ERRNO in ind_errn.c.
39  */
40 
41 enum __ghs_ThreadLocalStorage_specifier {
42     __ghs_TLS_asctime_buff,
43     __ghs_TLS_tmpnam_space,
44     __ghs_TLS_strtok_saved_pos,
45     __ghs_TLS_Errno,
46     __ghs_TLS_gmtime_temp,
47     __ghs_TLS___eh_globals,
48     __ghs_TLS_SignalHandlers,
49     __ghs_TLS__eh_mem_manage,
50     __ghs_TLS__eh_store_globals,
51     __ghs_TLS__eh_store_globals_tdeh,
52     __ghs_TLS__eh_init_block
53 };
54 
55 #ifdef __ghs_pic
56 #pragma weak __ghs_undefined_func
57 extern void *__ghs_undefined_func(int);
58 #endif /* __ghs_pic */
59 
60 #if defined(__INTEGRITY_SHARED_LIBS)
61 /* Allow INTEGRITY libraries to use GetThreadLocalStorage or
62    __ghs_GetThreadLocalStorageItem */
63 #pragma weak __ghs_GetThreadLocalStorageItem
64 /* Allow asctim, strtok, and tmpnam in INTEGRITY libraries to
65    to use either GetThreadLocalStorage or
66    __ghs_GetThreadLocalStorageItem */
67 #define GHS_LEGACY_TLS_COMPATIBILITY
68 #endif
69 
70 /*
71  * __ghs_GetThreadLocalStorageItem() retrieves thread-local storage
72  * items needed by library code. In previous releases, this symbol
73  * was declared weak to allow use of the legacy GetThreadLocalStorage
74  * interface used in releases prior to MULTI 4.2.3.
75  *
76  * Developing a new thread-local storage implementation:
77  *
78  * Customized thread-local storage implementations that will only
79  * use runtime libraries from MULTI releases 4.2.3 and later
80  * can implement __ghs_GetThreadLocalStorageItem() only.  If
81  * compatibility with earlier releases is also required, the
82  * implementation of GetThreadLocalStorage() is required as well.
83  *
84  * Upgrading a legacy thread-local storage implementation:
85  *
86  * If you have a customized thread-local storage implementation
87  * that was developed with the previous GetThreadLocalStorage
88  * capability, add the following implementation of
89  * __ghs_GetThreadLocalStorageItem to maintain compatibility with
90  * runtime libraries provided with MULTI 4.2.3 and later.
91  *
92  *      __ghs_GetThreadLocalStorageItem implementation that
93  *      uses an existing GetThreadLocalStorage routine:
94 
95 	void *__ghs_GetThreadLocalStorageItem(int specifier)
96 	{
97 	    ThreadLocalStorage *tls = GetThreadLocalStorage();
98 	    if(!tls)
99 		return (void *)0;
100 	    switch (specifier) {
101 		case (int)__ghs_TLS_Errno:
102 		    return (void *)&tls->Errno;
103 		case (int)__ghs_TLS_SignalHandlers:
104 		    return (void *)&tls->SignalHandlers;
105 		case (int)__ghs_TLS_asctime_buff:
106 		    return (void *)&tls->asctime_buff;
107 		case (int)__ghs_TLS_tmpnam_space:
108 		    return (void *)&tls->tmpnam_space;
109 		case (int)__ghs_TLS_strtok_saved_pos:
110 		    return (void *)&tls->strtok_saved_pos;
111 		case (int)__ghs_TLS_gmtime_temp:
112 		    return (void *)&tls->gmtime_temp;
113 		case (int)__ghs_TLS___eh_globals:
114 		    return (void *)&tls->__eh_globals;
115 	    }
116 	    return (void *)0;
117 	}
118 
119  */
120 extern void *__ghs_GetThreadLocalStorageItem(int);
121 
122 /*
123  * Some of the functions in this file are to be implemented by the user for
124  * use by the Green Hills Libraries.  See the Building book for more
125  * information.
126  *
127  */
128 
129 /* Acquire a lock which can be obtained from within an interrupt handler. */
130 #pragma weak __ghs_InterruptLock
131 void __ghs_InterruptLock(void);
132 
133 /* Release the lock acquired via __ghs_InterruptLock. */
134 #pragma weak __ghs_InterruptUnlock
135 void __ghs_InterruptUnlock(void);
136 
137 #ifdef __ghs_pic
138 #define __ghs_weak_sym_check(_fn) ((void*)_fn != (void*)__ghs_undefined_func)
139 #else
140 #define __ghs_weak_sym_check(_fn) (_fn)
141 #endif
142 
143 #if defined(GHS_LEGACY_TLS_COMPATIBILITY)
144 /* Allow INTEGRITY libraries to use either GetThreadLocalStorage or
145  * __ghs_GetThreadLocalStorageItem
146  */
147 
148 /* Use of ThreadLocalStorage from outside libsys is deprecated.  */
149 typedef struct
150 {
151 	int			Errno;
152 	SignalHandler 		SignalHandlers[_SIGMAX];
153 	char			tmpnam_space[L_tmpnam];
154 	char			asctime_buff[30];
155 	char			*strtok_saved_pos;
156 	struct tm		gmtime_temp;
157 	void 			*__eh_globals;
158 } ThreadLocalStorage;
159 
160 /* Return pointer to thread local storage */
161 #pragma weak GetThreadLocalStorage
162 ThreadLocalStorage *GetThreadLocalStorage(void);
163 
164 #ifdef __ghs_pic
165 #define __ghs_SafeGetThreadLocalStorageItem(item) \
166     ((&__ghs_GetThreadLocalStorageItem == &__ghs_undefined_func) ? \
167 	    (&(GetThreadLocalStorage()->item)) : \
168 	    (__ghs_GetThreadLocalStorageItem(__ghs_TLS_ ## item)))
169 #else
170 #define __ghs_SafeGetThreadLocalStorageItem(item) \
171     (!(&__ghs_GetThreadLocalStorageItem) ? \
172 	    (&(GetThreadLocalStorage()->item)) : \
173 	    (__ghs_GetThreadLocalStorageItem(__ghs_TLS_ ## item)))
174 #endif
175 #endif /* defined(GHS_LEGACY_TLS_COMPATIBILITY) */
176 
177 /* A "static" buffer to be shared between ind_gmtm.c and ind_tmzn.c */
178 extern struct tm __ghs_static_gmtime_temp;
179 
180 /* Define wrappers for profiling hooks to call interrupt lock if available,
181  * otherwise fall back on _ghsLock.  The interrupt lock is necessary if
182  * profiling may be used for code executing at interrupt level, or in some
183  * other context (e.g. kernel-internal) where the ghsLock cannot be used. */
184 #define __ghs_ProfileLock() { 						\
185     if (__ghs_weak_sym_check(__ghs_InterruptLock))			\
186 	__ghs_InterruptLock();						\
187     else								\
188 	__ghsLock();							\
189 }
190 #define __ghs_ProfileUnlock() { 					\
191     if (__ghs_weak_sym_check(__ghs_InterruptUnlock))			\
192 	__ghs_InterruptUnlock();					\
193     else								\
194 	__ghsUnlock();							\
195 }
196 
197 /* Acquire global lock.  Blocks until the lock becomes available. */
198 /* Implemented by the user for Green Hills libraries.  */
199 void __ghsLock(void);
200 
201 /* Release global lock */
202 /* Implemented by the user for Green Hills libraries.  */
203 void __ghsUnlock(void);
204 
205 /* Save arbitrary state across a setjmp() */
206 /* Implemented by the user for Green Hills libraries.  */
207 int  __ghs_SaveSignalContext(jmp_buf);
208 
209 /* Restore arbitrary state across a longjmp() */
210 /* Implemented by the user for Green Hills libraries.  */
211 void __ghs_RestoreSignalContext(jmp_buf);
212 
213 #if (!defined (EMBEDDED) && !defined (__OSE) && !defined (MSW)) || defined(MINIMAL_STARTUP)
__ghsLock(void)214 __inline void __ghsLock(void) { }
__ghsUnlock(void)215 __inline void __ghsUnlock(void) { }
216 #endif /* !EMBEDDED && !__OSE && !MSW */
217 
218 
219 #define GHSLOCK		__ghsLock();
220 #define GHSUNLOCK	__ghsUnlock();
221 
222 /* macros used in stdio library source */
223 #ifndef __disable_thread_safe_extensions
224 # define LOCKFILE(f)	flockfile(f);
225 # define TRYLOCKFILE(f)	ftrylockfile(f);
226 # define UNLOCKFILE(f)	funlockfile(f);
227 # define LOCKCREATE(f)	flockcreate(f);
228 # define LOCKCLEANUP(f)	flockdestroy(f);
229 # define LOCKINUSE(f)   __ghs_flock_in_use(f)
230 /* prototypes for FILE lock routines (not in POSIX API) */
231 
232 void ** __ghs_flock_ptr(void *);
233 
234 /* Acquire lock for FILE *addr */
235 /* Implemented by the user for Green Hills libraries.  */
236 void __ghs_flock_file(void *);
237 
238 /* Release lock for FILE *addr */
239 /* Implemented by the user for Green Hills libraries.  */
240 void __ghs_funlock_file(void *);
241 
242 /* Non blocking acquire lock for FILE *addr.  May return -1 if */
243 /* this cannot be implemented. Returns 0 on success and nonzero. */
244 /* Implemented by the user for Green Hills libraries.  */
245 int __ghs_ftrylock_file(void *);
246 
247 int __ghs_flock_in_use(void *);
248 
249 /* Callbacks to initialize local lock data structures before they */
250 /* are used. */
251 /* Implemented by the user for Green Hills libraries.  */
252 void __ghs_flock_create(void **);
253 void __ghs_flock_destroy(void *);
254 #else
255 # define LOCKFILE(f)
256 # define TRYLOCKFILE(f)	-1;	/* no lock obtained */
257 # define UNLOCKFILE(f)
258 # define LOCKCREATE(f)
259 # define LOCKCLEANUP(f)
260 # define LOCKINUSE(f) 0
261 #endif
262 /* prototypes for FILE lock routines (not in POSIX API) */
263 void flockcreate(FILE *stream);
264 void flockdestroy(FILE *stream);
265 /* End New */
266 
267 #ifdef __Declare_Initialization_Routines__
268 #pragma weak __gh_iob_init
269 extern void __gh_iob_init(void);
270 #pragma weak __gh_error_init
271 extern void __gh_error_init(void);
272 #pragma weak __gh_lock_init
273 
274 /* A callback to initialize the lock data structure before it is used. */
275 /* This function is provided by the user for use by the Green Hills libraries.
276  */
277 extern void __gh_lock_init(void);
278 #if defined(__OSE)
279 #else
280 #pragma weak __cpp_exception_init
281 #endif /* __OSE */
282 extern void __cpp_exception_init(void **);
283 #if defined(__OSE)
284 #else
285 #pragma weak __cpp_exception_cleanup
286 #endif /* __OSE */
287 extern void __cpp_exception_cleanup(void **);
288 #endif /* __Declare_Initialization_Routines__ */
289 #endif /* defined(_SIGMAX) */
290 #endif /* _THREAD_H_ */
291 
292