Kernel/LibC: Add basic support for pthread_{create,exit}
This commit is contained in:
@@ -17,6 +17,7 @@ set(LIBC_SOURCES
|
||||
netdb.cpp
|
||||
poll.cpp
|
||||
printf_impl.cpp
|
||||
pthread.cpp
|
||||
pwd.cpp
|
||||
scanf_impl.cpp
|
||||
setjmp.cpp
|
||||
|
||||
@@ -90,6 +90,8 @@ __BEGIN_DECLS
|
||||
O(SYS_FSYNC, fsync) \
|
||||
O(SYS_SYMLINKAT, symlinkat) \
|
||||
O(SYS_HARDLINKAT, hardlinkat) \
|
||||
O(SYS_PTHREAD_CREATE, pthread_create) \
|
||||
O(SYS_PTHREAD_EXIT, pthread_exit) \
|
||||
|
||||
enum Syscall
|
||||
{
|
||||
|
||||
49
userspace/libraries/LibC/pthread.cpp
Normal file
49
userspace/libraries/LibC/pthread.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include <BAN/Assert.h>
|
||||
|
||||
#include <pthread.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
struct pthread_trampoline_info_t
|
||||
{
|
||||
void* (*start_routine)(void*);
|
||||
void* arg;
|
||||
};
|
||||
|
||||
static void pthread_trampoline(void* arg)
|
||||
{
|
||||
pthread_trampoline_info_t info;
|
||||
memcpy(&info, arg, sizeof(pthread_trampoline_info_t));
|
||||
free(arg);
|
||||
|
||||
pthread_exit(info.start_routine(info.arg));
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
|
||||
int pthread_create(pthread_t* __restrict thread, const pthread_attr_t* __restrict attr, void* (*start_routine)(void*), void* __restrict arg)
|
||||
{
|
||||
auto* info = static_cast<pthread_trampoline_info_t*>(malloc(sizeof(pthread_trampoline_info_t)));
|
||||
if (info == nullptr)
|
||||
return -1;
|
||||
info->start_routine = start_routine;
|
||||
info->arg = arg;
|
||||
|
||||
const auto ret = syscall(SYS_PTHREAD_CREATE, attr, pthread_trampoline, info);
|
||||
if (ret == -1)
|
||||
{
|
||||
free(info);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (thread)
|
||||
*thread = ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void pthread_exit(void* value_ptr)
|
||||
{
|
||||
syscall(SYS_PTHREAD_EXIT, value_ptr);
|
||||
ASSERT_NOT_REACHED();
|
||||
}
|
||||
8
userspace/tests/test-pthread/CMakeLists.txt
Normal file
8
userspace/tests/test-pthread/CMakeLists.txt
Normal file
@@ -0,0 +1,8 @@
|
||||
set(SOURCES
|
||||
main.cpp
|
||||
)
|
||||
|
||||
add_executable(test-pthread ${SOURCES})
|
||||
banan_link_library(test-pthread libc)
|
||||
|
||||
install(TARGETS test-pthread OPTIONAL)
|
||||
28
userspace/tests/test-pthread/main.cpp
Normal file
28
userspace/tests/test-pthread/main.cpp
Normal file
@@ -0,0 +1,28 @@
|
||||
#include <stdio.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void* thread_func(void*)
|
||||
{
|
||||
printf("hello from thread\n");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
pthread_t tid;
|
||||
|
||||
printf("creating thread\n");
|
||||
|
||||
if (pthread_create(&tid, nullptr, &thread_func, nullptr) == -1)
|
||||
{
|
||||
perror("pthread_create");
|
||||
return 1;
|
||||
}
|
||||
|
||||
sleep(1);
|
||||
|
||||
printf("exiting\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user