From d902f3d8050ce90ddb8f300a5e1bd76f4710ca62 Mon Sep 17 00:00:00 2001 From: Mitya Selivanov <0x7fffff@guattari.ru> Date: Thu, 18 Aug 2022 17:08:06 +0400 Subject: [thread] Stack size --- source/kit/threads.h | 6 +++++- source/kit/threads.posix.c | 27 ++++++++++++++++++++++++--- source/kit/threads.win32.c | 13 ++++++++++--- source/test/unittests/thread.test.c | 9 +++++++++ 4 files changed, 48 insertions(+), 7 deletions(-) diff --git a/source/kit/threads.h b/source/kit/threads.h index 584ac7c..197f34f 100644 --- a/source/kit/threads.h +++ b/source/kit/threads.h @@ -39,6 +39,7 @@ # include # include +# include # include # ifdef _MSC_VER @@ -150,7 +151,8 @@ enum { thrd_timedout, // timed out thrd_error, // failed thrd_busy, // resource busy - thrd_nomem // out of memory + thrd_nomem, // out of memory, + thrd_wrong_stack_size }; /*-------------------------- functions --------------------------*/ @@ -171,6 +173,8 @@ int mtx_timedlock(mtx_t *__restrict mtx_, int mtx_trylock(mtx_t *mtx_); int mtx_unlock(mtx_t *mtx_); int thrd_create(thrd_t *, thrd_start_t, void *); +int thrd_create_with_stack(thrd_t *, thrd_start_t, void *, + ptrdiff_t stack_size); thrd_t thrd_current(void); int thrd_detach(thrd_t); int thrd_equal(thrd_t, thrd_t); diff --git a/source/kit/threads.posix.c b/source/kit/threads.posix.c index 9628bc7..66610ae 100644 --- a/source/kit/threads.posix.c +++ b/source/kit/threads.posix.c @@ -231,24 +231,45 @@ int mtx_unlock(mtx_t *mtx) { /*------------------- 7.25.5 Thread functions -------------------*/ // 7.25.5.1 -int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { +int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg, + ptrdiff_t const stack_size) { impl_thrd_param_t *pack; assert(thr != NULL); + assert(stack_size == 0 || stack_size >= PTHREAD_STACK_MIN); + pthread_attr_t attr; + pthread_attr_t *attr_p = NULL; + if (stack_size > 0) { + if (pthread_attr_init(&attr) != 0) + return thrd_nomem; + if (pthread_attr_setstacksize(&attr, (size_t) stack_size) != 0) + return thrd_wrong_stack_size; + attr_p = &attr; + } kit_allocator_t alloc = kit_alloc_default(); pack = (impl_thrd_param_t *) alloc.allocate( alloc.state, sizeof(impl_thrd_param_t)); - if (!pack) + if (!pack) { + if (attr_p) + pthread_attr_destroy(attr_p); return thrd_nomem; + } pack->func = func; pack->arg = arg; pack->alloc = alloc; - if (pthread_create(thr, NULL, impl_thrd_routine, pack) != 0) { + if (pthread_create(thr, attr_p, impl_thrd_routine, pack) != 0) { alloc.deallocate(alloc.state, pack); + if (attr_p) + pthread_attr_destroy(attr_p); return thrd_error; } + if (attr_p) + pthread_attr_destroy(attr_p); return thrd_success; } +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { + return thrd_create_with_stack(thr, func, arg, 0); +} // 7.25.5.2 thrd_t thrd_current(void) { return pthread_self(); diff --git a/source/kit/threads.win32.c b/source/kit/threads.win32.c index ce77fab..910ee82 100644 --- a/source/kit/threads.win32.c +++ b/source/kit/threads.win32.c @@ -322,10 +322,12 @@ void __threads_win32_tls_callback(void) { /*------------------- 7.25.5 Thread functions -------------------*/ // 7.25.5.1 -int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { +int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg, + ptrdiff_t const stack_size) { impl_thrd_param_t *pack; uintptr_t handle; assert(thr != NULL); + assert(stack_size >= 0 && stack_size < 0x100000000); kit_allocator_t alloc = kit_alloc_default(); pack = (impl_thrd_param_t *) alloc.allocate( alloc.state, (sizeof(impl_thrd_param_t))); @@ -334,8 +336,9 @@ int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { pack->func = func; pack->arg = arg; pack->alloc = alloc; - handle = _beginthreadex(NULL, 0, impl_thrd_routine, pack, - CREATE_SUSPENDED, NULL); + handle = _beginthreadex(NULL, (unsigned) stack_size, + impl_thrd_routine, pack, CREATE_SUSPENDED, + NULL); if (handle == 0) { alloc.deallocate(alloc.state, pack); if (errno == EAGAIN || errno == EACCES) @@ -348,6 +351,10 @@ int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { return thrd_success; } +int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) { + return thrd_create_with_stack(thr, func, arg); +} + // 7.25.5.2 thrd_t thrd_current(void) { /* GetCurrentThread() returns a pseudo-handle, which we need diff --git a/source/test/unittests/thread.test.c b/source/test/unittests/thread.test.c index 45fbea4..f60ad18 100644 --- a/source/test/unittests/thread.test.c +++ b/source/test/unittests/thread.test.c @@ -37,6 +37,13 @@ TEST("thread run") { REQUIRE(result == 42); } +TEST("thread stack size") { + thrd_t foo; + REQUIRE(thrd_create_with_stack(&foo, test_nothing, NULL, 200000) == + thrd_success); + REQUIRE(thrd_join(foo, NULL) == thrd_success); +} + TEST("thread equal") { thrd_t foo, bar; REQUIRE(thrd_create(&foo, test_nothing, NULL) == thrd_success); @@ -44,6 +51,8 @@ TEST("thread equal") { REQUIRE(thrd_equal(foo, foo)); REQUIRE(!thrd_equal(foo, bar)); REQUIRE(!thrd_equal(foo, thrd_current())); + REQUIRE(thrd_join(foo, NULL) == thrd_success); + REQUIRE(thrd_join(bar, NULL) == thrd_success); } TEST("thread exit") { -- cgit v1.2.3