Skip to content

Commit 02f3cea

Browse files
committed
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.
1 parent 7a61919 commit 02f3cea

File tree

3 files changed

+154
-0
lines changed

3 files changed

+154
-0
lines changed

src/native/pthread.cc

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
#include "pthread.h"
2+
3+
#include <ebbrt/EventManager.h>
4+
#include <ebbrt/Future.h>
5+
#include <ebbrt/LocalIdMap.h>
6+
#include <ebbrt/SpinBarrier.h>
7+
#include <ebbrt/UniqueIOBuf.h>
8+
#include <ebbrt/native/Cpu.h>
9+
10+
static std::vector<ebbrt::Future<uint32_t>> vecfut_;
11+
static std::unordered_map<uint32_t, ebbrt::Promise<uint32_t>> mmap_;
12+
static uint64_t tid_;
13+
14+
ebbrt::SpinLock spinlock_;
15+
16+
void pthread_attr_init(pthread_attr_t* attr) {
17+
vecfut_.clear();
18+
mmap_.clear();
19+
tid_ = 0;
20+
}
21+
22+
int pthread_create(pthread_t* th, pthread_attr_t* attr, void* (*func)(void*),
23+
void* arg) {
24+
25+
*th = reinterpret_cast<pthread_t>(tid_);
26+
size_t tid = reinterpret_cast<size_t>(tid_);
27+
28+
ebbrt::Promise<uint32_t> promise;
29+
bool inserted;
30+
auto f = promise.GetFuture();
31+
vecfut_.push_back(std::move(f));
32+
std::tie(std::ignore, inserted) = mmap_.emplace(tid, std::move(promise));
33+
34+
ebbrt::event_manager->SpawnRemote(
35+
[func, arg, tid]() {
36+
func((void*)arg);
37+
38+
std::lock_guard<ebbrt::SpinLock> l(spinlock_);
39+
{
40+
auto it = mmap_.find(tid);
41+
assert(it != mmap_.end());
42+
it->second.SetValue(tid);
43+
mmap_.erase(it);
44+
}
45+
},
46+
tid);
47+
48+
tid_++;
49+
50+
return 0;
51+
}
52+
53+
int pthread_join(pthread_t threadn, void** value_ptr) {
54+
size_t tid = static_cast<size_t>(threadn);
55+
vecfut_[tid].Block();
56+
57+
return 0;
58+
}

src/native/pthread.h

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
#ifndef BAREMETAL_SRC_INCLUDE_EBBRT_PTHREAD_H_
2+
#define BAREMETAL_SRC_INCLUDE_EBBRT_PTHREAD_H_
3+
4+
#include "sched.h"
5+
#include <ebbrt/Debug.h>
6+
#include <ebbrt/EventManager.h>
7+
#include <ebbrt/SpinLock.h>
8+
9+
extern "C" {
10+
typedef unsigned long pthread_t;
11+
typedef unsigned int pthread_key_t;
12+
typedef struct {
13+
int is_initialized;
14+
void* stackaddr;
15+
int stacksize;
16+
int contentionscope;
17+
int inheritsched;
18+
int schedpolicy;
19+
sched_param schedparam;
20+
int detachstate;
21+
} pthread_attr_t;
22+
23+
typedef struct {
24+
} pthread_barrier_t;
25+
typedef struct {
26+
} pthread_barrierattr_t;
27+
typedef struct {
28+
} pthread_cond_t;
29+
typedef struct {
30+
} pthread_condattr_t;
31+
typedef struct {
32+
} pthread_mutexattr_t;
33+
typedef struct {
34+
} pthread_rwlock_t;
35+
typedef struct {
36+
} pthread_rwlockattr_t;
37+
typedef struct {
38+
} pthread_spinlock_t;
39+
40+
typedef struct { ebbrt::SpinLock spinlock; } pthread_mutex_t;
41+
42+
void pthread_attr_init(pthread_attr_t* attr);
43+
int pthread_cond_broadcast(pthread_cond_t* cond);
44+
int pthread_cond_signal(pthread_cond_t* cond);
45+
int pthread_cond_timedwait(pthread_cond_t* cond, pthread_mutex_t* mutex,
46+
const struct timespec* abstime);
47+
int pthread_cond_wait(pthread_cond_t* cond, pthread_mutex_t* mutex);
48+
int pthread_cond_destroy(pthread_cond_t* cond);
49+
int pthread_cond_init(pthread_cond_t* __restrict cond,
50+
const pthread_condattr_t* __restrict attr);
51+
52+
pthread_t pthread_self();
53+
int pthread_create(pthread_t*, pthread_attr_t*, void* (*)(void*), void*);
54+
int pthread_join(pthread_t, void**);
55+
int pthread_detach(pthread_t thread);
56+
int pthread_equal(pthread_t t1, pthread_t t2);
57+
58+
void* pthread_getspecific(pthread_key_t key);
59+
int pthread_setspecific(pthread_key_t key, const void* value);
60+
int pthread_key_create(pthread_key_t* key, void (*destructor)(void*));
61+
int pthread_mutexattr_destroy(pthread_mutexattr_t* attr);
62+
int pthread_mutexattr_init(pthread_mutexattr_t* attr);
63+
int pthread_mutexattr_gettype(const pthread_mutexattr_t* __restrict attr,
64+
int* __restrict type);
65+
int pthread_mutexattr_settype(pthread_mutexattr_t* attr, int type);
66+
67+
typedef struct {
68+
} pthread_once_t;
69+
int pthread_once(pthread_once_t* once_control, void (*init_routine)(void));
70+
71+
#define PTHREAD_MUTEX_INITIALIZER \
72+
{ 0 }
73+
#define PTHREAD_COND_INITIALIZER \
74+
{}
75+
#define PTHREAD_ONCE_INIT \
76+
{}
77+
78+
#define PTHREAD_MUTEX_RECURSIVE 33
79+
80+
int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* attr);
81+
int pthread_mutex_lock(pthread_mutex_t* mutex);
82+
int pthread_mutex_trylock(pthread_mutex_t* mutex);
83+
int pthread_mutex_unlock(pthread_mutex_t* mutex);
84+
int pthread_mutex_destroy(pthread_mutex_t* mutex);
85+
86+
} // "C"
87+
88+
#endif

src/native/sched.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#ifndef BAREMETAL_SRC_INCLUDE_EBBRT_SCHED_H_
2+
#define BAREMETAL_SRC_INCLUDE_EBBRT_SCHED_H_
3+
4+
typedef struct { int sched_priority; } sched_param;
5+
6+
extern int sched_yield();
7+
8+
#endif

0 commit comments

Comments
 (0)