From 1805da1c85dffe2f8e018a5a9278d6af35276147 Mon Sep 17 00:00:00 2001 From: Jari Vetoniemi Date: Sun, 25 Feb 2018 15:25:06 +0200 Subject: pthread: Implement more pthread functions --- src/libpthread.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 147 insertions(+), 2 deletions(-) diff --git a/src/libpthread.c b/src/libpthread.c index 3136632..3016550 100644 --- a/src/libpthread.c +++ b/src/libpthread.c @@ -3,9 +3,39 @@ #include #include #include +#include #include #include +typedef struct { + union { + struct { + unsigned int count; +#ifdef __LP64__ + int __reserved[3]; +#endif + } bionic; + void *glibc; + }; +} bionic_sem_t; + +typedef struct { + union { + struct { + uint32_t flags; + void* stack_base; + size_t stack_size; + size_t guard_size; + int32_t sched_policy; + int32_t sched_priority; +#ifdef __LP64__ + char __reserved[16]; +#endif + } bionic; + void *glibc; + }; +} bionic_attr_t; + typedef struct { union { #if defined(__LP64__) @@ -54,8 +84,8 @@ typedef struct { typedef int bionic_key_t; _Static_assert(sizeof(bionic_key_t) == sizeof(pthread_key_t), "bionic_key_t and pthread_key_t size mismatch"); -typedef int bionic_pthread_once_t; -_Static_assert(sizeof(bionic_pthread_once_t) == sizeof(pthread_once_t), "bionic_pthread_once_t and pthread_once_t size mismatch"); +typedef int bionic_once_t; +_Static_assert(sizeof(bionic_once_t) == sizeof(pthread_once_t), "bionic_once_t and pthread_once_t size mismatch"); typedef long bionic_pthread_t; _Static_assert(sizeof(bionic_pthread_t) == sizeof(pthread_t), "bionic_pthread_t and pthread_t size mismatch"); @@ -95,6 +125,105 @@ bionic_pthread_cond_timedwait_monotonic_np(bionic_cond_t *cond, bionic_mutex_t * return 0; } +int +bionic_sem_destroy(bionic_sem_t *sem) +{ + assert(sem); + int ret = 0; + if (IS_MAPPED(sem)) { + ret = pthread_cond_destroy(sem->glibc); + munmap(sem->glibc, sizeof(sem_t)); + } + return ret; +} + +int +bionic_sem_init(bionic_sem_t *sem, int pshared, unsigned int value) +{ + assert(sem); + if (!IS_MAPPED(sem)) + sem->glibc = mmap(NULL, sizeof(sem_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); + return sem_init(sem->glibc, pshared, value); +} + +int +bionic_sem_post(bionic_sem_t *sem) +{ + assert(sem && IS_MAPPED(sem)); + return sem_post(sem->glibc); +} + +int +bionic_sem_wait(bionic_sem_t *sem) +{ + assert(sem && IS_MAPPED(sem)); + return sem_wait(sem->glibc); +} + +int +bionic_sem_trywait(bionic_sem_t *sem) +{ + assert(sem && IS_MAPPED(sem)); + return sem_trywait(sem->glibc); +} + +int +bionic_sem_timedwait(bionic_sem_t *sem, const struct timespec *abs_timeout) +{ + assert(sem && IS_MAPPED(sem) && abs_timeout); + return sem_timedwait(sem->glibc, abs_timeout); +} + +int +bionic_pthread_attr_destroy(bionic_attr_t *attr) +{ + assert(attr); + int ret = 0; + if (IS_MAPPED(attr)) { + ret = pthread_attr_destroy(attr->glibc); + munmap(attr->glibc, sizeof(pthread_attr_t)); + } + return ret; +} + +int +bionic_pthread_attr_init(bionic_attr_t *attr) +{ + assert(attr); + if (!IS_MAPPED(attr)) + attr->glibc = mmap(NULL, sizeof(pthread_attr_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); + return pthread_attr_init(attr->glibc); +} + +int +bionic_pthread_getattr_np(bionic_pthread_t thread, bionic_attr_t *attr) +{ + assert(thread && attr && !IS_MAPPED(attr)); + attr->glibc = mmap(NULL, sizeof(pthread_attr_t), PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_SHARED, -1, 0); + return pthread_getattr_np(thread, attr->glibc); +} + +int +bionic_pthread_attr_settstack(bionic_attr_t *attr, void *stackaddr, size_t stacksize) +{ + assert(attr && IS_MAPPED(attr)); + return pthread_attr_setstack(attr->glibc, stackaddr, stacksize); +} + +int +bionic_pthread_attr_getstack(const bionic_attr_t *attr, void *stackaddr, size_t *stacksize) +{ + assert(attr && IS_MAPPED(attr)); + return pthread_attr_getstack(attr->glibc, stackaddr, stacksize); +} + +int +bionic_pthread_create(bionic_pthread_t *thread, const bionic_attr_t *attr, void* (*start)(void*), void *arg) +{ + assert(thread && (!attr || IS_MAPPED(attr))); + return pthread_create(thread, (attr ? attr->glibc : NULL), start, arg); +} + int bionic_pthread_mutexattr_settype(bionic_mutexattr_t *attr, int type) { @@ -169,6 +298,14 @@ bionic_pthread_mutex_lock(bionic_mutex_t *mutex) return pthread_mutex_lock(mutex->glibc); } +int +bionic_pthread_mutex_trylock(bionic_mutex_t *mutex) +{ + assert(mutex); + INIT_IF_NOT_MAPPED(mutex, default_pthread_mutex_init); + return pthread_mutex_trylock(mutex->glibc); +} + int bionic_pthread_mutex_unlock(bionic_mutex_t *mutex) { @@ -206,6 +343,14 @@ bionic_pthread_cond_init(bionic_cond_t *cond, const bionic_condattr_t *attr) return pthread_cond_init(cond->glibc, (attr ? attr->glibc : NULL)); } +int +bionic_pthread_cond_broadcast(bionic_cond_t *cond) +{ + assert(cond); + INIT_IF_NOT_MAPPED(cond, default_pthread_cond_init); + return pthread_cond_broadcast(cond->glibc); +} + int bionic_pthread_cond_signal(bionic_cond_t *cond) { -- cgit v1.2.3-70-g09d2