1/* 2** GNU Pth - The GNU Portable Threads 3** Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com> 4** 5** This file is part of GNU Pth, a non-preemptive thread scheduling 6** library which can be found at http://www.gnu.org/software/pth/. 7** 8** This library is free software; you can redistribute it and/or 9** modify it under the terms of the GNU Lesser General Public 10** License as published by the Free Software Foundation; either 11** version 2.1 of the License, or (at your option) any later version. 12** 13** This library is distributed in the hope that it will be useful, 14** but WITHOUT ANY WARRANTY; without even the implied warranty of 15** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 16** Lesser General Public License for more details. 17** 18** You should have received a copy of the GNU Lesser General Public 19** License along with this library; if not, write to the Free Software 20** Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 21** USA, or contact Ralf S. Engelschall <rse@engelschall.com>. 22** 23** pthread.h: POSIX Thread ("Pthread") API for Pth 24*/ 25 /* ``Only those who attempt the absurd 26 can achieve the impossible.'' 27 -- Unknown */ 28#ifndef _PTH_PTHREAD_H_ 29#define _PTH_PTHREAD_H_ 30 31/* 32** 33** BOOTSTRAPPING 34** 35*/ 36 37/* 38 * Prevent system includes from implicitly including 39 * possibly existing vendor Pthread headers 40 */ 41#define PTHREAD 42#define PTHREAD_H 43#define _PTHREAD_T 44#define _PTHREAD_H 45#define _PTHREAD_H_ 46#define PTHREAD_INCLUDED 47#define _PTHREAD_INCLUDED 48#define SYS_PTHREAD_H 49#define _SYS_PTHREAD_H 50#define _SYS_PTHREAD_H_ 51#define SYS_PTHREAD_INCLUDED 52#define _SYS_PTHREAD_INCLUDED 53#define BITS_PTHREADTYPES_H 54#define _BITS_PTHREADTYPES_H 55#define _BITS_PTHREADTYPES_H_ 56#define _BITS_SIGTHREAD_H 57 58/* 59 * Special adjustments 60 */ 61#if defined(__hpux) 62#define _PTHREADS_DRAFT4 63#endif 64 65/* 66 * Check if the user requests a bigger FD_SETSIZE than we can handle 67 */ 68#if defined(FD_SETSIZE) 69#if FD_SETSIZE > @PTH_FDSETSIZE@ 70#error "FD_SETSIZE is larger than what GNU Pth can handle." 71#endif 72#endif 73 74/* 75 * Protect namespace, because possibly existing vendor Pthread stuff 76 * would certainly conflict with our defintions of pthread*_t. 77 */ 78#define pthread_t __vendor_pthread_t 79#define pthread_attr_t __vendor_pthread_attr_t 80#define pthread_key_t __vendor_pthread_key_t 81#define pthread_once_t __vendor_pthread_once_t 82#define pthread_mutex_t __vendor_pthread_mutex_t 83#define pthread_mutexattr_t __vendor_pthread_mutexattr_t 84#define pthread_cond_t __vendor_pthread_cond_t 85#define pthread_condattr_t __vendor_pthread_condattr_t 86#define pthread_rwlock_t __vendor_pthread_rwlock_t 87#define pthread_rwlockattr_t __vendor_pthread_rwlockattr_t 88#define sched_param __vendor_sched_param 89 90/* 91 * Allow structs containing pthread*_t in vendor headers 92 * to have some type definitions 93 */ 94#if 0 95typedef int __vendor_pthread_t; 96typedef int __vendor_pthread_attr_t; 97typedef int __vendor_pthread_key_t; 98typedef int __vendor_pthread_once_t; 99typedef int __vendor_pthread_mutex_t; 100typedef int __vendor_pthread_mutexattr_t; 101typedef int __vendor_pthread_cond_t; 102typedef int __vendor_pthread_condattr_t; 103typedef int __vendor_pthread_rwlock_t; 104typedef int __vendor_pthread_rwlockattr_t; 105typedef int __vendor_sched_param; 106#endif 107 108/* 109 * Include essential vendor headers 110 */ 111#include <sys/types.h> /* for ssize_t */ 112#include <sys/time.h> /* for struct timeval */ 113#include <sys/socket.h> /* for sockaddr */ 114#include <sys/signal.h> /* for sigset_t */ 115#include <time.h> /* for struct timespec */ 116#include <unistd.h> /* for off_t */ 117@EXTRA_INCLUDE_SYS_SELECT_H@ 118 119/* 120 * Unprotect namespace, so we can define our own variants now 121 */ 122#undef pthread_t 123#undef pthread_attr_t 124#undef pthread_key_t 125#undef pthread_once_t 126#undef pthread_mutex_t 127#undef pthread_mutexattr_t 128#undef pthread_cond_t 129#undef pthread_condattr_t 130#undef pthread_rwlock_t 131#undef pthread_rwlockattr_t 132#undef sched_param 133 134/* 135 * Cleanup more Pthread namespace from vendor values 136 */ 137#undef _POSIX_THREADS 138#undef _POSIX_THREAD_ATTR_STACKADDR 139#undef _POSIX_THREAD_ATTR_STACKSIZE 140#undef _POSIX_THREAD_PRIORITY_SCHEDULING 141#undef _POSIX_THREAD_PRIO_INHERIT 142#undef _POSIX_THREAD_PRIO_PROTECT 143#undef _POSIX_THREAD_PROCESS_SHARED 144#undef _POSIX_THREAD_SAFE_FUNCTIONS 145#undef PTHREAD_DESTRUCTOR_ITERATIONS 146#undef PTHREAD_KEYS_MAX 147#undef PTHREAD_STACK_MIN 148#undef PTHREAD_THREADS_MAX 149#undef PTHREAD_CREATE_DETACHED 150#undef PTHREAD_CREATE_JOINABLE 151#undef PTHREAD_SCOPE_SYSTEM 152#undef PTHREAD_SCOPE_PROCESS 153#undef PTHREAD_INHERIT_SCHED 154#undef PTHREAD_EXPLICIT_SCHED 155#undef PTHREAD_CANCEL_ENABLE 156#undef PTHREAD_CANCEL_DISABLE 157#undef PTHREAD_CANCEL_ASYNCHRONOUS 158#undef PTHREAD_CANCEL_DEFERRED 159#undef PTHREAD_CANCELED 160#undef PTHREAD_PROCESS_PRIVATE 161#undef PTHREAD_PROCESS_SHARED 162#undef PTHREAD_ONCE_INIT 163#undef PTHREAD_MUTEX_DEFAULT 164#undef PTHREAD_MUTEX_RECURSIVE 165#undef PTHREAD_MUTEX_NORMAL 166#undef PTHREAD_MUTEX_ERRORCHECK 167#undef PTHREAD_MUTEX_INITIALIZER 168#undef PTHREAD_COND_INITIALIZER 169#undef PTHREAD_RWLOCK_INITIALIZER 170 171/* 172 * Cleanup special adjustments 173 */ 174#if defined(__hpux) 175#undef _PTHREADS_DRAFT4 176#endif 177 178/* 179** 180** API DEFINITION 181** 182*/ 183 184#ifdef __cplusplus 185extern "C" { 186#endif 187 188/* 189 * Fallbacks for essential typedefs 190 */ 191@FALLBACK_PID_T@ 192@FALLBACK_SIZE_T@ 193@FALLBACK_SSIZE_T@ 194@FALLBACK_SOCKLEN_T@ 195@FALLBACK_OFF_T@ 196@FALLBACK_NFDS_T@ 197 198/* 199 * Extra structure definitions 200 */ 201struct timeval; 202struct timespec; 203 204/* 205 * GNU Pth indentification 206 */ 207#define _POSIX_THREAD_IS_GNU_PTH @PTH_VERSION_HEX@ 208 209/* 210 * Compile time symbolic feature macros for portability 211 * specification to applications using pthreads 212 */ 213#define _POSIX_THREADS 214#define _POSIX_THREAD_ATTR_STACKADDR 215#define _POSIX_THREAD_ATTR_STACKSIZE 216#undef _POSIX_THREAD_PRIORITY_SCHEDULING 217#undef _POSIX_THREAD_PRIO_INHERIT 218#undef _POSIX_THREAD_PRIO_PROTECT 219#undef _POSIX_THREAD_PROCESS_SHARED 220#undef _POSIX_THREAD_SAFE_FUNCTIONS 221 222/* 223 * System call mapping support type 224 * (soft variant can be overridden) 225 */ 226#define _POSIX_THREAD_SYSCALL_HARD @PTH_SYSCALL_HARD@ 227#ifndef _POSIX_THREAD_SYSCALL_SOFT 228#define _POSIX_THREAD_SYSCALL_SOFT @PTH_SYSCALL_SOFT@ 229#endif 230 231/* 232 * Run-time invariant values 233 */ 234#define PTHREAD_DESTRUCTOR_ITERATIONS 4 235#define PTHREAD_KEYS_MAX 256 236#define PTHREAD_STACK_MIN 8192 237#define PTHREAD_THREADS_MAX 10000 /* actually yet no restriction */ 238 239/* 240 * Flags for threads and thread attributes. 241 */ 242#define PTHREAD_CREATE_DETACHED 0x01 243#define PTHREAD_CREATE_JOINABLE 0x02 244#define PTHREAD_SCOPE_SYSTEM 0x03 245#define PTHREAD_SCOPE_PROCESS 0x04 246#define PTHREAD_INHERIT_SCHED 0x05 247#define PTHREAD_EXPLICIT_SCHED 0x06 248 249/* 250 * Values for cancellation 251 */ 252#define PTHREAD_CANCEL_ENABLE 0x01 253#define PTHREAD_CANCEL_DISABLE 0x02 254#define PTHREAD_CANCEL_ASYNCHRONOUS 0x01 255#define PTHREAD_CANCEL_DEFERRED 0x02 256#define PTHREAD_CANCELED ((void *)-1) 257 258/* 259 * Flags for mutex priority attributes 260 */ 261#define PTHREAD_PRIO_INHERIT 0x00 262#define PTHREAD_PRIO_NONE 0x01 263#define PTHREAD_PRIO_PROTECT 0x02 264 265/* 266 * Flags for read/write lock attributes 267 */ 268#define PTHREAD_PROCESS_PRIVATE 0x00 269#define PTHREAD_PROCESS_SHARED 0x01 270 271/* 272 * Forward structure definitions. 273 * These are mostly opaque to the application. 274 */ 275struct pthread_st; 276struct pthread_attr_st; 277struct pthread_cond_st; 278struct pthread_mutex_st; 279struct pthread_rwlock_st; 280struct sched_param; 281 282/* 283 * Primitive system data type definitions required by P1003.1c 284 */ 285typedef struct pthread_st *pthread_t; 286typedef struct pthread_attr_st *pthread_attr_t; 287typedef int pthread_key_t; 288typedef int pthread_once_t; 289typedef int pthread_mutexattr_t; 290typedef struct pthread_mutex_st *pthread_mutex_t; 291typedef int pthread_condattr_t; 292typedef struct pthread_cond_st *pthread_cond_t; 293typedef int pthread_rwlockattr_t; 294typedef struct pthread_rwlock_st *pthread_rwlock_t; 295 296/* 297 * Once support. 298 */ 299#define PTHREAD_ONCE_INIT 0 300 301/* 302 * Mutex static initialization values. 303 */ 304enum pthread_mutextype { 305 PTHREAD_MUTEX_DEFAULT = 1, 306 PTHREAD_MUTEX_RECURSIVE, 307 PTHREAD_MUTEX_NORMAL, 308 PTHREAD_MUTEX_ERRORCHECK 309}; 310 311/* 312 * Mutex/CondVar/RWLock static initialization values. 313 */ 314#define PTHREAD_MUTEX_INITIALIZER (pthread_mutex_t)(NULL) 315#define PTHREAD_COND_INITIALIZER (pthread_cond_t)(NULL) 316#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t)(NULL) 317 318/* 319 * IEEE (``POSIX'') Std 1003.1 Second Edition 1996-07-12 320 */ 321 322/* thread attribute routines */ 323extern int pthread_attr_init(pthread_attr_t *); 324extern int pthread_attr_destroy(pthread_attr_t *); 325extern int pthread_attr_setinheritsched(pthread_attr_t *, int); 326extern int pthread_attr_getinheritsched(const pthread_attr_t *, int *); 327extern int pthread_attr_setschedparam(pthread_attr_t *, const struct sched_param *); 328extern int pthread_attr_getschedparam(const pthread_attr_t *, struct sched_param *); 329extern int pthread_attr_setschedpolicy(pthread_attr_t *, int); 330extern int pthread_attr_getschedpolicy(const pthread_attr_t *, int *); 331extern int pthread_attr_setscope(pthread_attr_t *, int); 332extern int pthread_attr_getscope(const pthread_attr_t *, int *); 333extern int pthread_attr_setstacksize(pthread_attr_t *, size_t); 334extern int pthread_attr_getstacksize(const pthread_attr_t *, size_t *); 335extern int pthread_attr_setstackaddr(pthread_attr_t *, void *); 336extern int pthread_attr_getstackaddr(const pthread_attr_t *, void **); 337extern int pthread_attr_setdetachstate(pthread_attr_t *, int); 338extern int pthread_attr_getdetachstate(const pthread_attr_t *, int *); 339extern int pthread_attr_setguardsize(pthread_attr_t *, int); 340extern int pthread_attr_getguardsize(const pthread_attr_t *, int *); 341extern int pthread_attr_setname_np(pthread_attr_t *, char *); 342extern int pthread_attr_getname_np(const pthread_attr_t *, char **); 343extern int pthread_attr_setprio_np(pthread_attr_t *, int); 344extern int pthread_attr_getprio_np(const pthread_attr_t *, int *); 345 346/* thread routines */ 347extern int pthread_create(pthread_t *, const pthread_attr_t *, void *(*)(void *), void *); 348extern int __pthread_detach(pthread_t); 349#define pthread_detach(t) __pthread_detach(t) 350extern pthread_t pthread_self(void); 351extern int pthread_equal(pthread_t, pthread_t); 352extern int pthread_yield_np(void); 353extern void pthread_exit(void *); 354extern int pthread_join(pthread_t, void **); 355extern int pthread_once(pthread_once_t *, void (*)(void)); 356extern int pthread_sigmask(int, const sigset_t *, sigset_t *); 357extern int pthread_kill(pthread_t, int); 358 359/* concurrency routines */ 360extern int pthread_getconcurrency(void); 361extern int pthread_setconcurrency(int); 362 363/* context routines */ 364extern int pthread_key_create(pthread_key_t *, void (*)(void *)); 365extern int pthread_key_delete(pthread_key_t); 366extern int pthread_setspecific(pthread_key_t, const void *); 367extern void *pthread_getspecific(pthread_key_t); 368 369/* cancel routines */ 370extern int pthread_cancel(pthread_t); 371extern void pthread_testcancel(void); 372extern int pthread_setcancelstate(int, int *); 373extern int pthread_setcanceltype(int, int *); 374 375/* scheduler routines */ 376extern int pthread_setschedparam(pthread_t, int, const struct sched_param *); 377extern int pthread_getschedparam(pthread_t, int *, struct sched_param *); 378 379/* cleanup routines */ 380extern void pthread_cleanup_push(void (*)(void *), void *); 381extern void pthread_cleanup_pop(int); 382extern int pthread_atfork(void (*)(void), void (*)(void), void (*)(void)); 383 384/* mutex attribute routines */ 385extern int pthread_mutexattr_init(pthread_mutexattr_t *); 386extern int pthread_mutexattr_destroy(pthread_mutexattr_t *); 387extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int); 388extern int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *, int *); 389extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *, int); 390extern int pthread_mutexattr_getprotocol(pthread_mutexattr_t *, int *); 391extern int pthread_mutexattr_setpshared(pthread_mutexattr_t *, int); 392extern int pthread_mutexattr_getpshared(pthread_mutexattr_t *, int *); 393extern int pthread_mutexattr_settype(pthread_mutexattr_t *, int); 394extern int pthread_mutexattr_gettype(pthread_mutexattr_t *, int *); 395 396/* mutex routines */ 397extern int pthread_mutex_init(pthread_mutex_t *, const pthread_mutexattr_t *); 398extern int pthread_mutex_destroy(pthread_mutex_t *); 399extern int pthread_mutex_setprioceiling(pthread_mutex_t *, int, int *); 400extern int pthread_mutex_getprioceiling(pthread_mutex_t *, int *); 401extern int pthread_mutex_lock(pthread_mutex_t *); 402extern int pthread_mutex_trylock(pthread_mutex_t *); 403extern int pthread_mutex_unlock(pthread_mutex_t *); 404 405/* rwlock attribute routines */ 406extern int pthread_rwlockattr_init(pthread_rwlockattr_t *); 407extern int pthread_rwlockattr_destroy(pthread_rwlockattr_t *); 408extern int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *, int); 409extern int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *, int *); 410 411/* rwlock routines */ 412extern int pthread_rwlock_init(pthread_rwlock_t *, const pthread_rwlockattr_t *); 413extern int pthread_rwlock_destroy(pthread_rwlock_t *); 414extern int pthread_rwlock_rdlock(pthread_rwlock_t *); 415extern int pthread_rwlock_tryrdlock(pthread_rwlock_t *); 416extern int pthread_rwlock_wrlock(pthread_rwlock_t *); 417extern int pthread_rwlock_trywrlock(pthread_rwlock_t *); 418extern int pthread_rwlock_unlock(pthread_rwlock_t *); 419 420/* condition attribute routines */ 421extern int pthread_condattr_init(pthread_condattr_t *); 422extern int pthread_condattr_destroy(pthread_condattr_t *); 423extern int pthread_condattr_setpshared(pthread_condattr_t *, int); 424extern int pthread_condattr_getpshared(pthread_condattr_t *, int *); 425 426/* condition routines */ 427extern int pthread_cond_init(pthread_cond_t *, const pthread_condattr_t *); 428extern int pthread_cond_destroy(pthread_cond_t *); 429extern int pthread_cond_broadcast(pthread_cond_t *); 430extern int pthread_cond_signal(pthread_cond_t *); 431extern int pthread_cond_wait(pthread_cond_t *, pthread_mutex_t *); 432extern int pthread_cond_timedwait(pthread_cond_t *, pthread_mutex_t *, const struct timespec *); 433 434/* 435 * Extensions created by POSIX 1003.1j 436 */ 437extern int pthread_abort(pthread_t); 438 439/* 440 * Optionally fake poll(2) data structure and options 441 */ 442#if !(@PTH_FAKE_POLL@) 443/* use vendor poll(2) environment */ 444#include <poll.h> 445#ifndef INFTIM 446#define INFTIM (-1) 447#endif 448#else 449/* fake a poll(2) environment */ 450#define POLLIN 0x0001 /* any readable data available */ 451#define POLLPRI 0x0002 /* OOB/Urgent readable data */ 452#define POLLOUT 0x0004 /* file descriptor is writeable */ 453#define POLLERR 0x0008 /* some poll error occurred */ 454#define POLLHUP 0x0010 /* file descriptor was "hung up" */ 455#define POLLNVAL 0x0020 /* requested events "invalid" */ 456#define POLLRDNORM POLLIN 457#define POLLRDBAND POLLIN 458#define POLLWRNORM POLLOUT 459#define POLLWRBAND POLLOUT 460#ifndef INFTIM 461#define INFTIM (-1) /* poll infinite */ 462#endif 463struct pollfd { 464 int fd; /* which file descriptor to poll */ 465 short events; /* events we are interested in */ 466 short revents; /* events found on return */ 467}; 468#endif 469 470/* 471 * Optionally fake readv(2)/writev(2) data structure and options 472 */ 473#if !(@PTH_FAKE_RWV@) 474/* use vendor readv(2)/writev(2) environment */ 475#include <sys/uio.h> 476#ifndef UIO_MAXIOV 477#define UIO_MAXIOV 1024 478#endif 479#else 480/* fake a readv(2)/writev(2) environment */ 481struct iovec { 482 void *iov_base; /* memory base address */ 483 size_t iov_len; /* memory chunk length */ 484}; 485#ifndef UIO_MAXIOV 486#define UIO_MAXIOV 1024 487#endif 488#endif 489 490/* 491 * Replacement Functions (threading aware) 492 */ 493 494extern pid_t __pthread_fork(void); 495extern unsigned int __pthread_sleep(unsigned int); 496extern int __pthread_nanosleep(const struct timespec *, struct timespec *); 497extern int __pthread_usleep(unsigned int); 498extern int __pthread_system(const char *); 499extern int __pthread_sigwait(const sigset_t *, int *); 500extern pid_t __pthread_waitpid(pid_t, int *, int); 501extern int __pthread_connect(int, struct sockaddr *, socklen_t); 502extern int __pthread_accept(int, struct sockaddr *, socklen_t *); 503extern int __pthread_select(int, fd_set *, fd_set *, fd_set *, struct timeval *); 504extern int __pthread_poll(struct pollfd *, nfds_t, int); 505extern ssize_t __pthread_read(int, void *, size_t); 506extern ssize_t __pthread_write(int, const void *, size_t); 507extern ssize_t __pthread_readv(int, const struct iovec *, int); 508extern ssize_t __pthread_writev(int, const struct iovec *, int); 509extern ssize_t __pthread_recv(int, void *, size_t, int); 510extern ssize_t __pthread_send(int, const void *, size_t, int); 511extern ssize_t __pthread_recvfrom(int, void *, size_t, int, struct sockaddr *, socklen_t *); 512extern ssize_t __pthread_sendto(int, const void *, size_t, int, const struct sockaddr *, socklen_t); 513extern ssize_t __pthread_pread(int, void *, size_t, off_t); 514extern ssize_t __pthread_pwrite(int, const void *, size_t, off_t); 515 516#if _POSIX_THREAD_SYSCALL_SOFT && !defined(_PTHREAD_PRIVATE) 517#define fork __pthread_fork 518#define sleep __pthread_sleep 519#define nanosleep __pthread_nanosleep 520#define usleep __pthread_usleep 521#define system __pthread_system 522#define sigwait __pthread_sigwait 523#define waitpid __pthread_waitpid 524#define connect __pthread_connect 525#define accept __pthread_accept 526#define select __pthread_select 527#define poll __pthread_poll 528#define read __pthread_read 529#define write __pthread_write 530#define readv __pthread_readv 531#define writev __pthread_writev 532#define recv __pthread_recv 533#define send __pthread_send 534#define recvfrom __pthread_recvfrom 535#define sendto __pthread_sendto 536#define pread __pthread_pread 537#define pwrite __pthread_pwrite 538#endif 539 540/* 541 * More "special" POSIX stuff 542 */ 543 544#define sched_yield pthread_yield_np 545 546/* 547 * Backward Compatibility Stuff for Pthread draft 4 (DCE threads) 548 */ 549 550#ifdef _POSIX_BACKCOMPAT 551 552#define _POSIX_THREADS_PER_THREAD_SIGNALS 1 553 554#define pthread_attr_default NULL 555#define pthread_condattr_default NULL 556#define pthread_mutexattr_default NULL 557#define pthread_once_init PTHREAD_ONCE_INIT 558 559#define pthread_detach(thread) __pthread_detach(*(thread)) 560 561#define pthread_attr_init pthread_attr_create 562#define pthread_attr_delete pthread_attr_destroy 563#define pthread_keycreate pthread_key_create 564#define pthread_yield pthread_yield_np 565 566#define pthread_attr_setprio pthread_attr_setprio_np 567#define pthread_attr_getprio pthread_attr_getprio_np 568 569#define CANCEL_ON 1 570#define CANCEL_OFF 2 571#define pthread_setcancel(what) \ 572 pthread_setcancelstate((what) == CANCEL_ON ? \ 573 PTHREAD_CANCEL_ENABLE : \ 574 PTHREAD_CANCEL_DISABLE) 575#define pthread_setasynccancel(what) \ 576 pthread_setcanceltype((what) == CANCEL_ON ? \ 577 PTHREAD_CANCEL_ASYNCHRONOUS : \ 578 PTHREAD_CANCEL_DEFERRED) 579 580#define pthread_setscheduler #error 581#define pthread_setprio #error 582#define pthread_attr_setsched #error 583#define pthread_attr_getsched #error 584 585#endif /* _POSIX_BACKCOMPAT */ 586 587#ifdef __cplusplus 588} 589#endif 590 591#endif /* _PTH_PTHREAD_H_ */ 592 593