From 901c3d44b047f83b914f7a3cd1f532964255771a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Tue, 5 Mar 2019 21:07:25 +0100 Subject: [PATCH] pthread: implement pthread_attr_[get|set]stack. remove pthread_attr_[get|set]stackaddr from unimplemented functions. Change-Id: I58807e86c75a189a576639ae1b2e4505a63700a5 Reviewed-on: https://review.haiku-os.org/c/1152 Reviewed-by: waddlesplash --- headers/posix/pthread.h | 16 ++---- headers/private/libroot/pthread_private.h | 1 + src/system/libroot/posix/pthread/pthread.cpp | 5 +- .../libroot/posix/pthread/pthread_attr.c | 41 +++++++++++++++ src/tests/system/libroot/posix/Jamfile | 1 + .../libroot/posix/pthread_attr_stack_test.cpp | 52 +++++++++++++++++++ 6 files changed, 103 insertions(+), 13 deletions(-) create mode 100644 src/tests/system/libroot/posix/pthread_attr_stack_test.cpp diff --git a/headers/posix/pthread.h b/headers/posix/pthread.h index bd2f7f85c1..3a07eea80f 100644 --- a/headers/posix/pthread.h +++ b/headers/posix/pthread.h @@ -209,6 +209,11 @@ extern int pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize); extern int pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize); +extern int pthread_attr_getstack(const pthread_attr_t *attr, + void **stackaddr, size_t *stacksize); +extern int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, + size_t stacksize); + #if 0 /* Unimplemented attribute functions: */ /* [TPS] */ @@ -220,19 +225,8 @@ extern int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy); extern int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy); -/* [TSA] */ -extern int pthread_attr_getstackaddr(const pthread_attr_t *attr, - void **stackaddr); -extern int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr); - -/* [TSA TSS] */ -extern int pthread_attr_getstack(const pthread_attr_t *attr, - void **stackaddr, size_t *stacksize); -extern int pthread_attr_setstack(pthread_attr_t *attr, void *stackaddr, size_t stacksize); - #endif /* 0 */ - /* thread functions */ extern int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void*), void *arg); diff --git a/headers/private/libroot/pthread_private.h b/headers/private/libroot/pthread_private.h index 41b3401bcd..850ff3c730 100644 --- a/headers/private/libroot/pthread_private.h +++ b/headers/private/libroot/pthread_private.h @@ -46,6 +46,7 @@ typedef struct _pthread_attr { int32 sched_priority; size_t stack_size; size_t guard_size; + void *stack_address; } pthread_attr; typedef struct _pthread_rwlockattr { diff --git a/src/system/libroot/posix/pthread/pthread.cpp b/src/system/libroot/posix/pthread/pthread.cpp index 59e4c1ea99..807fd7f849 100644 --- a/src/system/libroot/posix/pthread/pthread.cpp +++ b/src/system/libroot/posix/pthread/pthread.cpp @@ -27,7 +27,8 @@ static pthread_attr pthread_attr_default = { PTHREAD_CREATE_JOINABLE, B_NORMAL_PRIORITY, USER_STACK_SIZE, - USER_STACK_GUARD_SIZE + USER_STACK_GUARD_SIZE, + NULL }; @@ -119,7 +120,7 @@ __pthread_init_creation_attributes(const pthread_attr_t* pthreadAttributes, attributes->priority = attr->sched_priority; attributes->args1 = argument1; attributes->args2 = argument2; - attributes->stack_address = NULL; + attributes->stack_address = attr->stack_address; attributes->stack_size = attr->stack_size; attributes->guard_size = attr->guard_size; attributes->pthread = thread; diff --git a/src/system/libroot/posix/pthread/pthread_attr.c b/src/system/libroot/posix/pthread/pthread_attr.c index fecb9fca5b..9ae6a3e8c4 100644 --- a/src/system/libroot/posix/pthread/pthread_attr.c +++ b/src/system/libroot/posix/pthread/pthread_attr.c @@ -33,6 +33,7 @@ pthread_attr_init(pthread_attr_t *_attr) attr->sched_priority = B_NORMAL_PRIORITY; attr->stack_size = USER_STACK_SIZE; attr->guard_size = USER_STACK_GUARD_SIZE; + attr->stack_address = NULL; *_attr = attr; return B_OK; @@ -194,3 +195,43 @@ pthread_attr_setguardsize(pthread_attr_t *_attr, size_t guardsize) return 0; } + + +int +pthread_attr_getstack(const pthread_attr_t *_attr, void **stackaddr, + size_t *stacksize) +{ + pthread_attr *attr; + + if (_attr == NULL || (attr = *_attr) == NULL || stackaddr == NULL + || stacksize == NULL) { + return B_BAD_VALUE; + } + + *stacksize = attr->stack_size; + *stackaddr = attr->stack_address; + + return 0; +} + + +int +pthread_attr_setstack(pthread_attr_t *_attr, void *stackaddr, + size_t stacksize) +{ + pthread_attr *attr; + + if (_attr == NULL || (attr = *_attr) == NULL) + return B_BAD_VALUE; + + STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE + && PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE); + if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE) + return B_BAD_VALUE; + + attr->stack_size = stacksize; + attr->stack_address = stackaddr; + + return 0; +} + diff --git a/src/tests/system/libroot/posix/Jamfile b/src/tests/system/libroot/posix/Jamfile index 3e45b51bb5..187dcb050f 100644 --- a/src/tests/system/libroot/posix/Jamfile +++ b/src/tests/system/libroot/posix/Jamfile @@ -45,6 +45,7 @@ SimpleTest posix_spawn_redir_test : posix_spawn_redir_test.c ; SimpleTest posix_spawn_redir_err : posix_spawn_redir_err.c ; SimpleTest posix_spawn_pipe_test : posix_spawn_pipe_test.c ; SimpleTest posix_spawn_pipe_err : posix_spawn_pipe_err.c ; +SimpleTest pthread_attr_stack_test : pthread_attr_stack_test.cpp ; # XSI tests SimpleTest xsi_msg_queue_test1 : xsi_msg_queue_test1.cpp ; diff --git a/src/tests/system/libroot/posix/pthread_attr_stack_test.cpp b/src/tests/system/libroot/posix/pthread_attr_stack_test.cpp new file mode 100644 index 0000000000..5716d5b1dd --- /dev/null +++ b/src/tests/system/libroot/posix/pthread_attr_stack_test.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include + +#define panic(str) if (ret != 0) { errno = ret; perror(str); return 1; } + + +void* +threadFunction(void*) +{ + int i = 0; + printf("variable addr: %p\n", &i); + pthread_exit(0); + return 0; +} + + +int +main(int argc, char **argv) +{ + int ret; + pthread_attr_t attr; + ret = pthread_attr_init(&attr); + panic("init"); + void* stackAddress; + size_t stackSize; + ret = pthread_attr_getstack(&attr, &stackAddress, &stackSize); + panic("getstack"); + printf("stackAddress: %p, stackSize: %lu\n", stackAddress, stackSize); + stackSize = PTHREAD_STACK_MIN; + ret = posix_memalign(&stackAddress, sysconf(_SC_PAGE_SIZE), + stackSize); + panic("memalign"); + ret = pthread_attr_setstack(&attr, stackAddress, stackSize); + panic("setstack"); + ret = pthread_attr_getstack(&attr, &stackAddress, &stackSize); + panic("getstack"); + printf("stackAddress: %p, stackSize: %lu\n", stackAddress, stackSize); + + pthread_t thread; + ret = pthread_create(&thread, &attr, threadFunction, NULL); + panic("create"); + ret = pthread_join(thread, NULL); + panic("join"); + + ret = pthread_attr_destroy(&attr); + panic("destroy"); + + return 0; +}