diff options
Diffstat (limited to 'src/Platform/Posix/Thread.c')
| -rw-r--r-- | src/Platform/Posix/Thread.c | 98 |
1 files changed, 98 insertions, 0 deletions
diff --git a/src/Platform/Posix/Thread.c b/src/Platform/Posix/Thread.c new file mode 100644 index 0000000..1771eb6 --- /dev/null +++ b/src/Platform/Posix/Thread.c @@ -0,0 +1,98 @@ +#include "Thread.h" + +#include <BH/Thread.h> +#include <limits.h> +#include <stdlib.h> + + +struct BH_ThreadContext +{ + BH_ThreadCallback callback; + void *data; +}; + + +static void *BH_ThreadRun(void *context) +{ + BH_ThreadCallback callback; + void *data, *result; + + callback = ((struct BH_ThreadContext *)context)->callback; + data = ((struct BH_ThreadContext *)context)->data; + free(context); + + callback(data); + BH_TssCleanup(); + + pthread_exit(0); +} + + +static int BH_ThreadInit(BH_Thread *thread, + size_t stack, + BH_ThreadCallback callback, + void *data) +{ + struct BH_ThreadContext *context; + pthread_attr_t attributes; + int result; + + context = malloc(sizeof(*context)); + if (!context) + return BH_ERROR; + context->callback = callback; + context->data = data; + + /* Create thread with specified stack size */ + pthread_attr_init(&attributes); + + if (!stack) + result = pthread_create(&thread->handle, NULL, BH_ThreadRun, context); + else + { + if (stack < PTHREAD_STACK_MIN) + stack = PTHREAD_STACK_MIN; + pthread_attr_setstacksize(&attributes, stack); + result = pthread_create(&thread->handle, &attributes, BH_ThreadRun, context); + } + + pthread_attr_destroy(&attributes); + return result; +} + + +BH_Thread *BH_ThreadNew(size_t stack, + BH_ThreadCallback callback, + void *data) +{ + BH_Thread *thread; + + thread = malloc(sizeof(BH_Thread)); + if (thread && BH_ThreadInit(thread, stack, callback, data)) + { + free(thread); + return NULL; + } + + return thread; +} + + +int BH_ThreadJoin(BH_Thread *thread) +{ + if (pthread_join(thread->handle, NULL)) + return BH_ERROR; + + free(thread); + return BH_OK; +} + + +int BH_ThreadDetach(BH_Thread *thread) +{ + if (pthread_detach(thread->handle)) + return BH_ERROR; + + free(thread); + return BH_OK; +} |
