diff --git a/.gitignore b/.gitignore index 52ed47c..6912295 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,5 @@ docs/out/ .*/ *~ *.bak +*.sh +.clangd \ No newline at end of file diff --git a/include/calico/system/thread.h b/include/calico/system/thread.h index c383bc4..12a9d17 100644 --- a/include/calico/system/thread.h +++ b/include/calico/system/thread.h @@ -135,6 +135,10 @@ void threadPrepare(Thread* t, ThreadFunc entrypoint, void* arg, void* stack_top, //! @brief Returns the required size for thread-local storage (8-byte aligned) @see threadAttachLocalStorage size_t threadGetLocalStorageSize(void); +// Sets an extra amount of thread-local storage to be allocated for threads created using +// system calls (POSIX threads, C threads, C++ std::thread). Will be 8-byte aligned. +void threadSetPthreadExtraTls(const size_t size); + /*! @brief Attaches thread-local storage to a @ref Thread @p t @param[in] storage 8-byte aligned memory buffer to use as thread-local storage, or NULL to consume thread stack memory instead diff --git a/source/system/newlib_syscalls.c b/source/system/newlib_syscalls.c index 3231907..c491862 100644 --- a/source/system/newlib_syscalls.c +++ b/source/system/newlib_syscalls.c @@ -133,6 +133,14 @@ int __SYSCALL(cond_wait_recursive)(_COND_T* cond, _LOCK_RECURSIVE_T* lock, uint6 return 0; } +static size_t extraTls = 0; + +void threadSetPthreadExtraTls(const size_t size) +{ + // make sure it's 8-byte aligned + extraTls = (size + 7) &~ 7; +} + int __SYSCALL(thread_create)(struct __pthread_t** thread, void* (*func)(void*), void* arg, void* stack_addr, size_t stack_size) { if (((uptr)stack_addr & 7) || (stack_size & 7)) { @@ -145,7 +153,7 @@ int __SYSCALL(thread_create)(struct __pthread_t** thread, void* (*func)(void*), size_t struct_sz = (sizeof(struct __pthread_t) + 7) &~ 7; - size_t needed_sz = struct_sz + threadGetLocalStorageSize(); + size_t needed_sz = struct_sz + threadGetLocalStorageSize() + extraTls; if (!stack_addr) { needed_sz += stack_size; }