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