20 #include "posixSyscallNumbers.h" 24 #define errno (*__errno()) 25 extern int *__errno(
void);
28 #include "posix-syscall.h" 30 #define _WANT_STRING_H 33 #define _PTHREAD_ATTR_MAGIC 0xdeadbeef 36 #define PTHREAD_DEBUG 0 38 #define STUBBED(str) \ 39 syscall1(POSIX_STUBBED, (long) (str)); \ 42 typedef void (*pthread_once_func_t)(void);
43 static int onceFunctions[32] = {0};
45 static void *_pedigree_create_waiter()
47 uintptr_t result = syscall0(POSIX_PEDIGREE_CREATE_WAITER);
48 return (
void *) result;
51 static void _pedigree_destroy_waiter(
void *waiter)
53 syscall1(POSIX_PEDIGREE_DESTROY_WAITER, (
long) waiter);
55 static int _pedigree_thread_wait_for(
void *waiter)
62 return syscall1(POSIX_PEDIGREE_THREAD_WAIT_FOR, (
long) waiter);
65 static int _pedigree_thread_trigger(
void *waiter)
67 return syscall1(POSIX_PEDIGREE_THREAD_TRIGGER, (
long) waiter);
70 static int _pthread_is_valid(pthread_t p)
72 return p && p->__internal.kthread >= 0;
75 static void _pthread_make_invalid(pthread_t p)
82 p->__internal.kthread = -1;
85 int pthread_cancel(pthread_t thread)
87 STUBBED(
"pthread_cancel");
91 int pthread_once(pthread_once_t *once_control, pthread_once_func_t init_routine)
93 int control = once_control->__internal.control;
94 if (!control || (control > 32))
98 "[%d] pthread_once called with an invalid once_control (> 32)",
103 if (!onceFunctions[control])
106 onceFunctions[control] = 1;
107 ++once_control->__internal.control;
114 pthread_t *thread,
const pthread_attr_t *attr,
115 void *(*start_routine)(
void *),
void *arg)
117 *thread = (pthread_t) malloc(
sizeof(**thread));
119 POSIX_PTHREAD_CREATE, (
long) thread, (
long) attr, (
long) start_routine,
123 int pthread_join(pthread_t thread,
void **value_ptr)
125 int result = syscall2(POSIX_PTHREAD_JOIN, (
long) thread, (
long) value_ptr);
130 void pthread_exit(
void *ret)
132 syscall1(POSIX_PTHREAD_RETURN, (
long) ret);
135 int pthread_detach(pthread_t thread)
137 return syscall1(POSIX_PTHREAD_DETACH, (
long) thread);
140 pthread_t pthread_self()
143 static struct _pthread_t result;
145 asm volatile(
"mov %%fs:0, %0" :
"=r"(result.__internal.kthread));
149 asm volatile(
"mrc p15,0,%0,c13,c0,3" :
"=r"(result.__internal.kthread));
155 int pthread_equal(pthread_t t1, pthread_t t2)
159 return t1->__internal.kthread == t2->__internal.kthread;
162 int pthread_kill(pthread_t thread,
int sig)
164 return syscall2(POSIX_PTHREAD_KILL, (
long) thread, sig);
167 int pthread_sigmask(
int how,
const sigset_t *
set, sigset_t *oset)
169 return syscall3(POSIX_PTHREAD_SIGMASK, how, (
long)
set, (
long) oset);
172 int pthread_attr_init(pthread_attr_t *attr)
180 if (attr->__internal.magic == _PTHREAD_ATTR_MAGIC)
186 attr->__internal.stackSize = 0x100000;
187 attr->__internal.detachState = 0;
188 attr->__internal.magic = _PTHREAD_ATTR_MAGIC;
192 int pthread_attr_destroy(pthread_attr_t *attr)
200 if (attr->__internal.magic != _PTHREAD_ATTR_MAGIC)
209 int pthread_attr_getdetachstate(
const pthread_attr_t *attr,
int *ret)
211 if (!attr || (attr->__internal.magic != _PTHREAD_ATTR_MAGIC) || !ret)
217 *ret = attr->__internal.detachState;
221 int pthread_attr_setdetachstate(pthread_attr_t *attr,
int detachstate)
223 if ((!attr || (attr->__internal.magic != _PTHREAD_ATTR_MAGIC)) ||
224 (detachstate != PTHREAD_CREATE_DETACHED &&
225 detachstate != PTHREAD_CREATE_JOINABLE))
231 attr->__internal.detachState = detachstate;
235 int pthread_attr_getstacksize(
const pthread_attr_t *attr,
size_t *sz)
237 if (!attr || (attr->__internal.magic != _PTHREAD_ATTR_MAGIC) || !sz)
243 *sz = attr->__internal.stackSize;
248 int pthread_attr_setstacksize(pthread_attr_t *attr,
size_t stacksize)
250 if (!attr || (attr->__internal.magic != _PTHREAD_ATTR_MAGIC) ||
251 (stacksize < PTHREAD_STACK_MIN) || (stacksize > (1 << 24)))
257 attr->__internal.stackSize = stacksize;
262 int pthread_attr_getschedparam(
263 const pthread_attr_t *attr,
struct sched_param *param)
268 int pthread_attr_setschedparam(
269 pthread_attr_t *attr,
const struct sched_param *param)
274 int pthread_mutex_init(pthread_mutex_t *mutex,
const pthread_mutexattr_t *attr)
277 syslog(LOG_NOTICE,
"pthread_mutex_init(%x)", mutex);
286 memset(mutex, 0,
sizeof(pthread_mutex_t));
288 mutex->__internal.value = 1;
289 _pthread_make_invalid(mutex->__internal.owner);
290 mutex->__internal.waiter = _pedigree_create_waiter();
294 mutex->__internal.attr = *attr;
300 int pthread_mutex_destroy(pthread_mutex_t *mutex)
303 syslog(LOG_NOTICE,
"pthread_mutex_destroy(%x)", mutex);
312 mutex->__internal.value = 0;
313 _pedigree_destroy_waiter(mutex->__internal.waiter);
315 memset(mutex, 0,
sizeof(pthread_mutex_t));
320 int pthread_mutex_lock(pthread_mutex_t *mutex)
324 LOG_NOTICE,
"pthread_mutex_lock(%p) [return: %p]", mutex,
325 __builtin_return_address(0));
343 int r = pthread_mutex_trylock(mutex);
344 if ((r < 0) && (errno != EBUSY))
357 if (_pedigree_thread_wait_for(mutex->__internal.waiter) < 0)
366 int pthread_mutex_trylock(pthread_mutex_t *mutex)
369 syslog(LOG_NOTICE,
"pthread_mutex_trylock(%p)", mutex);
378 int32_t val = mutex->__internal.value;
381 if (__sync_bool_compare_and_swap(
382 &mutex->__internal.value, val, val - 1))
386 if (mutex->__internal.attr.__internal.type == PTHREAD_MUTEX_RECURSIVE)
388 if (pthread_equal(pthread_self(), mutex->__internal.owner))
391 if (__sync_bool_compare_and_swap(
392 &mutex->__internal.value, val, val - 1))
400 mutex->__internal.owner = pthread_self();
407 int pthread_mutex_unlock(pthread_mutex_t *mutex)
410 syslog(LOG_NOTICE,
"pthread_mutex_unlock(%x)", mutex);
420 if (!_pthread_is_valid(mutex->__internal.owner))
427 if (!pthread_equal(mutex->__internal.owner, pthread_self()))
434 int32_t val = mutex->__internal.value;
435 if (!__sync_bool_compare_and_swap(&mutex->__internal.value, val, val + 1))
438 syslog(LOG_ALERT,
"CaS failed in pthread_mutex_unlock!");
449 _pthread_make_invalid(mutex->__internal.owner);
450 _pedigree_thread_trigger(mutex->__internal.waiter);
455 int pthread_mutexattr_init(pthread_mutexattr_t *attr)
457 attr->__internal.type = PTHREAD_MUTEX_DEFAULT;
461 int pthread_mutexattr_destroy(pthread_mutexattr_t *attr)
466 int pthread_mutexattr_gettype(
const pthread_mutexattr_t *attr,
int *type)
468 *type = attr->__internal.type;
472 int pthread_mutexattr_settype(pthread_mutexattr_t *attr,
int type)
475 attr->__internal.type = type;
490 int pthread_cond_init(pthread_cond_t *cond,
const pthread_condattr_t *attr)
493 syslog(LOG_NOTICE,
"pthread_cond_init(%x)", cond);
502 int ret = pthread_mutex_init(cond, 0);
505 LOG_NOTICE,
"pthread_cond_init: returning %d from mutex init [%s]\n",
506 ret, strerror(errno));
512 int pthread_cond_destroy(pthread_cond_t *cond)
515 syslog(LOG_NOTICE,
"pthread_cond_destroy(%x)", cond);
524 return pthread_mutex_destroy(cond);
527 int pthread_cond_broadcast(pthread_cond_t *cond)
530 syslog(LOG_NOTICE,
"pthread_cond_broadcast(%x)", cond);
541 __sync_fetch_and_sub(&cond->__internal.value, 1);
542 }
while (_pedigree_thread_trigger(cond->__internal.waiter) > 0);
547 int pthread_cond_signal(pthread_cond_t *cond)
550 syslog(LOG_NOTICE,
"pthread_cond_signal(%x)", cond);
553 return pthread_mutex_unlock(cond);
556 int pthread_cond_timedwait(
557 pthread_cond_t *cond, pthread_mutex_t *mutex,
const struct timespec *tm)
560 syslog(LOG_NOTICE,
"pthread_cond_timedwait(%x)", cond);
567 int pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex)
570 syslog(LOG_NOTICE,
"pthread_cond_wait(%x, %x)", cond, mutex);
573 if ((!cond) || (!mutex))
580 e = pthread_mutex_unlock(mutex);
583 e = pthread_mutex_lock(cond);
584 pthread_mutex_lock(mutex);
589 int pthread_condattr_destroy(pthread_condattr_t *attr)
594 int pthread_condattr_init(pthread_condattr_t *attr)
596 attr->__internal.clock_id = CLOCK_MONOTONIC;
600 int pthread_condattr_getclock(
601 const pthread_condattr_t *restrict attr, clockid_t *restrict clock_id)
603 *clock_id = attr->__internal.clock_id;
607 int pthread_condattr_setclock(pthread_condattr_t *attr, clockid_t clock_id)
609 attr->__internal.clock_id = clock_id;
613 void *pthread_getspecific(pthread_key_t key)
615 uintptr_t result = syscall1(POSIX_PTHREAD_GETSPECIFIC, (
long) &key);
616 return (
void *) result;
619 int pthread_setspecific(pthread_key_t key,
const void *data)
621 return syscall2(POSIX_PTHREAD_SETSPECIFIC, (
long) &key, (
long) data);
624 int pthread_key_create(pthread_key_t *key,
void (*destructor)(
void *))
626 return syscall2(POSIX_PTHREAD_KEY_CREATE, (
long) key, (
long) destructor);
629 typedef void (*key_destructor)(
void *);
631 key_destructor pthread_key_destructor(pthread_key_t key)
633 uintptr_t result = syscall1(POSIX_PTHREAD_KEY_DESTRUCTOR, (
long) &key);
634 return (key_destructor) result;
637 int pthread_key_delete(pthread_key_t key)
642 void *buff = pthread_getspecific(key);
643 pthread_setspecific(key, 0);
644 key_destructor a = pthread_key_destructor(key);
647 return syscall1(POSIX_PTHREAD_KEY_DELETE, (
long) &key);
650 int pthread_rwlockattr_init(pthread_rwlockattr_t *attr)
655 int pthread_rwlock_destroy(pthread_rwlock_t *lock)
658 syslog(LOG_NOTICE,
"pthread_rwlock_destroy(%x)", lock);
661 return pthread_mutex_destroy(&lock->mutex);
664 int pthread_rwlock_init(
665 pthread_rwlock_t *lock,
const pthread_rwlockattr_t *attr)
668 syslog(LOG_NOTICE,
"pthread_rwlock_init(%x)", lock);
671 return pthread_mutex_init(&lock->mutex, 0);
674 int pthread_rwlock_rdlock(pthread_rwlock_t *lock)
677 syslog(LOG_NOTICE,
"pthread_rwlock_rdlock(%x)", lock);
680 return pthread_mutex_lock(&lock->mutex);
683 int pthread_rwlock_tryrdlock(pthread_rwlock_t *lock)
686 syslog(LOG_NOTICE,
"pthread_rwlock_tryrdlock(%x)", lock);
689 return pthread_mutex_trylock(&lock->mutex);
692 int pthread_rwlock_trywrlock(pthread_rwlock_t *lock)
695 syslog(LOG_NOTICE,
"pthread_rwlock_trywrlock(%x)", lock);
698 return pthread_mutex_trylock(&lock->mutex);
701 int pthread_rwlock_unlock(pthread_rwlock_t *lock)
704 syslog(LOG_NOTICE,
"pthread_rwlock_unlock(%x)", lock);
707 return pthread_mutex_unlock(&lock->mutex);
710 int pthread_rwlock_wrlock(pthread_rwlock_t *lock)
713 syslog(LOG_NOTICE,
"pthread_rwlock_wrlock(%x)", lock);
716 return pthread_mutex_lock(&lock->mutex);
719 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr)
724 int pthread_spin_init(pthread_spinlock_t *lock,
int pshared)
732 lock->__internal.atom = 1;
733 lock->__internal.owner = pthread_self();
734 _pthread_make_invalid(lock->__internal.locker);
738 int pthread_spin_destroy(pthread_spinlock_t *lock)
746 if (_pthread_is_valid(lock->__internal.locker))
752 _pthread_make_invalid(lock->__internal.locker);
753 _pthread_make_invalid(lock->__internal.owner);
757 int pthread_spin_lock(pthread_spinlock_t *lock)
766 while (!(r = pthread_spin_trylock(lock)))
768 if (pthread_equal(lock->__internal.locker, pthread_self()))
779 lock->__internal.locker = pthread_self();
784 int pthread_spin_trylock(pthread_spinlock_t *lock)
792 if (!__sync_bool_compare_and_swap(&lock->__internal.atom, 1, 0))
798 lock->__internal.locker = pthread_self();
803 int pthread_spin_unlock(pthread_spinlock_t *lock)
812 if (!_pthread_is_valid(lock->__internal.locker))
818 _pthread_make_invalid(lock->__internal.locker);
819 __sync_bool_compare_and_swap(&lock->__internal.atom, 0, 1);