diff --git a/CMakeLists.txt b/CMakeLists.txt index 3046189..b2d0375 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ add_library( tb SHARED tb-utils.c tb-threads.c + tb-tls.c tb-clone.S) add_executable(test-00 test-00.c) @@ -18,3 +19,6 @@ target_link_libraries(test-00 tb) add_executable(test-01 test-01.c) target_link_libraries(test-01 tb) + +add_executable(test-02 test-02.c) +target_link_libraries(test-02 tb) diff --git a/tb-threads.c b/tb-threads.c index 36654ab..db0eb08 100644 --- a/tb-threads.c +++ b/tb-threads.c @@ -93,6 +93,7 @@ int tbthread_create( //---------------------------------------------------------------------------- *thread = malloc(sizeof(struct tbthread)); memset(*thread, 0, sizeof(struct tbthread)); + (*thread)->self = *thread; (*thread)->stack = stack; (*thread)->stack_size = attr->stack_size; (*thread)->fn = f; @@ -102,8 +103,9 @@ int tbthread_create( // Spawn the thread //---------------------------------------------------------------------------- int flags = CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SYSVSEM | CLONE_SIGHAND; - flags |= CLONE_THREAD; - int tid = tbclone(start_thread, *thread, flags, stack+attr->stack_size); + flags |= CLONE_THREAD | CLONE_SETTLS; + int tid = tbclone(start_thread, *thread, flags, stack+attr->stack_size, + 0, 0, *thread); if(tid < 0) { tbmunmap(stack, attr->stack_size); free(*thread); diff --git a/tb-tls.c b/tb-tls.c new file mode 100644 index 0000000..73ab89d --- /dev/null +++ b/tb-tls.c @@ -0,0 +1,30 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2016 by Lukasz Janyst +//------------------------------------------------------------------------------ +// This file is part of thread-bites. +// +// thread-bites is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// thread-bites is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with thread-bites. If not, see . +//------------------------------------------------------------------------------ + +#include "tb.h" + +//------------------------------------------------------------------------------ +// Get the pointer of the currently running thread +//------------------------------------------------------------------------------ +tbthread_t tbthread_self() +{ + tbthread_t self; + asm("movq %%fs:0, %0\n\t" : "=r" (self)); + return self; +} diff --git a/tb.h b/tb.h index 4424ee5..7a54a50 100644 --- a/tb.h +++ b/tb.h @@ -36,6 +36,7 @@ typedef struct //------------------------------------------------------------------------------ typedef struct tbthread { + struct tbthread *self; void *stack; uint32_t stack_size; void *(*fn)(void *); @@ -43,12 +44,17 @@ typedef struct tbthread } *tbthread_t; //------------------------------------------------------------------------------ -// Function prototypes, look in the c files for descriptions +// General threading //------------------------------------------------------------------------------ void tbthread_attr_init(tbthread_attr_t *attr); int tbthread_create(tbthread_t *thread, const tbthread_attr_t *attrs, void *(*f)(void *), void *arg); +//------------------------------------------------------------------------------ +// TLS +//------------------------------------------------------------------------------ +tbthread_t tbthread_self(); + //------------------------------------------------------------------------------ // Utility functions //------------------------------------------------------------------------------ diff --git a/test-02.c b/test-02.c new file mode 100644 index 0000000..fd60ffa --- /dev/null +++ b/test-02.c @@ -0,0 +1,61 @@ +//------------------------------------------------------------------------------ +// Copyright (c) 2016 by Lukasz Janyst +//------------------------------------------------------------------------------ +// This file is part of thread-bites. +// +// thread-bites is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// thread-bites is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with thread-bites. If not, see . +//------------------------------------------------------------------------------ + +#include +#include + +//------------------------------------------------------------------------------ +// Thread function +//------------------------------------------------------------------------------ +void *thread_func(void *arg) +{ + int num = *(int*)arg; + int i; + + tbprint("Hello from thread #%d, ptr: 0x%llx\n", num, tbthread_self()); + + return 0; +} + +//------------------------------------------------------------------------------ +// Start the show +//------------------------------------------------------------------------------ +int main(int argc, char **argv) +{ + tbthread_t thread[5]; + int targ[5]; + tbthread_attr_t attr; + void *ret; + int st; + tbthread_attr_init(&attr); + for(int i = 0; i < 5; ++i) { + targ[i] = i; + st = tbthread_create(&thread[i], &attr, thread_func, &targ[i]); + if(st != 0) { + tbprint("Failed to spawn thread %d: %s\n", i, strerror(-st)); + return 1; + } + } + + tbprint("Threads spawned successfully\n"); + + tbsleep(3); + + return 0; +};