1 /* 2 * Copyright (c) 2012 The Native Client Authors. All rights reserved. 3 * Use of this source code is governed by a BSD-style license that can be 4 * found in the LICENSE file. 5 */ 6 7 /** @file 8 * Defines the API in the 9 * <a href="group___pthread.html">Pthread library</a> 10 * 11 * @addtogroup Pthread 12 * @{ 13 */ 14 15 #ifndef _PTHREAD_H 16 #define _PTHREAD_H 1 17 18 #include <stdint.h> 19 #include <sched.h> 20 #include <time.h> 21 #include <sys/nacl_nice.h> 22 #include <sys/types.h> 23 24 /* 25 * Signed 32-bit integer supporting CompareAndSwap and AtomicIncrement 26 * (see implementations), as well as atomic loads and stores. 27 * Instances must be naturally aligned. 28 */ 29 typedef int AtomicInt32; 30 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 35 struct timespec; 36 struct __nc_basic_thread_data; 37 38 /** Mutex type attributes */ 39 enum { 40 /** Fast mutex type; for use with pthread_mutexattr_settype() */ 41 PTHREAD_MUTEX_FAST_NP, 42 /** Recursive mutex type; for use with pthread_mutexattr_settype() */ 43 PTHREAD_MUTEX_RECURSIVE_NP, 44 /** Error-checking mutex type; for use with pthread_mutexattr_settype() */ 45 PTHREAD_MUTEX_ERRORCHECK_NP, 46 PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP, 47 PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP, 48 PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP, 49 50 PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL 51 }; 52 53 /* 54 * The layout of pthread_mutex_t and the static initializers are redefined 55 * in newlib's sys/lock.h file (including this file from sys/lock.h will 56 * cause include conflicts). When changing one of the definitions, make sure to 57 * change the second one. 58 */ 59 /** 60 * A structure representing a thread mutex. It should be considered an 61 * opaque record; the names of the fields can change anytime. 62 */ 63 typedef struct { 64 /* 65 * mutex_state is either UNLOCKED (0), LOCKED_WITHOUT_WAITERS (1) or 66 * LOCKED_WITH_WAITERS (2). See "enum MutexState". 67 */ 68 volatile int mutex_state; 69 70 /** 71 * The kind of mutex: 72 * PTHREAD_MUTEX_FAST_NP, PTHREAD_MUTEX_RECURSIVE_NP, 73 * or PTHREAD_MUTEX_ERRORCHECK_NP 74 */ 75 int mutex_type; 76 77 /** 78 * ID of the thread that owns the mutex. This is volatile because 79 * it is accessed concurrently, and "volatile" is a way to make 80 * loads and stores atomic in PNaCl. 81 */ 82 struct __nc_basic_thread_data *volatile owner_thread_id; 83 84 /** Recursion depth counter for recursive mutexes */ 85 uint32_t recursion_counter; 86 87 /* 88 * Padding is for compatibility with libraries (newlib etc.) that 89 * were built before libpthread switched to using futexes, and to 90 * match _LOCK_T in newlib's newlib/libc/include/sys/lock.h. 91 */ 92 int unused_padding; 93 } pthread_mutex_t; 94 95 /** 96 * A structure representing mutex attributes. It should be considered an 97 * opaque record and accessed only using pthread_mutexattr_settype(). 98 */ 99 typedef struct { 100 /** 101 * The kind of mutex: 102 * PTHREAD_MUTEX_FAST_NP, PTHREAD_MUTEX_RECURSIVE_NP, 103 * or PTHREAD_MUTEX_ERRORCHECK_NP 104 */ 105 int kind; 106 } pthread_mutexattr_t; 107 108 /** 109 * A structure representing a condition variable. It should be considered an 110 * opaque record; the names of the fields can change anytime. 111 */ 112 typedef struct { 113 /* This is incremented on each pthread_cond_signal/broadcast() call. */ 114 int sequence_number; 115 116 /* 117 * Padding is for compatibility with libraries (newlib etc.) that 118 * were built before libpthread switched to using futexes. 119 */ 120 int unused_padding; 121 } pthread_cond_t; 122 123 /** 124 * A structure representing condition variable attributes. Currently 125 * Native Client condition variables have no attributes. 126 */ 127 typedef struct { 128 int dummy; /**< Reserved; condition variables don't have attributes */ 129 } pthread_condattr_t; 130 131 /** 132 * A structure representing a rwlock. It should be considered an 133 * opaque record; the names of the fields can change anytime. 134 */ 135 typedef struct { 136 pthread_mutex_t mutex; /* mutex for all values in the structure */ 137 int reader_count; 138 int writers_waiting; 139 struct __nc_basic_thread_data *writer_thread_id; 140 pthread_cond_t read_possible; 141 pthread_cond_t write_possible; 142 } pthread_rwlock_t; 143 144 /** 145 * A structure representing rwlock attributes. It should be considered an 146 * opaque record. 147 */ 148 typedef struct { 149 int dummy; /**< Reserved; rwlocks don't have attributes */ 150 } pthread_rwlockattr_t; 151 152 /** Illegal thread ID value. */ 153 #define NACL_PTHREAD_ILLEGAL_THREAD_ID ((pthread_t) 0) 154 155 /** Statically initializes a pthread_mutex_t representing a recursive mutex. */ 156 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP \ 157 {0, PTHREAD_MUTEX_RECURSIVE, NACL_PTHREAD_ILLEGAL_THREAD_ID, 0, 0} 158 /** Statically initializes a pthread_mutex_t representing a fast mutex. */ 159 #define PTHREAD_MUTEX_INITIALIZER \ 160 {0, PTHREAD_MUTEX_NORMAL, NACL_PTHREAD_ILLEGAL_THREAD_ID, 0, 0} 161 /** 162 * Statically initializes a pthread_mutex_t representing an 163 * error-checking mutex. 164 */ 165 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP \ 166 {0, PTHREAD_MUTEX_ERRORCHECK, NACL_PTHREAD_ILLEGAL_THREAD_ID, 0, 0} 167 /** Statically initializes a condition variable (pthread_cond_t). */ 168 #define PTHREAD_COND_INITIALIZER {0, 0} 169 /** Statically initializes a rwlock (pthread_rwlock_t). */ 170 #define PTHREAD_RWLOCK_INITIALIZER \ 171 {PTHREAD_MUTEX_INITIALIZER, 0, 0, NACL_PTHREAD_ILLEGAL_THREAD_ID, \ 172 PTHREAD_COND_INITIALIZER, PTHREAD_COND_INITIALIZER} 173 174 #define PTHREAD_PROCESS_PRIVATE 0 175 #define PTHREAD_PROCESS_SHARED 1 176 177 178 /* Functions for mutex handling. */ 179 180 /** 181 * @nqPosix 182 * Initializes a mutex using attributes in mutex_attr, or using the 183 * default values if the latter is NULL. 184 * 185 * @linkPthread 186 * 187 * @param mutex The address of the mutex structure to be initialized. 188 * @param mutex_attr The address of the attributes structure. 189 * 190 * @return 0 upon success, 1 otherwise 191 */ 192 int pthread_mutex_init(pthread_mutex_t *mutex, 193 const pthread_mutexattr_t *mutex_attr); 194 195 /** 196 * @nqPosix 197 * Destroys a mutex. 198 * 199 * @linkPthread 200 * 201 * @param mutex The address of the mutex structure to be destroyed. 202 * 203 * @return 0 upon success, non-zero error code otherwise 204 */ 205 int pthread_mutex_destroy(pthread_mutex_t *mutex); 206 207 /** 208 * @nqPosix 209 * Tries to lock a mutex. 210 * 211 * @linkPthread 212 * 213 * @param mutex The address of the mutex structure to be locked. 214 * 215 * @return 0 upon success, EBUSY if the mutex is locked by another thread, 216 * non-zero error code otherwise. 217 */ 218 int pthread_mutex_trylock(pthread_mutex_t *mutex); 219 220 /** 221 * @nqPosix 222 * Locks a mutex. 223 * 224 * @linkPthread 225 * 226 * @param mutex The address of the mutex structure to be locked. 227 * 228 * @return 0 upon success, non-zero error code otherwise. 229 */ 230 int pthread_mutex_lock(pthread_mutex_t *mutex); 231 232 /* Wait until lock becomes available, or specified time passes. */ 233 int pthread_mutex_timedlock(pthread_mutex_t *mutex, 234 const struct timespec *abstime); 235 236 /** 237 * @nqPosix 238 * Unlocks a mutex. 239 * 240 * @linkPthread 241 * 242 * @param mutex The address of the mutex structure to be unlocked. 243 * 244 * @return 0 upon success, non-zero error code otherwise. 245 */ 246 int pthread_mutex_unlock(pthread_mutex_t *mutex); 247 248 /* Mutex attributes manipulation */ 249 250 /** 251 * @nqPosix 252 * Initializes mutex attributes. 253 * 254 * @linkPthread 255 * 256 * @param attr The address of the attributes structure to be initialized. 257 * 258 * @return 0. 259 */ 260 int pthread_mutexattr_init(pthread_mutexattr_t *attr); 261 262 /** 263 * @nqPosix 264 * Destroys mutex attributes structure. 265 * 266 * @linkPthread 267 * 268 * @param attr The address of the attributes structure to be destroyed. 269 * 270 * @return 0. 271 */ 272 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr); 273 274 /** 275 * @nqPosix 276 * Sets the mutex type: fast, recursive or error-checking. 277 * 278 * @linkPthread 279 * 280 * @param attr The address of the attributes structure. 281 * @param kind PTHREAD_MUTEX_FAST_NP, PTHREAD_MUTEX_RECURSIVE_NP or 282 * PTHREAD_MUTEX_ERRORCHECK_NP. 283 * 284 * @return 0 on success, -1 for illegal values of kind. 285 */ 286 int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int kind); 287 288 /** 289 * @nqPosix 290 * Gets the mutex type: fast, recursive or error-checking. 291 * 292 * @linkPthread 293 * 294 * @param attr The address of the attributes structure. 295 * @param kind Pointer to the location where the mutex kind value is copied. 296 * 297 * @return 0. 298 */ 299 int pthread_mutexattr_gettype(const pthread_mutexattr_t *attr, int *kind); 300 301 int pthread_mutexattr_getpshared(const pthread_mutexattr_t *attr, int *pshared); 302 303 int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared); 304 305 /* Functions for handling conditional variables. */ 306 307 /** 308 * @nqPosix 309 * Initializes a condition variable. 310 * 311 * @linkPthread 312 * 313 * @param cond Pointer to the condition variable structure. 314 * @param cond_attr Pointer to the attributes structure, should be NULL as 315 * Native Client does not support any attributes for a condition variable at 316 * this stage. 317 * 318 * @return 0 for success, 1 otherwise. 319 */ 320 int pthread_cond_init(pthread_cond_t *cond, 321 const pthread_condattr_t *cond_attr); 322 323 /** 324 * @nqPosix 325 * Destroys a condition variable. 326 * 327 * @linkPthread 328 * 329 * @param cond Pointer to the condition variable structure. 330 * 331 * @return 0 for success, non-zero error code otherwise. 332 */ 333 int pthread_cond_destroy(pthread_cond_t *cond); 334 335 /** 336 * @nqPosix 337 * Signals a condition variable, waking up one of the threads waiting on it. 338 * 339 * @linkPthread 340 * 341 * @param cond Pointer to the condition variable structure. 342 * 343 * @return 0 for success, non-zero error code otherwise. 344 */ 345 int pthread_cond_signal(pthread_cond_t *cond); 346 347 /** 348 * @nqPosix 349 * Wakes up all threads waiting on a condition variable. 350 * 351 * @linkPthread 352 * 353 * @param cond Pointer to the condition variable structure. 354 * 355 * @return 0 for success, non-zero error code otherwise. 356 */ 357 int pthread_cond_broadcast(pthread_cond_t *cond); 358 359 /** 360 * @nqPosix 361 * Waits for a condition variable to be signaled or broadcast. 362 * 363 * @linkPthread 364 * 365 * @param cond Pointer to the condition variable structure. 366 * @param mutex Pointer to the mutex structure. The mutex is assumed to be 367 * locked when this function is called. 368 * 369 * @return 0 for success, non-zero error code otherwise. 370 */ 371 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); 372 373 /** 374 * @nqPosix 375 * Waits for condition variable cond to be signaled or broadcast until 376 * abstime. 377 * 378 * @linkPthread 379 * 380 * @param cond Pointer to the condition variable structure. 381 * @param mutex Pointer to the mutex structure. The mutex is assumed to be 382 * locked when this function is called. 383 * @param abstime Absolute time specification; zero is the beginning of the 384 * epoch (00:00:00 GMT, January 1, 1970). 385 * 386 * @return 0 for success, non-zero error code otherwise. 387 */ 388 int pthread_cond_timedwait_abs(pthread_cond_t *cond, 389 pthread_mutex_t *mutex, 390 const struct timespec *abstime); 391 392 /** 393 * @nqPosix 394 * Waits for condition variable cond to be signaled or broadcast; wait time is 395 * limited by reltime. 396 * 397 * @linkPthread 398 * 399 * @param cond Pointer to the condition variable structure. 400 * @param mutex Pointer to the mutex structure. The mutex is assumed to be 401 * locked when this function is called. 402 * @param reltime Time specification, relative to the current time. 403 * 404 * @return 0 for success, non-zero error code otherwise. 405 */ 406 int pthread_cond_timedwait_rel(pthread_cond_t *cond, 407 pthread_mutex_t *mutex, 408 const struct timespec *reltime); 409 410 /** 411 * Defined for POSIX compatibility; pthread_cond_timedwait() is actually 412 * a macro calling pthread_cond_timedwait_abs(). 413 */ 414 #define pthread_cond_timedwait pthread_cond_timedwait_abs 415 416 /* Condition variable attributes manipulation */ 417 418 int pthread_condattr_init(pthread_condattr_t *attr); 419 420 int pthread_condattr_destroy(pthread_condattr_t *attr); 421 422 int pthread_condattr_getpshared(const pthread_condattr_t *attr, int *pshared); 423 424 int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared); 425 426 int pthread_condattr_getclock(const pthread_condattr_t *attr, 427 clockid_t *clock_id); 428 429 int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id); 430 431 /* Functions for rwlock handling. */ 432 433 int pthread_rwlockattr_init(pthread_rwlockattr_t *attr); 434 int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, 435 int *pshared); 436 int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared); 437 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr); 438 439 int pthread_rwlock_init(pthread_rwlock_t *rwlock, 440 const pthread_rwlockattr_t *attr); 441 442 int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); 443 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock); 444 int pthread_rwlock_timedrdlock(pthread_rwlock_t *rwlock, 445 const struct timespec *abstime); 446 447 448 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); 449 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock); 450 int pthread_rwlock_timedwrlock(pthread_rwlock_t *rwlock, 451 const struct timespec *abstime); 452 453 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); 454 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); 455 456 457 /* Threads */ 458 /** Thread identifier type. */ 459 typedef struct __nc_basic_thread_data *pthread_t; 460 461 /** A structure representing thread attributes. */ 462 typedef struct { 463 int joinable; /**< 1 if the thread is joinable, 0 otherwise */ 464 size_t stacksize; /**< The requested thread stack size in bytes. */ 465 } pthread_attr_t; 466 467 468 /** Joinable thread type; for use with pthread_attr_setdetachstate(). */ 469 #define PTHREAD_CREATE_JOINABLE 1 470 /** Detached thread type; for use with pthread_attr_setdetachstate(). */ 471 #define PTHREAD_CREATE_DETACHED 0 472 473 /** For use with pthread_attr_setscope(). */ 474 #define PTHREAD_SCOPE_PROCESS 0 475 /** For use with pthread_attr_setscope(). */ 476 #define PTHREAD_SCOPE_SYSTEM 1 477 478 /** Minimum stack size; for use with pthread_attr_setstacksize(). */ 479 #define PTHREAD_STACK_MIN (1024) 480 481 /* default stack size */ 482 #define PTHREAD_STACK_DEFAULT (512 * 1024) 483 484 /* Thread functions */ 485 486 /** 487 * @nqPosix 488 * Creates a thread. 489 * 490 * @linkPthread 491 * 492 * @param[out] thread_id A pointer to the location where the identifier of the 493 * newly created thread is stored on success. 494 * @param attr Thread attributes structure. 495 * @param start_routine Thread function. 496 * @param arg A single argument that is passed to the thread function. 497 * 498 * @return 0 for success, non-zero error code otherwise. 499 */ 500 int pthread_create(pthread_t *thread_id, 501 const pthread_attr_t *attr, 502 void *(*start_routine)(void *p), 503 void *arg); 504 505 /** 506 * @nqPosix 507 * Obtains the identifier of the current thread. 508 * 509 * @linkPthread 510 * 511 * @return Thread ID of the current thread. 512 */ 513 pthread_t pthread_self(void); 514 515 /** 516 * @nqPosix 517 * Compares two thread identifiers. 518 * 519 * @linkPthread 520 * 521 * @param thread1 Thread ID of thread A. 522 * @param thread2 Thread ID of thread B. 523 * 524 * @return 1 if both identifiers belong to the same thread, 0 otherwise. 525 */ 526 int pthread_equal(pthread_t thread1, pthread_t thread2); 527 528 /** 529 * @nqPosix 530 * Terminates the calling thread. 531 * 532 * @linkPthread 533 * 534 * @param retval Return value of the thread. 535 * 536 * @return The function never returns. 537 */ 538 void pthread_exit(void *retval); 539 540 /** 541 * @nqPosix 542 * Makes the calling thread wait for termination of another thread. 543 * 544 * @linkPthread 545 * 546 * @param th The identifier of the thread to wait for. 547 * @param thread_return If not NULL, points to the location where the return 548 * value of the terminated thread is stored upon completion. 549 * 550 * @return 0 on success, non-zero error code otherwise. 551 */ 552 int pthread_join(pthread_t th, void **thread_return); 553 554 /** 555 * @nqPosix 556 * Indicates that the specified thread is never to be joined with 557 * pthread_join(). The resources of that thread will therefore be freed 558 * immediately when it terminates, instead of waiting for another thread to 559 * perform pthread_join() on it. 560 * 561 * @linkPthread 562 * 563 * @param th Thread identifier. 564 * 565 * @return 0 on success, non-zero error code otherwise. 566 */ 567 int pthread_detach(pthread_t th); 568 569 /** 570 * @nqPosix 571 * Sends a signal to a thread. (Currently only a stub implementation.) 572 * 573 * @linkPthread 574 * 575 * @param thread_id The identifier of the thread to receive the signal. 576 * @param sig The signal value to send. 577 * 578 * @return 0 for success, non-zero error code otherwise. 579 */ 580 int pthread_kill(pthread_t thread_id, int sig); 581 582 /* Functions for handling thread attributes. */ 583 584 /** 585 * @nqPosix 586 * Initializes thread attributes structure attr with default attributes 587 * (detachstate is PTHREAD_CREATE_JOINABLE). 588 * 589 * @linkPthread 590 * 591 * @param attr Pointer to thread attributes structure. 592 * 593 * @return 0 on success, non-zero error code otherwise. 594 */ 595 int pthread_attr_init(pthread_attr_t *attr); 596 597 /** 598 * @nqPosix 599 * Destroys a thread attributes structure. 600 * 601 * @linkPthread 602 * 603 * @param attr Pointer to thread attributes structure. 604 * 605 * @return 0 on success, non-zero error code otherwise. 606 */ 607 int pthread_attr_destroy(pthread_attr_t *attr); 608 609 /** 610 * @nqPosix 611 * Sets the detachstate attribute in thread attributes. 612 * 613 * @linkPthread 614 * 615 * @param attr Pointer to thread attributes structure. 616 * @param detachstate Value to be set, determines whether the thread is 617 * joinable. 618 * 619 * @return 0 on success, non-zero error code otherwise. 620 */ 621 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate); 622 623 /** 624 * @nqPosix 625 * Gets the detachstate attribute from thread attributes. 626 * 627 * @linkPthread 628 * 629 * @param attr Pointer to thread attributes structure. 630 * @param detachstate Location where the value of `detachstate` is stored upon 631 * successful completion. 632 * 633 * @return 0 on success, non-zero error code otherwise. 634 */ 635 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate); 636 637 /** 638 * @nqPosix 639 * Sets the contention scope attribute in thread attributes. 640 * Native Client (like Linux) only supports PTHREAD_SCOPE_SYSTEM. 641 * 642 * @linkPthread 643 * 644 * @param attr Pointer to thread attributes structure. 645 * @param scope Value to be set, determines the contention scope of the thread. 646 * 647 * @return 0 on success, non-zero error code otherwise. 648 */ 649 int pthread_attr_setscope(pthread_attr_t *attr, int scope); 650 651 /** 652 * @nqPosix 653 * Gets the contention scope attribute from thread attributes. 654 * Native Client (like Linux) only supports PTHREAD_SCOPE_SYSTEM. 655 * 656 * @linkPthread 657 * 658 * @param attr Pointer to thread attributes structure. 659 * @param scope Location where the value of `scope` is stored upon 660 * successful completion. 661 * 662 * @return 0 on success, non-zero error code otherwise. 663 */ 664 int pthread_attr_getscope(const pthread_attr_t *attr, int *scope); 665 666 /** 667 * @nqPosix 668 * Sets the stacksize attribute in thread attributes. Has no effect if the 669 * size is less than PTHREAD_STACK_MIN. 670 * 671 * @linkPthread 672 * 673 * @param attr Pointer to thread attributes structure. 674 * @param stacksize Value to be set, determines the minimum stack size. 675 * 676 * @return 0 on success, non-zero error code otherwise. 677 */ 678 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize); 679 680 /** 681 * @nqPosix 682 * Gets the stacksize attribute in thread attributes. 683 * 684 * @linkPthread 685 * 686 * @param attr Pointer to thread attributes structure. 687 * @param stacksize Value to be set, determines the minimum stack size. 688 * 689 * @return 0 on success, non-zero error code otherwise. 690 */ 691 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize); 692 693 /** 694 * @nqPosix 695 * Gets the maximum address of the stack (assuming stacks grow 696 * downwards) of the given thread. 697 * 698 * If the given thread exits concurrently with the call to this 699 * function, the behaviour is undefined. 700 * 701 * Note that in the future this may be removed and replaced with an 702 * implementation of pthread_getattr_np(), for consistency with Linux 703 * glibc. pthread_getattr_np() + pthread_attr_getstack() return the 704 * stack base (minimum) address and stack size. However, that is 705 * currently unimplementable under NaCl, because NaCl does not provide 706 * a way to determine the initial thread's stack size. See: 707 * https://code.google.com/p/nativeclient/issues/detail?id=3431 708 */ 709 int pthread_get_stack_end_np(pthread_t tid, void **stack_end); 710 711 /* Functions for handling thread-specific data. */ 712 713 /** Thread-specific key identifier type */ 714 typedef int pthread_key_t; 715 716 /** Number of available keys for thread-specific data. */ 717 #define PTHREAD_KEYS_MAX 512 718 719 /** 720 * @nqPosix 721 * Creates a key value identifying a location in the thread-specific 722 * data area. 723 * 724 * @linkPthread 725 * 726 * @param key Pointer to the location where the value of the key is stored upon 727 * successful completion. 728 * @param destr_function Pointer to a cleanup function that is called if the 729 * thread terminates while the key is still allocated. 730 * 731 * @return 0 on success, non-zero error code otherwise. 732 */ 733 int pthread_key_create(pthread_key_t *key, void (*destr_function)(void *p)); 734 735 736 /** 737 * @nqPosix 738 * Destroys a thread-specific data key. 739 * 740 * @linkPthread 741 * 742 * @param key Key value, previously obtained using pthread_key_create(). 743 * 744 * @return 0 on success, non-zero error code otherwise. 745 */ 746 int pthread_key_delete(pthread_key_t key); 747 748 /** 749 * @nqPosix 750 * Stores a value in the thread-specific data slot identified by a key value. 751 * 752 * @linkPthread 753 * 754 * @param key Key value, previously obtained using pthread_key_create(). 755 * @param pointer The value to be stored. 756 * 757 * @return 0 on success, non-zero error code otherwise. 758 */ 759 int pthread_setspecific(pthread_key_t key, const void *pointer); 760 761 /** 762 * @nqPosix 763 * Gets the value currently stored at the thread-specific data slot 764 * identified by the key. 765 * 766 * @linkPthread 767 * 768 * @param key Key value, previously obtained using pthread_key_create(). 769 * 770 * @return The value that was previously stored using pthread_setspecific is 771 * returned on success, otherwise NULL. 772 */ 773 void *pthread_getspecific(pthread_key_t key); 774 775 /** 776 * A structure describing a control block 777 * used with the pthread_once() function. 778 * It should be considered an opaque record; 779 * the names of the fields can change anytime. 780 */ 781 typedef struct { 782 /** A flag: 1 if the function was already called, 0 if it wasn't */ 783 AtomicInt32 done; 784 785 /** Synchronization lock for the flag */ 786 pthread_mutex_t lock; 787 } pthread_once_t; 788 789 /** Static initializer for pthread_once_t. */ 790 #define PTHREAD_ONCE_INIT {0, PTHREAD_MUTEX_INITIALIZER} 791 792 /** 793 * @nqPosix 794 * Ensures that a piece of initialization code is executed at most once. 795 * 796 * @linkPthread 797 * 798 * @param __once_control Points to a static or extern variable statically 799 * initialized to PTHREAD_ONCE_INIT. 800 * @param __init_routine A pointer to the initialization function. 801 * 802 * @return 0. 803 */ 804 int pthread_once(pthread_once_t *__once_control, void (*__init_routine)(void)); 805 806 /** 807 * @nqPosix 808 * Sets the scheduling priority of a thread. 809 * 810 * @linkPthread 811 * 812 * @param thread_id Identifies the thread to operate on. 813 * @param prio Scheduling priority to apply to that thread. 814 * 815 * @return 0 on success, non-zero error code otherwise. 816 */ 817 int pthread_setschedprio(pthread_t thread_id, int prio); 818 819 /* 820 * NOTE: this is only declared here to shut up 821 * some warning in the c++ system header files. 822 * We do not define this function anywhere. 823 */ 824 825 int pthread_cancel(pthread_t th); 826 827 /* 828 * NOTE: There are only stub implementations of these functions. 829 */ 830 831 void pthread_cleanup_push(void (*func)(void *cleanup_arg), void *arg); 832 void pthread_cleanup_pop(int execute); 833 834 /** 835 * @} End of PTHREAD group 836 */ 837 838 #ifdef __cplusplus 839 } 840 #endif 841 842 #endif /* pthread.h */ 843