From 6940bbd7ce14bc183f8ab987356a35b7c00beb5a Mon Sep 17 00:00:00 2001
From: Mitya Selivanov <0x7fffff@guattari.ru>
Date: Thu, 18 Aug 2022 18:13:13 +0400
Subject: [macOS] Calculate stack size as multiple of page size

---
 source/kit/threads.posix.c | 15 ++++++++++-----
 1 file changed, 10 insertions(+), 5 deletions(-)

(limited to 'source')

diff --git a/source/kit/threads.posix.c b/source/kit/threads.posix.c
index d234686..0cd7b7d 100644
--- a/source/kit/threads.posix.c
+++ b/source/kit/threads.posix.c
@@ -234,17 +234,23 @@ int mtx_unlock(mtx_t *mtx) {
 /*------------------- 7.25.5 Thread functions -------------------*/
 // 7.25.5.1
 int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg,
-                           ptrdiff_t const stack_size) {
+                           ptrdiff_t const require_stack_size) {
   impl_thrd_param_t *pack;
   assert(thr != NULL);
-  assert(stack_size == 0 || stack_size >= PTHREAD_STACK_MIN);
+  assert(require_stack_size == 0 ||
+         require_stack_size >= PTHREAD_STACK_MIN);
   pthread_attr_t  attr;
   pthread_attr_t *attr_p = NULL;
-  if (stack_size > 0) {
+  if (require_stack_size > 0) {
+    ptrdiff_t const page_size  = (ptrdiff_t) sysconf(_SC_PAGESIZE);
+    ptrdiff_t const delta      = require_stack_size % page_size;
+    ptrdiff_t const stack_size = delta == 0
+                                     ? require_stack_size
+                                     : require_stack_size +
+                                           require_stack_size - delta;
     if (pthread_attr_init(&attr) != 0)
       return thrd_nomem;
     if (pthread_attr_setstacksize(&attr, (size_t) stack_size) != 0) {
-      printf("%% pthread_attr_setstacksize failed\n");
       return thrd_wrong_stack_size;
     }
     attr_p = &attr;
@@ -261,7 +267,6 @@ int thrd_create_with_stack(thrd_t *thr, thrd_start_t func, void *arg,
   pack->arg   = arg;
   pack->alloc = alloc;
   if (pthread_create(thr, attr_p, impl_thrd_routine, pack) != 0) {
-    printf("%% pthread_create failed\n");
     alloc.deallocate(alloc.state, pack);
     if (attr_p)
       pthread_attr_destroy(attr_p);
-- 
cgit v1.2.3