diff --git a/lib/libc/amd64/entry.S b/lib/libc/amd64/entry.S index 448e144..2279bae 100644 --- a/lib/libc/amd64/entry.S +++ b/lib/libc/amd64/entry.S @@ -7,6 +7,7 @@ .globl _start _start: + call __pthread_init call main movq %rax, %rdi call OSExit diff --git a/lib/libc/posix/pthread.c b/lib/libc/posix/pthread.c index 0631ad6..d4dc3e7 100644 --- a/lib/libc/posix/pthread.c +++ b/lib/libc/posix/pthread.c @@ -1,5 +1,7 @@ +#include #include +#include #include #include @@ -7,6 +9,8 @@ #include #include +#include + #include #include @@ -17,6 +21,7 @@ struct pthread_attr { struct pthread { uint64_t tid; int errno; + TAILQ_ENTRY(pthread) threadTable; // Initialization void *(*entry)(void *); @@ -24,13 +29,60 @@ struct pthread { // Termination void *result; + + // Condition Variables + TAILQ_ENTRY(pthread) threadTable; }; +typedef TAILQ_HEAD(pthreadList, pthread) pthreadList; + +#define THREAD_HASH_SLOTS 32 + +static CoreMutex __threadTableLock; +static pthreadList __threads[THREAD_HASH_SLOTS]; + +void +__pthread_init(void) +{ + int i; + struct pthread *thr = (struct pthread *)malloc(sizeof(*thr)); + + for (i = 0; i < THREAD_HASH_SLOTS; i++) { + TAILQ_INIT(&__threads[i]); + } + + if (thr == NULL) { + abort(); + } + + thr->tid = OSGetTID(); + thr->entry = NULL; + thr->arg = 0; + + CoreMutex_Init(&__threadTableLock); + + CoreMutex_Lock(&__threadTableLock); + TAILQ_INSERT_HEAD(&__threads[thr->tid % THREAD_HASH_SLOTS], thr, threadTable); + CoreMutex_Unlock(&__threadTableLock); +} + pthread_t pthread_self(void) { - // XXX Implement - return NULL; + int tid = OSGetTID(); + struct pthread *thr; + + CoreMutex_Lock(&__threadTableLock); + TAILQ_FOREACH(thr, &__threads[tid % THREAD_HASH_SLOTS], threadTable) { + if (thr->tid == tid) { + CoreMutex_Unlock(&__threadTableLock); + return thr; + } + } + CoreMutex_Unlock(&__threadTableLock); + + printf("pthread_self failed to find current thread!\n"); + abort(); } void @@ -66,6 +118,10 @@ pthread_create(pthread_t *thread, const pthread_attr_t *attr, thr->tid = SYSCALL_VALUE(status); + CoreMutex_Lock(&__threadTableLock); + TAILQ_INSERT_HEAD(&__threads[thr->tid % THREAD_HASH_SLOTS], thr, threadTable); + CoreMutex_Unlock(&__threadTableLock); + *thread = thr; return 0; @@ -92,6 +148,10 @@ pthread_join(pthread_t thread, void **value_ptr) *value_ptr = (void *)thr->result; + CoreMutex_Lock(&__threadTableLock); + TAILQ_REMOVE(&__threads[thr->tid % THREAD_HASH_SLOTS], thr, threadTable); + CoreMutex_Unlock(&__threadTableLock); + // Cleanup free(thr);