From 02f3cea403bb52268992d865b602cd5bfc2f6159 Mon Sep 17 00:00:00 2001 From: Han Date: Mon, 20 Nov 2017 16:30:52 -0500 Subject: [PATCH] feat(pthread): new pthread interface Added experimental pthread_create and pthread_join interfaces that run on top of SpawnRemote and waits on Future for each thread to do the join. --- src/native/pthread.cc | 58 ++++++++++++++++++++++++++++ src/native/pthread.h | 88 +++++++++++++++++++++++++++++++++++++++++++ src/native/sched.h | 8 ++++ 3 files changed, 154 insertions(+) create mode 100644 src/native/pthread.cc create mode 100644 src/native/pthread.h create mode 100644 src/native/sched.h diff --git a/src/native/pthread.cc b/src/native/pthread.cc new file mode 100644 index 00000000..652175e5 --- /dev/null +++ b/src/native/pthread.cc @@ -0,0 +1,58 @@ +#include "pthread.h" + +#include +#include +#include +#include +#include +#include + +static std::vector> vecfut_; +static std::unordered_map> mmap_; +static uint64_t tid_; + +ebbrt::SpinLock spinlock_; + +void pthread_attr_init(pthread_attr_t* attr) { + vecfut_.clear(); + mmap_.clear(); + tid_ = 0; +} + +int pthread_create(pthread_t* th, pthread_attr_t* attr, void* (*func)(void*), + void* arg) { + + *th = reinterpret_cast(tid_); + size_t tid = reinterpret_cast(tid_); + + ebbrt::Promise promise; + bool inserted; + auto f = promise.GetFuture(); + vecfut_.push_back(std::move(f)); + std::tie(std::ignore, inserted) = mmap_.emplace(tid, std::move(promise)); + + ebbrt::event_manager->SpawnRemote( + [func, arg, tid]() { + func((void*)arg); + + std::lock_guard l(spinlock_); + { + auto it = mmap_.find(tid); + assert(it != mmap_.end()); + it->second.SetValue(tid); + mmap_.erase(it); + } + }, + tid); + + tid_++; + + return 0; +} + +int pthread_join(pthread_t threadn, void** value_ptr) { + size_t tid = static_cast(threadn); + vecfut_[tid].Block(); + + return 0; +} diff --git a/src/native/pthread.h b/src/native/pthread.h new file mode 100644 index 00000000..d5bf9819 --- /dev/null +++ b/src/native/pthread.h @@ -0,0 +1,88 @@ +#ifndef BAREMETAL_SRC_INCLUDE_EBBRT_PTHREAD_H_ +#define BAREMETAL_SRC_INCLUDE_EBBRT_PTHREAD_H_ + +#include "sched.h" +#include +#include +#include + +extern "C" { +typedef unsigned long pthread_t; +typedef unsigned int pthread_key_t; +typedef struct { + int is_initialized; + void* stackaddr; + int stacksize; + int contentionscope; + int inheritsched; + int schedpolicy; + sched_param schedparam; + int detachstate; +} pthread_attr_t; + +typedef struct { +} pthread_barrier_t; +typedef struct { +} pthread_barrierattr_t; +typedef struct { +} pthread_cond_t; +typedef struct { +} pthread_condattr_t; +typedef struct { +} pthread_mutexattr_t; +typedef struct { +} pthread_rwlock_t; +typedef struct { +} pthread_rwlockattr_t; +typedef struct { +} pthread_spinlock_t; + +typedef struct { ebbrt::SpinLock spinlock; } pthread_mutex_t; + +void pthread_attr_init(pthread_attr_t* attr); +int pthread_cond_broadcast(pthread_cond_t* cond); +int pthread_cond_signal(pthread_cond_t* cond); +int pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex, + const struct timespec* abstime); +int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex); +int pthread_cond_destroy(pthread_cond_t* cond); +int pthread_cond_init(pthread_cond_t* __restrict cond, + const pthread_condattr_t* __restrict attr); + +pthread_t pthread_self(); +int pthread_create(pthread_t*, pthread_attr_t*, void* (*)(void*), void*); +int pthread_join(pthread_t, void**); +int pthread_detach(pthread_t thread); +int pthread_equal(pthread_t t1, pthread_t t2); + +void* pthread_getspecific(pthread_key_t key); +int pthread_setspecific(pthread_key_t key, const void* value); +int pthread_key_create(pthread_key_t* key, void (*destructor)(void*)); +int pthread_mutexattr_destroy(pthread_mutexattr_t* attr); +int pthread_mutexattr_init(pthread_mutexattr_t* attr); +int pthread_mutexattr_gettype(const pthread_mutexattr_t* __restrict attr, + int* __restrict type); +int pthread_mutexattr_settype(pthread_mutexattr_t* attr, int type); + +typedef struct { +} pthread_once_t; +int pthread_once(pthread_once_t* once_control, void (*init_routine)(void)); + +#define PTHREAD_MUTEX_INITIALIZER \ + { 0 } +#define PTHREAD_COND_INITIALIZER \ + {} +#define PTHREAD_ONCE_INIT \ + {} + +#define PTHREAD_MUTEX_RECURSIVE 33 + +int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr); +int pthread_mutex_lock(pthread_mutex_t* mutex); +int pthread_mutex_trylock(pthread_mutex_t* mutex); +int pthread_mutex_unlock(pthread_mutex_t* mutex); +int pthread_mutex_destroy(pthread_mutex_t* mutex); + +} // "C" + +#endif diff --git a/src/native/sched.h b/src/native/sched.h new file mode 100644 index 00000000..0e8f8965 --- /dev/null +++ b/src/native/sched.h @@ -0,0 +1,8 @@ +#ifndef BAREMETAL_SRC_INCLUDE_EBBRT_SCHED_H_ +#define BAREMETAL_SRC_INCLUDE_EBBRT_SCHED_H_ + +typedef struct { int sched_priority; } sched_param; + +extern int sched_yield(); + +#endif