aboutsummaryrefslogtreecommitdiff
path: root/libc/src/pthread/pthread_create.cpp
diff options
context:
space:
mode:
authorNoah Goldstein <goldstein.w.n@gmail.com>2023-04-20 15:05:04 -0500
committerNoah Goldstein <goldstein.w.n@gmail.com>2023-05-22 15:54:19 -0500
commit6a185718d4a29d17a389d0c50419e7e36ac3c866 (patch)
tree6d18fee29d2f2e861f40cea4ad134a7adbe19777 /libc/src/pthread/pthread_create.cpp
parentae5ff3ca0cd923a9fb2b46701641acab3dd15e4b (diff)
downloadllvm-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.cpp62
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;
}