diff options
author | Noah Goldstein <goldstein.w.n@gmail.com> | 2023-04-20 15:05:04 -0500 |
---|---|---|
committer | Noah Goldstein <goldstein.w.n@gmail.com> | 2023-05-22 15:54:19 -0500 |
commit | 6a185718d4a29d17a389d0c50419e7e36ac3c866 (patch) | |
tree | 6d18fee29d2f2e861f40cea4ad134a7adbe19777 /libc/src/pthread/pthread_create.cpp | |
parent | ae5ff3ca0cd923a9fb2b46701641acab3dd15e4b (diff) | |
download | llvm-6a185718d4a29d17a389d0c50419e7e36ac3c866.zip llvm-6a185718d4a29d17a389d0c50419e7e36ac3c866.tar.gz llvm-6a185718d4a29d17a389d0c50419e7e36ac3c866.tar.bz2 |
Support custom attributes in pthread_create
Only functional for stack growsdown (same as before), but custom
`stack`, `stacksize`, `guardsize`, and `detachstate` all should be
working.
Differential Revision: https://reviews.llvm.org/D148290
Diffstat (limited to 'libc/src/pthread/pthread_create.cpp')
-rw-r--r-- | libc/src/pthread/pthread_create.cpp | 62 |
1 files changed, 58 insertions, 4 deletions
diff --git a/libc/src/pthread/pthread_create.cpp b/libc/src/pthread/pthread_create.cpp index 7064125..9eebb80 100644 --- a/libc/src/pthread/pthread_create.cpp +++ b/libc/src/pthread/pthread_create.cpp @@ -8,7 +8,15 @@ #include "pthread_create.h" +#include "pthread_attr_destroy.h" +#include "pthread_attr_init.h" + +#include "pthread_attr_getdetachstate.h" +#include "pthread_attr_getguardsize.h" +#include "pthread_attr_getstack.h" + #include "src/__support/common.h" +#include "src/__support/macros/optimization.h" #include "src/__support/threads/thread.h" #include <errno.h> @@ -20,12 +28,58 @@ static_assert(sizeof(pthread_t) == sizeof(__llvm_libc::Thread), "Mismatch between pthread_t and internal Thread."); LLVM_LIBC_FUNCTION(int, pthread_create, - (pthread_t *__restrict th, const pthread_attr_t *__restrict, + (pthread_t *__restrict th, + const pthread_attr_t *__restrict attr, __pthread_start_t func, void *arg)) { + pthread_attr_t default_attr; + if (attr == nullptr) { + // We failed to initialize attributes (should be impossible) + if (LIBC_UNLIKELY(__llvm_libc::pthread_attr_init(&default_attr) != 0)) + return EINVAL; + + attr = &default_attr; + } + + void *stack; + size_t stacksize, guardsize; + int detachstate; + + // As of writing this all the `pthread_attr_get*` functions always succeed. + if (LIBC_UNLIKELY( + __llvm_libc::pthread_attr_getstack(attr, &stack, &stacksize) != 0)) + return EINVAL; + + if (LIBC_UNLIKELY(__llvm_libc::pthread_attr_getguardsize(attr, &guardsize) != + 0)) + return EINVAL; + + if (LIBC_UNLIKELY( + __llvm_libc::pthread_attr_getdetachstate(attr, &detachstate) != 0)) + return EINVAL; + + if (attr == &default_attr) + // Should we fail here? Its non-issue as the moment as pthread_attr_destroy + // can only succeed. + if (LIBC_UNLIKELY(__llvm_libc::pthread_attr_destroy(&default_attr) != 0)) + return EINVAL; + + if (stacksize && stacksize < PTHREAD_STACK_MIN) + return EINVAL; + + if (guardsize % EXEC_PAGESIZE != 0) + return EINVAL; + + if (detachstate != PTHREAD_CREATE_DETACHED && + detachstate != PTHREAD_CREATE_JOINABLE) + return EINVAL; + + // Thread::run will check validity of the `stack` argument (stack alignment is + // universal, not sure a pthread requirement). + auto *thread = reinterpret_cast<__llvm_libc::Thread *>(th); - // TODO: Use the attributes parameter to set up thread properties. - int result = thread->run(func, arg, nullptr, 0); - if (result != 0 && result != EPERM) + int result = thread->run(func, arg, stack, stacksize, guardsize, + detachstate == PTHREAD_CREATE_DETACHED); + if (result != 0 && result != EPERM && result != EINVAL) return EAGAIN; return result; } |