1 /* $Id: ncbithr.h,v 6.11 2002/07/09 15:33:46 kans Exp $ */
2 /*****************************************************************************
3 
4     Name: ncbithr.h
5 
6     Description: Function and type declarations for Multi-Thread API library.
7 
8     Author: Sergei Shavirin, Denis Vakatov
9 
10    ***************************************************************************
11 
12                           PUBLIC DOMAIN NOTICE
13               National Center for Biotechnology Information
14 
15     This software/database is a "United States Government Work" under the
16     terms of the United States Copyright Act.  It was written as part of
17     the author's official duties as a United States Government employee
18     and thus cannot be copyrighted.  This software/database is freely
19     available to the public for use. The National Library of Medicine and
20     the U.S. Government have not placed any restriction on its use or
21     reproduction.
22 
23     Although all reasonable efforts have been taken to ensure the accuracy
24     and reliability of the software and data, the NLM and the U.S.
25     Government do not and cannot warrant the performance or results that
26     may be obtained by using this software or data. The NLM and the U.S.
27     Government disclaim all warranties, express or implied, including
28     warranties of performance, merchantability or fitness for any
29     particular purpose.
30 
31     Please cite the author in any work or product based on this material.
32 
33    ***************************************************************************
34 
35  Modification History:
36 -----------------------------------------------------------------------------
37 * $Log: ncbithr.h,v $
38 * Revision 6.11  2002/07/09 15:33:46  kans
39 * use Nlm_ prefixes now that it is indirectly included by vibwndws.c
40 *
41 * Revision 6.10  2000/11/06 17:09:21  vakatov
42 * RW_HISTORY, RW_TRACE -- To gather and printout info on the RW-lock history
43 *
44 * Revision 6.9  1999/10/14 18:44:36  vakatov
45 * For better consistency, include <ncbilcl.h> to <ncbistd.h>
46 *
47 * Revision 6.8  1998/02/27 17:13:58  vakatov
48 * [WIN32 DLL]  Declared some functions as NLM_EXTERN(DLL-exportable)
49 *
50 * Revision 6.7  1998/02/17 20:13:55  vakatov
51 * NlmTlsInit() removed from the public API;  instead, the
52 * NlmTlsSetValue() now initializes the TLS if it is not initialized yet
53 *
54 * Revision 6.6  1998/02/13 15:15:36  vakatov
55 * Added "cleanup" parameter to NlmTlsSetValue() to provide TLS cleanup.
56 * Removed NlmTlsDestroy(); now destroy all TLSs in NlmThreadDestroyAll()
57 *
58 * Revision 6.5  1998/01/08 17:17:08  vakatov
59 * Added NlmThreadJoinAll() and NlmThreadCleanupAll()
60 *
61 * Revision 6.4  1997/12/24 17:18:01  vakatov
62 * Added TLS(Thread Local Storage) functionality for all platforms(incl.
63 * non-"thread-capable" ones -- interpreted as a single-thread application)
64 *
65 * Revision 6.3  1997/12/23 19:13:32  vakatov
66 * Thread handling -- revised, fixed:
67 * removed NlmThreadKill(), NlmThread[Set|Get]Concurrency() and
68 * NlmThread[Set|Get]Priority() functions;
69 * NlmThreadCreate() doesn't accept parameter "flags" anymore;
70 * added "priority" parameter to NlmThreadCreateEx()
71 *
72 * Revision 6.2  1997/12/17 19:11:27  vakatov
73 * Use all-platform THREAD_{RUN|BOUND|DETACHED} instead of the platform
74 * specific THR_{...} thread creation/running attributes
75 *
76 * Revision 6.1  1997/12/16 23:12:38  vakatov
77 * Mutexes and RW-locks:  revised, rewritten, fixed;  added built-in
78 * strict run-time checks -- (use -D_DEBUG_HARD)
79 *
80 *
81 * 20 February of 1996 - Shavirin  -  originaly written
82 *****************************************************************************/
83 
84 #ifndef __NLM_THREAD__
85 #define __NLM_THREAD__
86 
87 #include <ncbistd.h>
88 
89 #undef NLM_EXTERN
90 #ifdef NLM_IMPORT
91 #define NLM_EXTERN NLM_IMPORT
92 #else
93 #define NLM_EXTERN extern
94 #endif
95 
96 #ifdef __cplusplus
97 extern "C" {
98 #endif /* __cplusplus */
99 
100 
101 /****************************************************************************/
102 /* TYPEDEFS */
103 /****************************************************************************/
104 
105 typedef Nlm_VoidPtr TNlmThread;         /* handle(id) of the thread */
106 
107 #define NULL_thread ((TNlmThread)0) /* for error handling */
108 
109 typedef Nlm_VoidPtr TNlmSemaphore;      /* handle (id) of the semaphore */
110 
111 struct TNlmRWlockTag;                         /* internal RW-lock storage  */
112 typedef struct TNlmRWlockTag PNTR TNlmRWlock; /* handle(id) of the RW-lock */
113 typedef TNlmRWlock PNTR TNlmRWlockPtr;        /* pointer to RW-lock handle */
114 
115 struct TNlmMutexTag;                        /* internal mutex storage  */
116 typedef struct TNlmMutexTag PNTR TNlmMutex; /* handle(id) of the mutex */
117 typedef TNlmMutex PNTR TNlmMutexPtr;        /* pointer to mutex handle */
118 
119 struct TNlmTlsTag;                      /* hidden internal TLS structure */
120 typedef struct TNlmTlsTag PNTR TNlmTls; /* handle(id) of the mutex       */
121 typedef TNlmTls PNTR TNlmTlsPtr;        /* pointer to mutex handle       */
122 
123 /* pointer to the thread function */
124 typedef Nlm_VoidPtr (*TNlmThreadStart)(Nlm_VoidPtr arg);
125 
126 /* pointer to the thread finishing function */
127 typedef void (*TNlmThreadOnExit)(Nlm_VoidPtr user_arg);
128 
129 
130 /****************************************************************************/
131 /* FINCTION DEFINITIONS */
132 /****************************************************************************/
133 
134 /*
135  *  Auxiliary function to be used in the NlmThreadAddOnExit()
136  *  function call to provide memory deallocation on the thread exit
137  */
138 NLM_EXTERN void NlmThreadMemFree(Nlm_VoidPtr ptr);
139 
140 
141 /* --------------------  NlmThreadAddOnExit  ----------------------
142    Purpose:     Adds a function to be called on the thread termination
143    Parameters:  The function "func" will be called with the "arg" argument
144                 when the thread is terminating;  then, the later registered
145                 "destroying function" will be called earlier (LIFO order)
146    Returns:     TRUE on success...
147    NOTE:        Must be called from inside the thread
148   ------------------------------------------------------------------*/
149 NLM_EXTERN Nlm_Boolean NlmThreadAddOnExit(TNlmThreadOnExit func, Nlm_VoidPtr arg);
150 
151 
152 /* --------------------  NlmThreadRemoveOnExit  -------------------
153    Purpose:     Removes the thread's termination function(s)
154    Description: This function removes all previosly registered(for this
155                 thread) terminating functions whose attributes
156                 matches both "func" and "arg"
157    NOTE:        Must be called from inside the thread
158   ------------------------------------------------------------------*/
159 NLM_EXTERN void NlmThreadRemoveOnExit(TNlmThreadOnExit func, Nlm_VoidPtr arg);
160 
161 
162 /* --------------------  NlmThreadCreate  ---------------------------
163    Purpose:     To create new thread
164    Parameters:  theStartFunction - address of the thread function
165                 *arg             - arguments for the new thread
166    Returns:     New thread handle. Will be used to identify the thread.
167    Description: This function creates new thread - independent process
168                 inside current process, that share most resources of the
169                 parent thread.
170   ------------------------------------------------------------------*/
171 NLM_EXTERN TNlmThread NlmThreadCreate(TNlmThreadStart theStartFunction, Nlm_VoidPtr arg);
172 
173 
174 /* --------------------  NlmThreadCreateEx  -------------------------
175    Purpose:     To create new thread
176    Parameters:  "theStartFunction", "arg"  -- see NlmThreadCreate;
177                 "flags" bit mask of {THREAD_RUN, THREAD_BOUND, THREAD_DETACHED}
178                 "priority" -- specifies the thread's relative priority;
179                 "exit_func", "exit_arg"  -- these two allow one to add a
180                 function to be called when the thread is exiting -- it's
181                 the only convenient way to do this from outside of thread
182                 (see also the NlmThreadAddOnExit() function to get know
183                 how to do it from the thread's inside).
184    Description: This is an extendend version of NlmThreadCreate()
185    NOTE:        It's guaranteed that the "exit_func"(if non-NULL) will
186                 be called *after* any other exit function specified
187                 from inside the thread
188    HINTS:       THREAD_BOUND    may not be supported on OSF1 and IRIX
189                 THREAD_DETACHED may not be supported on OSF1
190                 Priorities may not be supported for POSIX threads on Solaris
191   ------------------------------------------------------------------*/
192 #define THREAD_RUN      0x0  /* default == { unbound & joinable }           */
193 #define THREAD_BOUND    0x1  /* run the thread bound to an LPW (UNIX only)  */
194 #define THREAD_DETACHED 0x2  /* run the thread detached(note: non-joinable) */
195 
196 typedef enum { /* NOTE:  priority doesn't apply to "bound" threads on UNIX */
197   eTP_Idle,
198   eTP_Lowest,
199   eTP_Low,
200   eTP_Normal,
201   eTP_High,
202   eTP_Highest,
203   eTP_Default
204 } EThreadPriority;
205 
206 NLM_EXTERN TNlmThread NlmThreadCreateEx(TNlmThreadStart theStartFunction, Nlm_VoidPtr arg, Nlm_Int4 flags, EThreadPriority priority, TNlmThreadOnExit exit_func, Nlm_VoidPtr exit_arg);
207 
208 
209 /* ----------------------  NlmThreadSelf  --------------------------
210    Purpose:     To get thread handle
211    Returns:     the thread's handle(NULL on error)
212    Description: NlmThreadSelf() returns the handle of the calling thread
213   -----------------------------------------------------------------*/
214 NLM_EXTERN TNlmThread NlmThreadSelf(void);
215 
216 
217 /* ----------------------  NlmThreadCompare  --------------------------
218    Purpose:     To compare 2 threads
219    Parameters:  Thread handles to compare
220    Returns:     TRUE if the 2 threads are identical
221    Description: In OSF1 thread ID is structure and must be compared
222                 in different way
223   -----------------------------------------------------------------*/
224 NLM_EXTERN Nlm_Boolean NlmThreadCompare(TNlmThread thread1, TNlmThread thread2);
225 
226 
227 /* ----------------------  NlmThreadJoin  --------------------------
228    Purpose:     Wait for thread termination
229    Parameters:  INPUT:  "wait_for" -- thread handle to wait for termination
230                 OUTPUT: "status"   -- the thread's exit status
231    Returns:     zero value on success;  non-zero value on error
232    Description: Blocks the calling thread until the thread specified by
233                 wait_for terminates. The specified thread must be in the
234                 current process.
235    NOTE:        Multiple threads cannot wait for the same thread to
236                 terminate. One thread will return successfully and the
237                 others will fail.
238                 On WIN32, if a thread is not joined using this function
239                 it lead to a minor resource leak
240   -----------------------------------------------------------------*/
241 NLM_EXTERN Nlm_Int4 NlmThreadJoin(TNlmThread wait_for, Nlm_VoidPtr *status);
242 
243 
244 /* ----------------------  NlmThreadJoinAll  -----------------------
245    Purpose:     Wait for termination of all threads presently running
246                 in the current process
247    Returns:     zero value on success;  non-zero value on error
248    NOTE:        joins only the threads created by NlmThreadCreate[Ex]
249                 and exited with the NlmThreadExit() or due to the
250                 normal return from the main thread function;
251                 deadlocks if called *not* from the main thread!
252   -----------------------------------------------------------------*/
253 NLM_EXTERN Nlm_Int4 NlmThreadJoinAll(void);
254 
255 
256 /* -------------------  NlmThreadExit  ------------------------------
257    Purpose:      To terminate the calling thread
258    Parameters:   status - exit data(code) for the calling thread
259    Description:  This function terminates th calling thread. All thread-
260                  specific data bindings are released. If the initial thread
261                  returns from main() then the process exits with a status
262                  equal to the return value
263    -----------------------------------------------------------------*/
264 NLM_EXTERN void NlmThreadExit(Nlm_VoidPtr status);
265 
266 
267 /********************************************************************/
268 /*                                                                  */
269 /* =========== Semaphore support for the thread API library ======= */
270 /*                                                                  */
271 /********************************************************************/
272 
273 
274 /* ---------------------  NlmSemaInit  ------------------------------
275    Purpose:     To create new semaphore
276    Parameters:  count - number of threads that may use semaphore in parallel
277    Returns:     Semaphore handle
278    Description: To create new semaphore with "count" simultaneous accesses.
279    NOTE:        This semaphore can be used to synchronize threads in this
280                 process only
281    -----------------------------------------------------------------*/
282 NLM_EXTERN TNlmSemaphore NlmSemaInit(Nlm_Uint4 count);
283 
284 
285 /* ---------------------  NlmSemaDestroy  ---------------------------
286    Purpose:     To destroy specified semaphore.
287    Parameters:  theSemaphore - handle of the semaphore
288    Returns:     Zero on success;  non-zero value on error
289    Description: destroys any state associated with the semaphore pointed
290                 to by theSemaphore
291    -----------------------------------------------------------------*/
292 NLM_EXTERN Nlm_Int4 NlmSemaDestroy(TNlmSemaphore theSemaphore);
293 
294 
295 /* ---------------------  NlmSemaWait  ------------------------------
296    Purpose:      To wait until semaphore is not zero.
297    Parameters:   theSemaphore - handle of the semaphore
298    Returns:      Zero on success;  non-zero value on error
299    Descrription: Blocks the calling thread until the count in the
300                  semaphore pointed by theSemaphore becomes greater than zero
301                  and then atomically decrements it
302    -----------------------------------------------------------------*/
303 NLM_EXTERN Nlm_Int4 NlmSemaWait(TNlmSemaphore theSemaphore);
304 
305 
306 /* ---------------------  NlmSemaTryWait  ---------------------------
307    Purpose:      To poll semaphore status
308    Parameters:   theSemaphore - handle of the semaphore to poll
309    Returns:      Zero on success;  non-zero value on error
310    Description:  atomically decrements the count in the semaphore
311                  pointed to by theSemaphore if the count is greater
312                  than zero. Otherwise it returns an error.
313   -----------------------------------------------------------------*/
314 NLM_EXTERN Nlm_Int4 NlmSemaTryWait(TNlmSemaphore theSemaphore);
315 
316 
317 /* ---------------------  NlmSemaPost  ------------------------------
318    Purpose:      To increase the count of semaphore by one
319    Parameters:   theSemaphore - handle of the semaphore to post
320    Returns:      Zero on success;  non-zero value on error
321    Description:  atomically increments the count semaphore pointed to by
322                  theSemaphore, one is unblocked.
323    -----------------------------------------------------------------*/
324 NLM_EXTERN Nlm_Int4 NlmSemaPost(TNlmSemaphore theSemaphore);
325 
326 
327 /********************************************************************/
328 /*                                                                  */
329 /* === Semaphore-like object to keep read/write syncronization ==== */
330 /*                                                                  */
331 /********************************************************************/
332 
333 /* [POSIX and WIN32]  Nested locking policy:
334  *   W after R -- never allowed;
335  *   W after W -- allowed if the W-lock is owned by the same thread;
336  *   R after W -- allowed if the W-lock is owned by the same thread (and,
337  *                then this R is treated as if it was W);
338  *   R after R -- always allowed (unless there already was a "R after W"
339  *                performed in another thread)
340  *   U after W -- only if the W-lock is owned by the same thread
341  */
342 
343 
344 /* Do not pass the file name in the non-debug mode to avoid having
345  * numerous strings in the static data segment.
346  */
347 #if defined(_DEBUG)
348 #  define RW_FILE __FILE__
349 #else
350 #  define RW_FILE 0
351 #endif
352 #define RW_LINE __LINE__
353 
354 
355 /* ---------------------  NlmRWlock  --------------------------------
356    Purpose:  Initialize readers/writer lock
357    Returns:  Handle of the new RW-lock(NULL on error)
358    NOTE:     Readers/writer locks MUST be initialized before use.
359    -----------------------------------------------------------------*/
360 NLM_EXTERN TNlmRWlock NlmRWinit(void);
361 
362 
363 /* ---------------------  NlmRWdestroy  -----------------------------
364    Purpose:      Destroy RW-lock
365    Parameters:   Handle of RW-lock
366    Returns:      Zero on success;  non-zero value on error
367    Description:  Destroys any state associated with the RW lock
368                  pointed to by RW.
369   -----------------------------------------------------------------*/
370 NLM_EXTERN Nlm_Int4 NlmRWdestroy(TNlmRWlock RW);
371 
372 
373 /* ---------------------  NlmRWrdlock  ------------------------------
374    Purpose:      Acquire a read lock
375    Parameters:   Handle of RW-lock
376    Returns:      Zero on success;  non-zero value on error
377    Description:  Acquires a read lock on the readers/writer lock
378                  pointed to by RW. If the RW lock is already
379                  locked for writing, the calling thread blocks until
380                  the write lock is released.
381    NOTE:         More than one thread may hold a read lock on a RW lock
382                  at any one time.
383   -----------------------------------------------------------------*/
384 NLM_EXTERN Nlm_Int4 NlmRWrdlockEx(TNlmRWlock RW,
385                               const char* file, int line);
386 #define NlmRWrdlock(RW)  NlmRWrdlockEx(RW, RW_FILE, RW_LINE)
387 
388 
389 /* ---------------------  NlmRWwrlock  ------------------------------
390    Purpose:      Acquire a write lock
391    Parameters:   Handle of RW-lock
392    Returns:      Zero on success;  non-zero value on error
393    Description:  Acquires a write lock on the readers/writer lock
394                  pointed to by RW. If the RW lock is already
395                  locked for reading or writing, the calling thread blocks
396                  until the lock is released.
397    NOTE:         Only one thread may hold a write lock on a RW lock
398                  at any one time.
399   -----------------------------------------------------------------*/
400 NLM_EXTERN Nlm_Int4 NlmRWwrlockEx(TNlmRWlock RW,
401                               const char* file, int line);
402 #define NlmRWwrlock(RW)  NlmRWwrlockEx(RW, RW_FILE, RW_LINE)
403 
404 
405 /* ---------------------  NlmRWunlock  ------------------------------
406    Purpose:      Unlock RW-lock
407    Parameters:   Handle of RW-lock
408    Returns:      Zero on success;  non-zero value on error
409    Description:  The RW-lock must be locked and the calling thread must
410                  hold the lock either for reading or for writing. If
411                  any other threads are waiting for the RW lock to become
412                  available, one of them is unblocked.
413    NOTE:         If the calling thread does not hold the lock for either
414                  reading or writing no error status is returned and the
415                  behavior of the program is undefined.
416    -----------------------------------------------------------------*/
417 NLM_EXTERN Nlm_Int4 NlmRWunlockEx(TNlmRWlock RW,
418                               const char* file, int line);
419 #define NlmRWunlock(RW)  NlmRWunlockEx(RW, RW_FILE, RW_LINE)
420 
421 
422 /* ---------------------  NlmRWtryrdlock  ---------------------------
423    Purpose:      Try to acquire a read lock
424    Parameters:   Handle of RW-lock
425    Returns:      Zero on success;  non-zero value on error
426    Description:  Attempts to acquire a read lock on the RW-lock
427                  pointed to by RW. If the RW-lock is already
428                  locked for writing, it returns an error. Otherwise
429                  the read lock is acquired
430    -----------------------------------------------------------------*/
431 NLM_EXTERN Nlm_Int4 NlmRWtryrdlockEx(TNlmRWlock RW,
432                                  const char* file, int line);
433 #define NlmRWtryrdlock(RW)  NlmRWtryrdlockEx(RW, RW_FILE, RW_LINE)
434 
435 
436 /* ---------------------  NlmRWtrywrlock  ---------------------------
437    Purpose:       Try to acquire a write lock
438    Parameters:    Handle of RW-lock
439    Returns:       Zero on success;  non-zero value on error
440    Description:   Attempts to acquire a write lock on the RW lock
441                   pointed to by RW. If the RW-lock is already
442                   locked for reading or writing, it returnes an error.
443                   Otherwise the write lock is acquired
444    -----------------------------------------------------------------*/
445 NLM_EXTERN Nlm_Int4 NlmRWtrywrlockEx(TNlmRWlock RW,
446                                  const char* file, int line);
447 #define NlmRWtrywrlock(RW)  NlmRWtrywrlockEx(RW, RW_FILE, RW_LINE)
448 
449 
450 /* ---------------------  NlmRWprintout  ---------------------------
451    Purpose:       Printout the latest RW-lock activity
452    Parameters:    Handle of RW-lock
453    Returns:       non-NULL dynamically allocated string (caller must free it)
454    Description:   Print the latest RW-lock activity (starting from the
455                   latest "Unlocked" state), if the "ncbithr.c" was compiled
456                   in the RW-lock history tracking mode.
457                   Otherwise, just print the current state of RW-lock.
458    -----------------------------------------------------------------*/
459 NLM_EXTERN char* NlmRWprintout(TNlmRWlock RW);
460 
461 
462 
463 /********************************************************************
464  * === MUTEXes ====================================================
465  *
466  * Description: Mutual exclusion locks (mutexes)  prevent  multiple
467  *              threads from  simultaneously  executing  critical
468  *              sections  of code which access shared data (i.e.,
469  *              mutexes are used to  serialize  the execution of threads).
470  * NOTE:        All mutexes MUST be global.
471  ********************************************************************/
472 
473 
474 /* ---------------------  NlmMutexInit  ------------------------------
475    Purpose:     To create and initialize mutex, if necessary
476    Parameters:  Pointer to the mutex handle
477    Returns:     New(or old -- if the referenced mutex already exists)
478                 mutex handle
479    Description: Create new mutex if it doesn's not exist(i.e. if
480                 *theMutexPtr == NULL); do nothing if it already exists.
481    NOTE:        This mutex can be used to synchronize threads in this
482                 process only.
483    -----------------------------------------------------------------*/
484 NLM_EXTERN TNlmMutex NlmMutexInit(TNlmMutexPtr theMutexPtr);
485 
486 
487 /* ---------------------  NlmMutexLock  ------------------------------
488    Purpose:      To lock mutex.  Block the calling thread if mutex is busy.
489    Parameters:   theMutex -- handle of the mutex
490    Returns:      Zero on success;  non-zero value on error
491    Description:  Blocks code access
492    -----------------------------------------------------------------*/
493 NLM_EXTERN Nlm_Int4 NlmMutexLock (TNlmMutex theMutex);
494 
495 
496 /* ---------------------  NlmMutexTryLock  ------------------------------
497    Purpose:      Try to poll mutex.  Don't block the calling thread.
498    Parameters:   theMutex -- handle of the mutex
499    Returns:      Zero on success;  non-zero value if already locked
500                  by another thread
501    Description:  Poll condition of mutex -- do not block if mutex busy
502    -----------------------------------------------------------------*/
503 NLM_EXTERN Nlm_Int4 NlmMutexTryLock(TNlmMutex theMutex);
504 
505 
506 /* ---------------------  NlmMutexLockEx  ----------------------------
507    Purpose:      To lock mutex(initialize it, if necessary)
508    Parameters:   theMutex -- handle of the mutex
509    Returns:      Zero on success;  non-zero value on error
510    Description:  Blocks code access
511    -----------------------------------------------------------------*/
512 NLM_EXTERN Nlm_Int4 NlmMutexLockEx(TNlmMutexPtr theMutexPtr);
513 
514 
515 /* ---------------------  NlmMutexTryLockEx  ----------------------------
516    Purpose:      To try lock mutex(initialize it, if necessary)
517    Parameters:   theMutex -- handle of the mutex
518    Returns:      Zero on success;  non-zero value  if already locked
519                  by another thread
520    Description:  Poll condition of mutex -- do not block if mutex busy
521    -----------------------------------------------------------------*/
522 NLM_EXTERN Nlm_Int4 NlmMutexTryLockEx(TNlmMutexPtr theMutexPtr);
523 
524 
525 /* ---------------------  NlmMutexUnlock  ------------------------------
526    Purpose:      To unlock mutex
527    Parameters:   theMutex - handle of the mutex
528    Returns:      Zero on success;  non-zero value on error
529    Description:  Unblocks code access
530    -----------------------------------------------------------------*/
531 NLM_EXTERN Nlm_Int4 NlmMutexUnlock(TNlmMutex theMutex);
532 
533 
534 /* ---------------------  NlmMutexDestroy ------------------------------
535    Purpose:      To destroy mutex
536    Parameters:   theMutex - handle of the mutex
537    Returns:      Zero on success;  non-zero value on error
538    Description:  Remove the mutex from execution
539    -----------------------------------------------------------------*/
540 NLM_EXTERN Nlm_Int4 NlmMutexDestroy(TNlmMutex theMutex);
541 
542 
543 /********************************************************************
544  * === TLS (Thread Local Storage)  ==================================
545  *
546  * NOTE:  All TLSs MUST be global and belong to the same process
547  * NOTE:  Even if there are no real threads engaged, the TLS would
548  *        work properly -- just as if the "main()" was a thread
549  ********************************************************************/
550 
551 
552 /* ---------------------  NlmTlsSetValue  --------------------------
553    Purpose:     Set TLS value and its cleanup function; initialize TLS
554                 if the passed handle is NULL
555    Parameters:  "pTLS" -- ptr. to the TLS handle;  "value" -- the value to set;
556    		       "cleanup" -- to be called(with the thread's old TLS
557                 value) if the value is changed or the thread is finished.
558    Returns:     TRUE on success, FALSE on error
559    NOTE 1:      do nothing(and ret. TRUE) if new value is equal to the old one
560    NOTE 2:      inside the "cleanup" function: the new value is set
561                 already, and NlmTls[SG]etValue(...) are safe to call
562    -----------------------------------------------------------------*/
563 typedef void (*TNlmTlsCleanup)(TNlmTls TLS, Nlm_VoidPtr old_value);
564 NLM_EXTERN Nlm_Boolean NlmTlsSetValue(TNlmTls *pTLS, Nlm_VoidPtr value, TNlmTlsCleanup cleanup);
565 
566 
567 /* ---------------------  NlmTlsSetValue  --------------------------
568    Purpose:     Get TLS value
569    Parameters:  "TLS"       -- handle of the TLS,
570                 "value_ptr" -- pointer to location where to store
571                                the TLS value
572    Returns:     TRUE on success, FALSE on error
573    NOTE:        Return value_ptr = NULL if the specified value has not
574                 yet been set(by NlmTlsSetValue) in this thread, or
575                 if the TLS has not been initialized yet(NULL TLS handle)
576    -----------------------------------------------------------------*/
577 NLM_EXTERN Nlm_Boolean NlmTlsGetValue(TNlmTls TLS, Nlm_VoidPtr *value_ptr);
578 
579 
580 /********************************************************************
581  * === Auxiliaries  =================================================
582  ********************************************************************/
583 
584 /* ---------------------  NlmThreadsAvailable -----------------------
585    Purpose:      Check to see if threads are available on this platform
586    Returns:      TRUE if threads are available, FALSE otherwise
587    Description:  Check to see if threads are available on this platform
588    -----------------------------------------------------------------*/
589 NLM_EXTERN Nlm_Boolean NlmThreadsAvailable(void);
590 
591 
592 /* ---------------------  NlmCPUNumber ------------------------------
593    Purpose:      To get number of CPU on machine
594    Returns:      Number of CPU
595    -----------------------------------------------------------------*/
596 NLM_EXTERN Nlm_Int4 NlmCPUNumber(void);
597 
598 
599 /********************************************************************
600  * === CoreLib internals
601  ********************************************************************/
602 
603 /* Joins all NCBI threads, then clean/destroy all internal thread
604  * library data(including TLSs and their cleanups); can be called
605  * from the main thread only.
606  * NOTE: for internal use only! must be called in the very end of the
607  * program execution; no NCBI thread library functions can be called
608  * after the call to this function!
609  */
610 NLM_EXTERN void NlmThreadDestroyAll(void);
611 
612 
613 #ifdef __cplusplus
614 }
615 #endif /* __cplusplus */
616 
617 
618 #undef NLM_EXTERN
619 #ifdef NLM_EXPORT
620 #define NLM_EXTERN NLM_EXPORT
621 #else
622 #define NLM_EXTERN
623 #endif
624 
625 #endif /* __NLM_THREAD__ */
626 
627 /*EOF*/
628 
629