summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/kit/threads.h6
-rw-r--r--source/kit/threads.posix.c27
-rw-r--r--source/kit/threads.win32.c13
-rw-r--r--source/test/unittests/thread.test.c9
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 <errno.h>
# include <limits.h>
+# include <stddef.h>
# include <stdlib.h>
# 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") {