source: branches/libc-0.6/src/emx/include/InnoTekLIBC/thread.h

Last change on this file was 2254, checked in by bird, 20 years ago

o LIBC_ASSERT*() are for internal libc errors, LIBCLOG_ERROR*() are

for user related error. Big code adjustements.

o Fixed a few smaller issues.
o Started fixing exec() backend.

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