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