source: trunk/src/emx/include/InnoTekLIBC/thread.h@ 1614

Last change on this file since 1614 was 1614, checked in by bird, 21 years ago

Non-working signal code. (better having it in CVS than locally now)

  • Property cvs2svn:cvs-rev set to 1.8
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 18.8 KB
Line 
1/* $Id: thread.h 1614 2004-11-05 02:16:17Z bird $ */
2/** @file
3 *
4 * LIBC Thread Handling.
5 *
6 * Copyright (c) 2004 knut st. osmundsen <[email protected]>
7 *
8 *
9 * This file is part of InnoTek LIBC.
10 *
11 * InnoTek LIBC is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * InnoTek LIBC is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License
22 * along with InnoTek LIBC; if not, write to the Free Software
23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 *
25 */
26
27#ifndef __InnoTekLIBC_thread_h__
28#define __InnoTekLIBC_thread_h__
29
30/*******************************************************************************
31* Defined Constants And Macros *
32*******************************************************************************/
33/** Maximum number of TLS variables supported by LIBC.
34 * The current limit (128) is higher than for instance WinNT. But if
35 * you think we're wasting space, look at the page padding of the thread
36 * structure... */
37#define __LIBC_TLS_MAX 128
38
39
40/*******************************************************************************
41* Header Files *
42*******************************************************************************/
43#include <sys/cdefs.h>
44#include <time.h> /* struct tm; */
45#include <signal.h>
46
47
48/*******************************************************************************
49* Structures and Typedefs *
50*******************************************************************************/
51struct _uheap;
52
53/**
54 * Per thread structure for LIBC.
55 *
56 * This structure contains buffers and variables which in a single threaded
57 * LIBC would be static.
58 *
59 * Members most frequently used have been put together at the front.
60 */
61typedef struct __libc_thread
62{
63 /** errno value. (Comes first, see errnofun.s.) */
64 int iErrNo;
65 /** Default tiled heap. */
66 struct _uheap * pTiledHeap;
67 /** Default regular heap. */
68 struct _uheap * pRegularHeap;
69 /** Reference count. */
70 volatile unsigned cRefs;
71 /** Thread Id. */
72 unsigned tid;
73 /** Pointer to next thread in the list. */
74 struct __libc_thread *pNext;
75 /** New TLS variable array. */
76 void *apvTLS[__LIBC_TLS_MAX];
77 /** Old TLS variable. */
78 void *pvThreadStoreVar;
79
80 /** The nesting depth of the default logger. */
81 unsigned cDefLoggerDepth;
82 /** Current rand() seed value. */
83 unsigned int iRand;
84 /** Buffer used by asctime() and indirectly by ctime() . (Adds two 2 bytes for padding). */
85 char szAscTimeAndCTimeBuf[26+2];
86 /** Buffer used by gmtime() and localtime(). */
87 struct tm GmTimeAndLocalTimeBuf;
88 /** Buffer used by tmpnam(). */
89 char szTmpNamBuf[16];
90 /** Current posistion of strtok(). */
91 char *pszStrTokPos;
92 /** Buffer used by strerror() to format unknown error values. */
93 char szStrErrorBuf[28];
94 /** Buffer used by _getvol(). */
95 char szVolLabelBuf[12];
96 /** Buffer used by ttyname(). */
97 char szTTYNameBuf[32];
98
99 /** Pending signals.
100 * Protected by the signal semaphore. */
101 sigset_t SigSetPending;
102 /** Blocked signals.
103 * Protected by the signal semaphore. */
104 sigset_t SigSetBlocked;
105 /** Old Blocked signals. Used by sigsuspend().
106 * sigsuspend() sets this and fSigSetBlockedOld. When a signal is to be
107 * delivered this member will be pushed on the stack for use on an eventual
108 * return. fSigSetBlockOld will be clared.
109 * Protected by the signal semaphore. */
110 sigset_t SigSetBlockedOld;
111
112 /** Signals queued for delivery on this thread.
113 * Protected by the signal semaphore. */
114 struct
115 {
116 struct SignalQueued *pHead;
117 struct SignalQueued *pTail;
118 } SigQueue;
119
120 /** Alternate signal stack block address.
121 * Protected by the signal semaphore. */
122 void *pvSigStack;
123 /** Alternate signal stack block size.
124 * Protected by the signal semaphore. */
125 size_t cbSigStack;
126
127 /** @defgroup libc_threadstruct_flags Thread Flags
128 * @todo checkup access safety here!
129 * @{ */
130 /** If set SigSetBlockedOld should be used used to restore SigSetBlocked
131 * when returning from a signal handler. */
132 unsigned fSigSetBlockedOld : 1;
133 /** If set the stack block pointed to by pvSigStack is in use. */
134 unsigned fSigStackActive : 1;
135 /** If set the thread is internal.
136 * This means the thread will not receive signals. */
137 unsigned fInternalThread : 1;
138 /** @} */
139
140 /** Flags whether or not the thread is being forced to evaluate its
141 * pending signals.
142 *
143 * All updates of this variable must be done atomically and when owning
144 * the signal semaphore. The atomically requirement is because it's being
145 * read without owning the semaphore.
146 */
147 volatile unsigned fSigBeingPoked;
148
149
150
151 /** Thread status, chiefly used for the u member of the thread structure. */
152 enum enmLIBCThreadStatus
153 {
154 /** The thread status must be queried from the OS. */
155 enmLIBCThreadStatus_unknown = 0,
156 /** The thread status must be queried from the OS. */
157 enmLIBCThreadStatus_startup,
158 /** The thread is in a sigwait(), sigwaitinfo(), or sigtimedwait() call. */
159 enmLIBCThreadStatus_sigwait,
160 } enmStatus;
161
162 /** Data used in certain thread states.
163 * Use the enmStatus field to determin which way to read the data items here.
164 */
165 union
166 {
167 /** enmLIBCThreadStatus_startup: Begin Thread Arguments. */
168 struct __libc_thread_startup
169 {
170 /** Thread argument. */
171 void *pvArg;
172 /** Thread routine. */
173 void (*pfnStart)(void *pvArg);
174 } startup;
175
176 /** enmLIBCThreadStatus_sigwait: Thread blocked in sigwait(), sigwaitinfo() or sigtimedwait(). */
177 struct __libc_thread_sigwait
178 {
179 /** The signals we're waiting for. */
180 sigset_t SigSetWait;
181 /** The where to return signal info. */
182 siginfo_t *pSigInfo;
183 } SigWait;
184 } u;
185
186 /** Data used by the backends. */
187 union __libc_backend_data
188 {
189 struct __libc_sys
190 {
191 /** Directory find data entry.
192 * Used by __findfirst() and __findnext(). */
193 struct find_data
194 {
195 /** Directory handle. HDIR_CREATE if no session opened. */
196 unsigned long hdir;
197 /** Type of buffer content. FIL_STANDARDL or FIL_STANDARD,
198 * i.e. FILEFINDBUF4 or FILEFINDBUF4L. */
199 unsigned long fType;
200 /** Number of files left in the buffer. */
201 unsigned long cFiles;
202 /** Pointer to the next entry. Don't test on this, test on cFiles! */
203 const char *pchNext;
204 /** Buffer. */
205 char achBuffer[2048];
206 } fd;
207 } sys;
208 } b;
209
210
211} __LIBC_THREAD;
212
213#ifndef __LIBC_THREAD_DECLARED
214#define __LIBC_THREAD_DECLARED
215typedef struct __libc_thread *__LIBC_PTHREAD, **__LIBC_PPTHREAD;
216#endif
217
218
219/**
220 * Thread Termination Callback Registration Record. (cool name, right)
221 * For use with __libc_ThreadRegisterTermCallback().
222 */
223typedef struct __libc_ThreadTermCbRegRec
224{
225 /** This member must be initialized to NULL. */
226 struct __libc_ThreadTermCbRegRec *pNext;
227 /** Flags field reserved for future use.
228 * Must be initalized to ZERO. */
229 unsigned fFlags;
230 /**
231 * The callback function.
232 *
233 * @param pRegRec Registration record which the callback was registered with.
234 * @param fFlags Reserved for future use. Will always be zero when fFlags
235 * in the RegRec is zero.
236 */
237 void (*pfnCallback)(struct __libc_ThreadTermCbRegRec *pRegRec, unsigned fFlags);
238} __LIBC_THREADTERMCBREGREC, *__LIBC_PTHREADTERMCBREGREC;
239
240
241/*******************************************************************************
242* Global Variables *
243*******************************************************************************/
244__BEGIN_DECLS
245/** Pointer to the TLS ULONG (OS/2 rules) which will point to the LIBC thread
246 * structure for the current thread.
247 * The TLS ULONG is allocated by __init_dll(). The thread structure it points to
248 * is allocated on demand. */
249extern __LIBC_PPTHREAD __libc_gpTLS;
250__END_DECLS
251
252
253/*******************************************************************************
254* External Functions *
255*******************************************************************************/
256__BEGIN_DECLS
257/**
258 * Get the thread structure for the current thread.
259 *
260 * Will automatically allocate a thread structure if such is not yet done
261 * for the thread.
262 *
263 * @returns pointer to current thread struct.
264
265 * @remark No reference counting here, current thread have a permanent
266 * reference to it self.
267 * @remark This API is considered to be internal to LIBC and is thus not
268 * exposed in the shared library version of LIBC. Please don't call it.
269 * External LIBs should use the __libc_TLS*() API.
270 */
271#define __libc_threadCurrent() (*__libc_gpTLS ? *__libc_gpTLS : __libc_threadCurrentSlow())
272
273
274/**
275 * Get the thread structure for the current thread.
276 *
277 * Used by the __libc_threadCurrent() macro for allocating a thread structure for the
278 * current thread when such doesn't exist.
279 *
280 * @returns pointer to current thread struct.
281
282 * @remark No reference counting here, current thread have a permanent
283 * reference to it self.
284 * @remark This API is considered to be internal to LIBC and is thus not
285 * exposed in the shared library version of LIBC. Please don't call it.
286 * External LIBs should use the __libc_TLS*() API.
287 */
288__LIBC_PTHREAD __libc_threadCurrentSlow(void);
289
290
291/**
292 * Get the thread structure for the current thread.
293 *
294 * Do not create anything automatically.
295 *
296 * @returns pointer to current thread struct.
297 * @returns NULL if not initiated.
298 *
299 * @remark No reference counting here, current thread have a permanent
300 * reference to it self.
301 * @remark This API is considered to be internal to LIBC and is thus not
302 * exposed in the shared library version of LIBC. Please don't call it.
303 * External LIBs should use the __libc_TLS*() API.
304 */
305#define __libc_threadCurrentNoAuto() (__libc_gpTLS ? *__libc_gpTLS : NULL)
306
307
308/**
309 * Get the thread structure for the thread specified by it's thread identification.
310 *
311 * Used for instance by signal handling to change the signal properties of another
312 * thread.
313 *
314 * @returns Pointer to threads thread struct.
315 * The caller _must_ call __libc_threadRelease() when it's done using the
316 * thread structure.
317 * @returns NULL if the thread wasn't found.
318 * @param tid The Thread Id of the thread to find.
319 * @remark This API is considered to be internal to LIBC and is thus not
320 * exposed in the shared library version of LIBC. Please don't call it.
321 */
322__LIBC_PTHREAD __libc_threadLookup(unsigned tid);
323
324
325/**
326 * Get the thread structure for a thread selected by a custom callback function.
327 *
328 * @returns Pointer to the selected thread.
329 * The caller _must_ call __libc_threadRelease() when it's done using the
330 * thread structure.
331 * @param pfnCallback Function which will to the thread selection.
332 *
333 * Returns 1 if the current thread should be returned.
334 * Returns 2 if the current thread should be returned immediately.
335 * Returns 0 if the current best thread should remain unchanged.
336 * Returns -1 if the enumeration should fail (immediately).
337 *
338 * pCur The current thread.
339 * pBest The current best thread.
340 * pvParam User parameter.
341 *
342 * @param pvParam User Parameter.
343 */
344__LIBC_PTHREAD __libc_threadLookup2(int (pfnCallback)(__LIBC_PTHREAD pCur, __LIBC_PTHREAD pBest, void *pvParam), void *pvParam);
345
346
347/**
348 * Enumerates all the threads LIBC is aware of subjecting each of them to a
349 * caller specified callback function.
350 *
351 * @returns 0 on success.
352 * @returns -1 if pfnCallback returned -1.
353 *
354 * @param pfnCallback Function which will to the thread selection.
355 *
356 * Returns 0 if the enmeration should continue.
357 * Returns -1 if the enumeration should fail (immediately).
358 *
359 * pCur The current thread.
360 * pvParam User parameter.
361 *
362 * @param pvParam User Parameter.
363 */
364int __libc_threadEnum(int (pfnCallback)(__LIBC_PTHREAD pCur, void *pvParam), void *pvParam);
365
366
367/**
368 * Allocate and initialize a thread structure for a thread which is yet
369 * to be created.
370 *
371 * The returned thread structure will have cRefs set to 1, thus
372 * use __libc_threadDereference() to free it.
373 *
374 * @returns Pointer to thread structure.
375 * @returns NULL on error. errno set.
376 */
377__LIBC_PTHREAD __libc_threadAlloc(void);
378
379
380/**
381 * Sets up the current thread to use the thread structure pThrd.
382 *
383 * @param pThrd Pointer to the thread structure this thread
384 * should be using.
385 */
386void __libc_threadUse(__LIBC_PTHREAD pThrd);
387
388
389/**
390 * Dereferences a thread structure referenced by __libc_threadLookup() or
391 * __libc_threadLookup2(), or allocated by __libc_threadAlloc().
392 *
393 * LIBC maintains reference counting on the thread structure so the thread
394 * structure will not be freed by the thread it represent while someone else
395 * is accessing it. However, the reference counting does not protect any of
396 * the structures members from writes or reads, that's left to the users of
397 * the members to synchronize between them.
398 *
399 * @returns pointer to threads thread struct.
400 * @returns NULL if the thread wasn't found.
401 * @param pThrd Pointer to thread structure returned by __libc_threadLookup(),
402 * __libc_threadLookup2() or __libc_threadAlloc().
403 * @remark This API is considered to be internal to LIBC and is thus not
404 * exposed in the shared library version of LIBC. Please don't call it.
405 */
406void __libc_threadDereference(__LIBC_PTHREAD pThrd);
407
408
409/**
410 * Register a thread destruction callback.
411 *
412 * This will be called when one thread is terminating normally, i.e. calling
413 * _endthread() or returning from it's thread function.
414 * When LIBC implements pthreads basics any new non-abnormal thread exit will
415 * cause a callback too.
416 *
417 * @param pRegRec Pointer to thread registration record.
418 * This must be initialized as described in the documation of
419 * the structure. After calling this API the memory must not
420 * be touched or freed by the application. It is not possible
421 * to unregister a callback at present.
422 *
423 * @remark We might wanna extend the API at a later point for calling back
424 * at abnormal termination and such. Such extensions will be done
425 * using the fFlags member of __LIBC_THREADTERMCBREGREC and the fFlags
426 * parameter to the callback.
427 */
428int __libc_ThreadRegisterTermCallback(__LIBC_PTHREADTERMCBREGREC pRegRec);
429
430/**
431 * Internal API which is called by a thread exit to work the registered callbacks.
432 *
433 * Not called for thread 1.
434 *
435 * @param fFlags Reserved for termination reasons.
436 * Zero means normal exit, no other codes have been defined.
437 */
438void __libc_threadTermination(unsigned fFlags);
439
440
441/** @group InnoTek LIBC Thread Local Storage
442 * @{
443 */
444
445/**
446 * Allocates a TLS entry.
447 *
448 * @returns index of the allocated TLS index.
449 * @returns -1 on failure. errno set.
450 */
451int __libc_TLSAlloc(void);
452
453/**
454 * Frees a TLS entry allocated by __libc_TLSAlloc().
455 *
456 * @returns 0 on success.
457 * @returns -1 on failure. errno set.
458 * @param iTLSIndex Value returned by __libc_TLSAlloc().
459 */
460int __libc_TLSFree(int iIndex);
461
462/**
463 * Get the value stored in an allocated TLS entry.
464 *
465 * @returns value in given TLS entry.
466 * @returns NULL on failure with errno set.
467 * @param iTLSIndex Value returned by __libc_TLSAlloc().
468 */
469void * __libc_TLSGet(int iIndex);
470
471/**
472 * Set the value stored in an allocated TLS entry.
473 *
474 * @returns 0 on success.
475 * @returns -1 on failure. errno set.
476 * @param iTLSIndex Value returned by __libc_TLSAlloc().
477 * @param pvValue Value to store.
478 */
479int __libc_TLSSet(int iIndex, void *pvValue);
480
481/**
482 * Register a thread termination destructor for an TLS entry.
483 *
484 * The destructor function will be called when a thread terminates
485 * in a normal fashion and the TLS entry iTLSIndex of that thread is
486 * not NULL.
487 *
488 * There will be no callbacks in thread 1.
489 *
490 * @returns 0 on succces.
491 * @returns -1 on failure. errno set.
492 * @param iTLSIndex Value returned by __libc_TLSAlloc().
493 * @param pfnDestructor Callback function. Use NULL to unregister a previously
494 * registered destructor.
495 *
496 * It's pvValue argument is the non-zero value in the
497 * TLS entry for the thread it's called on.
498 *
499 * It's fFlags argument is reserved for future use, it will
500 * always be zero when the fFlags parameter to this API is zero.
501 *
502 * @param fFlags Flags reserved for future use. At the moment
503 * only ZERO is allowed.
504 *
505 * @remark The application is not allowed to call __libc_TLSFree() for iIndex when calling
506 * this function. The result from doing that is undefined.
507 */
508int __libc_TLSDestructor(int iIndex, void (*pfnDestructor)(void *pvValue, int iTLSIndex, unsigned fFlags), unsigned fFlags);
509
510
511/**
512 * Get pointer to the destructor function registered for the given TLS entry.
513 *
514 * @returns NULL if invalid entry, errno set.
515 * @returns NULL if no entry registered.
516 * @returns Pointer to destructor if registered.
517 *
518 * @param iTLSIndex Value returned by __libc_TLSAlloc().
519 * @param pfFlags Where to store the flags supplied to __libc_TLSDestructor().
520 * NULL is ok.
521 */
522void (*__libc_TLSGetDestructor(int iTLSIndex, unsigned *pfFlags))(void *, int, unsigned);
523
524/** @} */
525
526__END_DECLS
527
528#endif
Note: See TracBrowser for help on using the repository browser.