2 ** GNU Pth - The GNU Portable Threads
3 ** Copyright (c) 1999-2006 Ralf S. Engelschall <rse@engelschall.com>
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/.
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.
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.
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>.
23 ** pthread.c: POSIX Thread ("Pthread") API for Pth
25 /* ``The nice thing about standards is that
26 there are so many to choose from. And if
27 you really don't like all the standards you
28 just have to wait another year until the one
29 arises you are looking for''
30 -- Tannenbaum, 'Introduction
31 to Computer Networks' */
38 * Include our own Pthread and then the private Pth header.
39 * The order here is very important to get correct namespace hiding!
41 #define _PTHREAD_PRIVATE
44 #undef _PTHREAD_PRIVATE
46 /* general success return value */
56 static void pthread_shutdown(void)
62 static int pthread_initialized = FALSE;
64 #define pthread_initialize() \
66 if (pthread_initialized == FALSE) { \
67 pthread_initialized = TRUE; \
69 atexit(pthread_shutdown); \
74 ** THREAD ATTRIBUTE ROUTINES
77 int pthread_attr_init(pthread_attr_t *attr)
83 return pth_error(EINVAL, EINVAL);
84 if ((na = pth_attr_new()) == NULL)
86 (*attr) = (pthread_attr_t)na;
90 int pthread_attr_destroy(pthread_attr_t *attr)
94 if (attr == NULL || *attr == NULL)
95 return pth_error(EINVAL, EINVAL);
96 na = (pth_attr_t)(*attr);
102 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inheritsched)
105 return pth_error(EINVAL, EINVAL);
107 return pth_error(ENOSYS, ENOSYS);
110 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inheritsched)
112 if (attr == NULL || inheritsched == NULL)
113 return pth_error(EINVAL, EINVAL);
115 return pth_error(ENOSYS, ENOSYS);
118 int pthread_attr_setschedparam(pthread_attr_t *attr, const struct sched_param *schedparam)
121 return pth_error(EINVAL, EINVAL);
123 return pth_error(ENOSYS, ENOSYS);
126 int pthread_attr_getschedparam(const pthread_attr_t *attr, struct sched_param *schedparam)
128 if (attr == NULL || schedparam == NULL)
129 return pth_error(EINVAL, EINVAL);
131 return pth_error(ENOSYS, ENOSYS);
134 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int schedpolicy)
137 return pth_error(EINVAL, EINVAL);
139 return pth_error(ENOSYS, ENOSYS);
142 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *schedpolicy)
144 if (attr == NULL || schedpolicy == NULL)
145 return pth_error(EINVAL, EINVAL);
147 return pth_error(ENOSYS, ENOSYS);
150 int pthread_attr_setscope(pthread_attr_t *attr, int scope)
153 return pth_error(EINVAL, EINVAL);
155 return pth_error(ENOSYS, ENOSYS);
158 int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
160 if (attr == NULL || scope == NULL)
161 return pth_error(EINVAL, EINVAL);
163 return pth_error(ENOSYS, ENOSYS);
166 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
169 return pth_error(EINVAL, EINVAL);
170 if (!pth_attr_set((pth_attr_t)(*attr), PTH_ATTR_STACK_SIZE, (unsigned int)stacksize))
175 int pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
177 if (attr == NULL || stacksize == NULL)
178 return pth_error(EINVAL, EINVAL);
179 if (!pth_attr_get((pth_attr_t)(*attr), PTH_ATTR_STACK_SIZE, (unsigned int *)stacksize))
184 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
187 return pth_error(EINVAL, EINVAL);
188 if (!pth_attr_set((pth_attr_t)(*attr), PTH_ATTR_STACK_ADDR, (char *)stackaddr))
193 int pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
195 if (attr == NULL || stackaddr == NULL)
196 return pth_error(EINVAL, EINVAL);
197 if (!pth_attr_get((pth_attr_t)(*attr), PTH_ATTR_STACK_ADDR, (char **)stackaddr))
202 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
207 return pth_error(EINVAL, EINVAL);
208 if (detachstate == PTHREAD_CREATE_DETACHED)
210 else if (detachstate == PTHREAD_CREATE_JOINABLE)
213 return pth_error(EINVAL, EINVAL);
214 if (!pth_attr_set((pth_attr_t)(*attr), PTH_ATTR_JOINABLE, s))
219 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
223 if (attr == NULL || detachstate == NULL)
224 return pth_error(EINVAL, EINVAL);
225 if (!pth_attr_get((pth_attr_t)(*attr), PTH_ATTR_JOINABLE, &s))
228 *detachstate = PTHREAD_CREATE_JOINABLE;
230 *detachstate = PTHREAD_CREATE_DETACHED;
234 int pthread_attr_setguardsize(pthread_attr_t *attr, int stacksize)
236 if (attr == NULL || stacksize < 0)
237 return pth_error(EINVAL, EINVAL);
239 return pth_error(ENOSYS, ENOSYS);
242 int pthread_attr_getguardsize(const pthread_attr_t *attr, int *stacksize)
244 if (attr == NULL || stacksize == NULL)
245 return pth_error(EINVAL, EINVAL);
247 return pth_error(ENOSYS, ENOSYS);
250 int pthread_attr_setname_np(pthread_attr_t *attr, char *name)
252 if (attr == NULL || name == NULL)
253 return pth_error(EINVAL, EINVAL);
254 if (!pth_attr_set((pth_attr_t)(*attr), PTH_ATTR_NAME, name))
259 int pthread_attr_getname_np(const pthread_attr_t *attr, char **name)
261 if (attr == NULL || name == NULL)
262 return pth_error(EINVAL, EINVAL);
263 if (!pth_attr_get((pth_attr_t)(*attr), PTH_ATTR_NAME, name))
268 int pthread_attr_setprio_np(pthread_attr_t *attr, int prio)
270 if (attr == NULL || (prio < PTH_PRIO_MIN || prio > PTH_PRIO_MAX))
271 return pth_error(EINVAL, EINVAL);
272 if (!pth_attr_set((pth_attr_t)(*attr), PTH_ATTR_PRIO, prio))
277 int pthread_attr_getprio_np(const pthread_attr_t *attr, int *prio)
279 if (attr == NULL || prio == NULL)
280 return pth_error(EINVAL, EINVAL);
281 if (!pth_attr_get((pth_attr_t)(*attr), PTH_ATTR_PRIO, prio))
291 pthread_t *thread, const pthread_attr_t *attr,
292 void *(*start_routine)(void *), void *arg)
296 pthread_initialize();
297 if (thread == NULL || start_routine == NULL)
298 return pth_error(EINVAL, EINVAL);
299 if (pth_ctrl(PTH_CTRL_GETTHREADS) >= PTHREAD_THREADS_MAX)
300 return pth_error(EAGAIN, EAGAIN);
302 na = (pth_attr_t)(*attr);
304 na = PTH_ATTR_DEFAULT;
305 *thread = (pthread_t)pth_spawn(na, start_routine, arg);
307 return pth_error(EAGAIN, EAGAIN);
311 int __pthread_detach(pthread_t thread)
316 return pth_error(EINVAL, EINVAL);
317 if ((na = pth_attr_of((pth_t)thread)) == NULL)
319 if (!pth_attr_set(na, PTH_ATTR_JOINABLE, FALSE))
321 pth_attr_destroy(na);
325 pthread_t pthread_self(void)
327 pthread_initialize();
328 return (pthread_t)pth_self();
331 int pthread_equal(pthread_t t1, pthread_t t2)
336 int pthread_yield_np(void)
338 pthread_initialize();
343 void pthread_exit(void *value_ptr)
345 pthread_initialize();
350 int pthread_join(pthread_t thread, void **value_ptr)
352 pthread_initialize();
353 if (!pth_join((pth_t)thread, value_ptr))
355 if (value_ptr != NULL)
356 if (*value_ptr == PTH_CANCELED)
357 *value_ptr = PTHREAD_CANCELED;
362 pthread_once_t *once_control, void (*init_routine)(void))
364 pthread_initialize();
365 if (once_control == NULL || init_routine == NULL)
366 return pth_error(EINVAL, EINVAL);
367 if (*once_control != 1)
373 int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset)
375 pthread_initialize();
376 return pth_sigmask(how, set, oset);
379 int pthread_kill(pthread_t thread, int sig)
381 if (!pth_raise((pth_t)thread, sig))
387 ** CONCURRENCY ROUTINES
389 ** We just have to provide the interface, because SUSv2 says:
390 ** "The pthread_setconcurrency() function allows an application to
391 ** inform the threads implementation of its desired concurrency
392 ** level, new_level. The actual level of concurrency provided by the
393 ** implementation as a result of this function call is unspecified."
396 static int pthread_concurrency = 0;
398 int pthread_getconcurrency(void)
400 return pthread_concurrency;
403 int pthread_setconcurrency(int new_level)
406 return pth_error(EINVAL, EINVAL);
407 pthread_concurrency = new_level;
415 int pthread_key_create(pthread_key_t *key, void (*destructor)(void *))
417 pthread_initialize();
418 if (!pth_key_create((pth_key_t *)key, destructor))
423 int pthread_key_delete(pthread_key_t key)
425 if (!pth_key_delete((pth_key_t)key))
430 int pthread_setspecific(pthread_key_t key, const void *value)
432 if (!pth_key_setdata((pth_key_t)key, value))
437 void *pthread_getspecific(pthread_key_t key)
439 return pth_key_getdata((pth_key_t)key);
446 int pthread_cancel(pthread_t thread)
448 if (!pth_cancel((pth_t)thread))
453 void pthread_testcancel(void)
459 int pthread_setcancelstate(int state, int *oldstate)
463 if (oldstate != NULL) {
464 pth_cancel_state(0, &os);
465 if (os & PTH_CANCEL_ENABLE)
466 *oldstate = PTHREAD_CANCEL_ENABLE;
468 *oldstate = PTHREAD_CANCEL_DISABLE;
471 pth_cancel_state(0, &s);
472 if (state == PTHREAD_CANCEL_ENABLE) {
473 s |= PTH_CANCEL_ENABLE;
474 s &= ~(PTH_CANCEL_DISABLE);
477 s |= PTH_CANCEL_DISABLE;
478 s &= ~(PTH_CANCEL_ENABLE);
480 pth_cancel_state(s, NULL);
485 int pthread_setcanceltype(int type, int *oldtype)
489 if (oldtype != NULL) {
490 pth_cancel_state(0, &ot);
491 if (ot & PTH_CANCEL_DEFERRED)
492 *oldtype = PTHREAD_CANCEL_DEFERRED;
494 *oldtype = PTHREAD_CANCEL_ASYNCHRONOUS;
497 pth_cancel_state(0, &t);
498 if (type == PTHREAD_CANCEL_DEFERRED) {
499 t |= PTH_CANCEL_DEFERRED;
500 t &= ~(PTH_CANCEL_ASYNCHRONOUS);
503 t |= PTH_CANCEL_ASYNCHRONOUS;
504 t &= ~(PTH_CANCEL_DEFERRED);
506 pth_cancel_state(t, NULL);
512 ** SCHEDULER ROUTINES
515 int pthread_setschedparam(pthread_t pthread, int policy, const struct sched_param *param)
518 return pth_error(ENOSYS, ENOSYS);
521 int pthread_getschedparam(pthread_t pthread, int *policy, struct sched_param *param)
524 return pth_error(ENOSYS, ENOSYS);
531 void pthread_cleanup_push(void (*routine)(void *), void *arg)
533 pthread_initialize();
534 pth_cleanup_push(routine, arg);
538 void pthread_cleanup_pop(int execute)
540 pth_cleanup_pop(execute);
548 struct pthread_atfork_st {
549 void (*prepare)(void);
550 void (*parent)(void);
553 static struct pthread_atfork_st pthread_atfork_info[PTH_ATFORK_MAX];
554 static int pthread_atfork_idx = 0;
556 static void pthread_atfork_cb_prepare(void *_info)
558 struct pthread_atfork_st *info = (struct pthread_atfork_st *)_info;
562 static void pthread_atfork_cb_parent(void *_info)
564 struct pthread_atfork_st *info = (struct pthread_atfork_st *)_info;
568 static void pthread_atfork_cb_child(void *_info)
570 struct pthread_atfork_st *info = (struct pthread_atfork_st *)_info;
575 int pthread_atfork(void (*prepare)(void), void (*parent)(void), void (*child)(void))
577 struct pthread_atfork_st *info;
579 if (pthread_atfork_idx > PTH_ATFORK_MAX-1)
580 return pth_error(ENOMEM, ENOMEM);
581 info = &pthread_atfork_info[pthread_atfork_idx++];
582 info->prepare = prepare;
583 info->parent = parent;
585 if (!pth_atfork_push(pthread_atfork_cb_prepare,
586 pthread_atfork_cb_parent,
587 pthread_atfork_cb_child, info))
593 ** MUTEX ATTRIBUTE ROUTINES
596 int pthread_mutexattr_init(pthread_mutexattr_t *attr)
598 pthread_initialize();
600 return pth_error(EINVAL, EINVAL);
601 /* nothing to do for us */
605 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
608 return pth_error(EINVAL, EINVAL);
609 /* nothing to do for us */
613 int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *attr, int prioceiling)
616 return pth_error(EINVAL, EINVAL);
618 return pth_error(ENOSYS, ENOSYS);
621 int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *attr, int *prioceiling)
624 return pth_error(EINVAL, EINVAL);
626 return pth_error(ENOSYS, ENOSYS);
629 int pthread_mutexattr_setprotocol(pthread_mutexattr_t *attr, int protocol)
632 return pth_error(EINVAL, EINVAL);
634 return pth_error(ENOSYS, ENOSYS);
637 int pthread_mutexattr_getprotocol(pthread_mutexattr_t *attr, int *protocol)
640 return pth_error(EINVAL, EINVAL);
642 return pth_error(ENOSYS, ENOSYS);
645 int pthread_mutexattr_setpshared(pthread_mutexattr_t *attr, int pshared)
648 return pth_error(EINVAL, EINVAL);
650 return pth_error(ENOSYS, ENOSYS);
653 int pthread_mutexattr_getpshared(pthread_mutexattr_t *attr, int *pshared)
656 return pth_error(EINVAL, EINVAL);
658 return pth_error(ENOSYS, ENOSYS);
661 int pthread_mutexattr_settype(pthread_mutexattr_t *attr, int type)
664 return pth_error(EINVAL, EINVAL);
666 return pth_error(ENOSYS, ENOSYS);
669 int pthread_mutexattr_gettype(pthread_mutexattr_t *attr, int *type)
672 return pth_error(EINVAL, EINVAL);
674 return pth_error(ENOSYS, ENOSYS);
681 int pthread_mutex_init(pthread_mutex_t *mutex, const pthread_mutexattr_t *attr)
685 pthread_initialize();
687 return pth_error(EINVAL, EINVAL);
688 if ((m = (pth_mutex_t *)malloc(sizeof(pth_mutex_t))) == NULL)
690 if (!pth_mutex_init(m))
692 (*mutex) = (pthread_mutex_t)m;
696 int pthread_mutex_destroy(pthread_mutex_t *mutex)
699 return pth_error(EINVAL, EINVAL);
705 int pthread_mutex_setprioceiling(pthread_mutex_t *mutex, int prioceiling, int *old_ceiling)
708 return pth_error(EINVAL, EINVAL);
709 if (*mutex == PTHREAD_MUTEX_INITIALIZER)
710 if (pthread_mutex_init(mutex, NULL) != OK)
713 return pth_error(ENOSYS, ENOSYS);
716 int pthread_mutex_getprioceiling(pthread_mutex_t *mutex, int *prioceiling)
719 return pth_error(EINVAL, EINVAL);
720 if (*mutex == PTHREAD_MUTEX_INITIALIZER)
721 if (pthread_mutex_init(mutex, NULL) != OK)
724 return pth_error(ENOSYS, ENOSYS);
727 int pthread_mutex_lock(pthread_mutex_t *mutex)
730 return pth_error(EINVAL, EINVAL);
731 if (*mutex == PTHREAD_MUTEX_INITIALIZER)
732 if (pthread_mutex_init(mutex, NULL) != OK)
734 if (!pth_mutex_acquire((pth_mutex_t *)(*mutex), FALSE, NULL))
739 int pthread_mutex_trylock(pthread_mutex_t *mutex)
742 return pth_error(EINVAL, EINVAL);
743 if (*mutex == PTHREAD_MUTEX_INITIALIZER)
744 if (pthread_mutex_init(mutex, NULL) != OK)
746 if (!pth_mutex_acquire((pth_mutex_t *)(*mutex), TRUE, NULL))
751 int pthread_mutex_unlock(pthread_mutex_t *mutex)
754 return pth_error(EINVAL, EINVAL);
755 if (*mutex == PTHREAD_MUTEX_INITIALIZER)
756 if (pthread_mutex_init(mutex, NULL) != OK)
758 if (!pth_mutex_release((pth_mutex_t *)(*mutex)))
764 ** LOCK ATTRIBUTE ROUTINES
767 int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
769 pthread_initialize();
771 return pth_error(EINVAL, EINVAL);
772 /* nothing to do for us */
776 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
779 return pth_error(EINVAL, EINVAL);
780 /* nothing to do for us */
784 int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int pshared)
787 return pth_error(EINVAL, EINVAL);
789 return pth_error(ENOSYS, ENOSYS);
792 int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *pshared)
795 return pth_error(EINVAL, EINVAL);
797 return pth_error(ENOSYS, ENOSYS);
804 int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
808 pthread_initialize();
810 return pth_error(EINVAL, EINVAL);
811 if ((rw = (pth_rwlock_t *)malloc(sizeof(pth_rwlock_t))) == NULL)
813 if (!pth_rwlock_init(rw))
815 (*rwlock) = (pthread_rwlock_t)rw;
819 int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
822 return pth_error(EINVAL, EINVAL);
828 int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock)
831 return pth_error(EINVAL, EINVAL);
832 if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
833 if (pthread_rwlock_init(rwlock, NULL) != OK)
835 if (!pth_rwlock_acquire((pth_rwlock_t *)(*rwlock), PTH_RWLOCK_RD, FALSE, NULL))
840 int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock)
843 return pth_error(EINVAL, EINVAL);
844 if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
845 if (pthread_rwlock_init(rwlock, NULL) != OK)
847 if (!pth_rwlock_acquire((pth_rwlock_t *)(*rwlock), PTH_RWLOCK_RD, TRUE, NULL))
852 int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
855 return pth_error(EINVAL, EINVAL);
856 if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
857 if (pthread_rwlock_init(rwlock, NULL) != OK)
859 if (!pth_rwlock_acquire((pth_rwlock_t *)(*rwlock), PTH_RWLOCK_RW, FALSE, NULL))
864 int pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock)
867 return pth_error(EINVAL, EINVAL);
868 if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
869 if (pthread_rwlock_init(rwlock, NULL) != OK)
871 if (!pth_rwlock_acquire((pth_rwlock_t *)(*rwlock), PTH_RWLOCK_RW, TRUE, NULL))
876 int pthread_rwlock_unlock(pthread_rwlock_t *rwlock)
879 return pth_error(EINVAL, EINVAL);
880 if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
881 if (pthread_rwlock_init(rwlock, NULL) != OK)
883 if (!pth_rwlock_release((pth_rwlock_t *)(*rwlock)))
889 ** CONDITION ATTRIBUTE ROUTINES
892 int pthread_condattr_init(pthread_condattr_t *attr)
894 pthread_initialize();
896 return pth_error(EINVAL, EINVAL);
897 /* nothing to do for us */
901 int pthread_condattr_destroy(pthread_condattr_t *attr)
904 return pth_error(EINVAL, EINVAL);
905 /* nothing to do for us */
909 int pthread_condattr_setpshared(pthread_condattr_t *attr, int pshared)
912 return pth_error(EINVAL, EINVAL);
914 return pth_error(ENOSYS, ENOSYS);
917 int pthread_condattr_getpshared(pthread_condattr_t *attr, int *pshared)
920 return pth_error(EINVAL, EINVAL);
922 return pth_error(ENOSYS, ENOSYS);
926 ** CONDITION ROUTINES
929 int pthread_cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr)
933 pthread_initialize();
935 return pth_error(EINVAL, EINVAL);
936 if ((cn = (pth_cond_t *)malloc(sizeof(pth_cond_t))) == NULL)
938 if (!pth_cond_init(cn))
940 (*cond) = (pthread_cond_t)cn;
944 int pthread_cond_destroy(pthread_cond_t *cond)
947 return pth_error(EINVAL, EINVAL);
953 int pthread_cond_broadcast(pthread_cond_t *cond)
956 return pth_error(EINVAL, EINVAL);
957 if (*cond == PTHREAD_COND_INITIALIZER)
958 if (pthread_cond_init(cond, NULL) != OK)
960 if (!pth_cond_notify((pth_cond_t *)(*cond), TRUE))
965 int pthread_cond_signal(pthread_cond_t *cond)
968 return pth_error(EINVAL, EINVAL);
969 if (*cond == PTHREAD_COND_INITIALIZER)
970 if (pthread_cond_init(cond, NULL) != OK)
972 if (!pth_cond_notify((pth_cond_t *)(*cond), FALSE))
977 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
979 if (cond == NULL || mutex == NULL)
980 return pth_error(EINVAL, EINVAL);
981 if (*cond == PTHREAD_COND_INITIALIZER)
982 if (pthread_cond_init(cond, NULL) != OK)
984 if (*mutex == PTHREAD_MUTEX_INITIALIZER)
985 if (pthread_mutex_init(mutex, NULL) != OK)
987 if (!pth_cond_await((pth_cond_t *)(*cond), (pth_mutex_t *)(*mutex), NULL))
992 int pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex,
993 const struct timespec *abstime)
996 static pth_key_t ev_key = PTH_KEY_INIT;
998 if (cond == NULL || mutex == NULL || abstime == NULL)
999 return pth_error(EINVAL, EINVAL);
1001 if (abstime->ts_sec < 0 || abstime->ts_nsec < 0 || abstime->ts_nsec >= 1000000000)
1003 if (abstime->tv_sec < 0 || abstime->tv_nsec < 0 || abstime->tv_nsec >= 1000000000)
1005 return pth_error(EINVAL, EINVAL);
1006 if (*cond == PTHREAD_COND_INITIALIZER)
1007 if (pthread_cond_init(cond, NULL) != OK)
1009 if (*mutex == PTHREAD_MUTEX_INITIALIZER)
1010 if (pthread_mutex_init(mutex, NULL) != OK)
1012 ev = pth_event(PTH_EVENT_TIME|PTH_MODE_STATIC, &ev_key,
1014 pth_time(abstime->ts_sec, (abstime->ts_nsec)/1000)
1016 pth_time(abstime->tv_sec, (abstime->tv_nsec)/1000)
1019 if (!pth_cond_await((pth_cond_t *)(*cond), (pth_mutex_t *)(*mutex), ev))
1021 if (pth_event_status(ev) == PTH_STATUS_OCCURRED)
1030 int pthread_abort(pthread_t thread)
1032 if (!pth_abort((pth_t)thread))
1038 ** THREAD-SAFE REPLACEMENT FUNCTIONS
1041 pid_t __pthread_fork(void)
1043 pthread_initialize();
1047 unsigned int __pthread_sleep(unsigned int sec)
1049 pthread_initialize();
1050 return pth_sleep(sec);
1053 int __pthread_system(const char *cmd)
1055 pthread_initialize();
1056 return pth_system(cmd);
1059 int __pthread_nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
1061 pthread_initialize();
1062 return pth_nanosleep(rqtp, rmtp);
1065 int __pthread_usleep(unsigned int sec)
1067 pthread_initialize();
1068 return pth_usleep(sec);
1071 int __pthread_sigwait(const sigset_t *set, int *sig)
1073 pthread_initialize();
1074 return pth_sigwait(set, sig);
1077 pid_t __pthread_waitpid(pid_t pid, int *status, int options)
1079 pthread_initialize();
1080 return pth_waitpid(pid, status, options);
1083 int __pthread_connect(int s, struct sockaddr *addr, socklen_t addrlen)
1085 pthread_initialize();
1086 return pth_connect(s, addr, addrlen);
1089 int __pthread_accept(int s, struct sockaddr *addr, socklen_t *addrlen)
1091 pthread_initialize();
1092 return pth_accept(s, addr, addrlen);
1095 int __pthread_select(int nfds, fd_set *readfds, fd_set *writefds,
1096 fd_set *exceptfds, struct timeval *timeout)
1098 pthread_initialize();
1099 return pth_select(nfds, readfds, writefds, exceptfds, timeout);
1102 int __pthread_poll(struct pollfd *pfd, nfds_t nfd, int timeout)
1104 pthread_initialize();
1105 return pth_poll(pfd, nfd, timeout);
1108 ssize_t __pthread_read(int fd, void *buf, size_t nbytes)
1110 pthread_initialize();
1111 return pth_read(fd, buf, nbytes);
1114 ssize_t __pthread_write(int fd, const void *buf, size_t nbytes)
1116 pthread_initialize();
1117 return pth_write(fd, buf, nbytes);
1120 ssize_t __pthread_readv(int fd, const struct iovec *piovec, int iocnt)
1122 pthread_initialize();
1123 return pth_readv(fd, piovec, iocnt);
1126 ssize_t __pthread_writev(int fd, const struct iovec *piovec, int iocnt)
1128 pthread_initialize();
1129 return pth_writev(fd, piovec, iocnt);
1132 ssize_t __pthread_recv(int fd, void *buf, size_t nbytes, int flags)
1134 pthread_initialize();
1135 return pth_recv(fd, buf, nbytes, flags);
1138 ssize_t __pthread_send(int fd, const void *buf, size_t nbytes, int flags)
1140 pthread_initialize();
1141 return pth_send(fd, buf, nbytes, flags);
1144 ssize_t __pthread_recvfrom(int fd, void *buf, size_t nbytes, int flags, struct sockaddr *from, socklen_t *fromlen)
1146 pthread_initialize();
1147 return pth_recvfrom(fd, buf, nbytes, flags, from, fromlen);
1150 ssize_t __pthread_sendto(int fd, const void *buf, size_t nbytes, int flags, const struct sockaddr *to, socklen_t tolen)
1152 pthread_initialize();
1153 return pth_sendto(fd, buf, nbytes, flags, to, tolen);
1156 ssize_t __pthread_pread(int fd, void *buf, size_t nbytes, off_t offset)
1158 pthread_initialize();
1159 return pth_pread(fd, buf, nbytes, offset);
1162 ssize_t __pthread_pwrite(int fd, const void *buf, size_t nbytes, off_t offset)
1164 pthread_initialize();
1165 return pth_pwrite(fd, buf, nbytes, offset);