diff options
author | Jari Vetoniemi <mailroxas@gmail.com> | 2018-02-25 15:25:06 +0200 |
---|---|---|
committer | Jari Vetoniemi <mailroxas@gmail.com> | 2018-02-25 15:25:06 +0200 |
commit | 1805da1c85dffe2f8e018a5a9278d6af35276147 (patch) | |
tree | b9e40244cb8e8a9f087a0faa5d88cacb99585965 /src | |
parent | c4f2f8449ad09301e5725f69b7374d958cc5dff8 (diff) |
pthread: Implement more pthread functions
Diffstat (limited to 'src')
-rw-r--r-- | src/libpthread.c | 149 |
1 files 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,11 +3,41 @@ #include <unistd.h> #include <memory.h> #include <pthread.h> +#include <semaphore.h> #include <assert.h> #include <sys/mman.h> 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__) int32_t __private[10]; #else @@ -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"); @@ -96,6 +126,105 @@ bionic_pthread_cond_timedwait_monotonic_np(bionic_cond_t *cond, bionic_mutex_t * } 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) { assert(attr && IS_MAPPED(attr)); @@ -170,6 +299,14 @@ bionic_pthread_mutex_lock(bionic_mutex_t *mutex) } 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) { assert(mutex); @@ -207,6 +344,14 @@ bionic_pthread_cond_init(bionic_cond_t *cond, const bionic_condattr_t *attr) } 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) { assert(cond); |