Improving pthread support
This commit is contained in:
parent
dd0a1d5612
commit
289412b585
@ -11,6 +11,7 @@
|
||||
#define ENOTDIR 0xBAD7
|
||||
#define ENAMETOOLONG 0xBAD8
|
||||
#define ENOSYS 0xBAD9
|
||||
#define EAGAIN 0xBADA
|
||||
|
||||
#endif /* __ERRNO_H__ */
|
||||
|
||||
|
@ -2,12 +2,12 @@
|
||||
#ifndef __PTHREAD_H__
|
||||
#define __PTHREAD_H__
|
||||
|
||||
typedef uint64_t pthread_t;
|
||||
typedef uint64_t pthread_attr_t;
|
||||
typedef uint64_t pthread_barrier_t;
|
||||
typedef uint64_t pthread_barrierattr_t;
|
||||
typedef uint64_t pthread_mutex_t;
|
||||
typedef uint64_t pthread_mutexattr_t;
|
||||
typedef struct pthread *pthread_t;
|
||||
typedef struct pthread_attr *pthread_attr_t;
|
||||
typedef struct pthread_barrier *pthread_barrier_t;
|
||||
typedef struct pthread_barrierattr *pthread_barrierattr_t;
|
||||
typedef struct pthread_mutex *pthread_mutex_t;
|
||||
typedef struct pthread_mutexattr *pthread_mutexattr_t;
|
||||
|
||||
pthread_t pthread_self(void);
|
||||
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
|
@ -1,34 +1,101 @@
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include <syscall.h>
|
||||
#include <sys/syscall.h>
|
||||
|
||||
struct pthread_attr {
|
||||
uint64_t _unused;
|
||||
};
|
||||
|
||||
struct pthread {
|
||||
uint64_t tid;
|
||||
int errno;
|
||||
|
||||
// Initialization
|
||||
void *(*entry)(void *);
|
||||
void *arg;
|
||||
|
||||
// Termination
|
||||
void *result;
|
||||
};
|
||||
|
||||
pthread_t
|
||||
pthread_self(void)
|
||||
{
|
||||
// XXX Implement
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
pthreadCreateHelper(void *arg)
|
||||
{
|
||||
struct pthread *thr = (struct pthread *)arg;
|
||||
|
||||
OSThreadExit((uint64_t)(thr->entry)(thr->arg));
|
||||
}
|
||||
|
||||
int
|
||||
pthread_create(pthread_t *thread, const pthread_attr_t *attr,
|
||||
void *(*start_routine)(void *), void *arg)
|
||||
{
|
||||
uint64_t status;
|
||||
struct pthread *thr;
|
||||
|
||||
thr = malloc(sizeof(*thr));
|
||||
if (!thr) {
|
||||
return EAGAIN;
|
||||
}
|
||||
|
||||
memset(thr, 0, sizeof(*thr));
|
||||
|
||||
thr->entry = start_routine;
|
||||
thr->arg = arg;
|
||||
|
||||
status = OSThreadCreate((uintptr_t)&pthreadCreateHelper, (uint64_t)thr);
|
||||
if (SYSCALL_ERRCODE(status) != 0) {
|
||||
free(thr);
|
||||
return SYSCALL_ERRCODE(status);
|
||||
}
|
||||
|
||||
thr->tid = SYSCALL_VALUE(status);
|
||||
|
||||
*thread = thr;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
pthread_exit(void *value_ptr)
|
||||
{
|
||||
OSThreadExit(value_ptr);
|
||||
struct pthread *thr = pthread_self();
|
||||
|
||||
thr->result = value_ptr;
|
||||
|
||||
OSThreadExit(0);
|
||||
}
|
||||
|
||||
int
|
||||
pthread_join(pthread_t thread, void **value_ptr)
|
||||
{
|
||||
uint64_t value = OSThreadWait(thread);
|
||||
struct pthread *thr = thread;
|
||||
uint64_t status = OSThreadWait(thr->tid);
|
||||
if (status != 0) {
|
||||
return status;
|
||||
}
|
||||
|
||||
*value_ptr = (void *)value;
|
||||
*value_ptr = (void *)thr->result;
|
||||
|
||||
// Cleanup
|
||||
free(thr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
|
Loading…
Reference in New Issue
Block a user