rather than allocating memory for _Thread struct and stack together,
this diff[1] changes the allocation by pulling apart the stack of the
thread_t struct, so now only the stack segment has the MAP_STACK flag
for passing stack-register checking.

tested on amd64(MAP_STACK bits in). acme(1)/sam(1) works
fine!

[1] http://shutpandhack.org/~gsoares/plan9port_map_stack.diff

Index: Makefile
===================================================================
RCS file: /cvs/ports/plan9/plan9port/Makefile,v
retrieving revision 1.24
diff -u -p -r1.24 Makefile
--- Makefile    20 Jan 2018 03:29:56 -0000      1.24
+++ Makefile    21 Mar 2018 02:02:26 -0000
@@ -4,6 +4,7 @@ ONLY_FOR_ARCHS =        amd64 i386 powerpc
 BROKEN-powerpc =       threading issues
 
 COMMENT =              Plan 9 from user space
+REVISION =             0
 
 DISTNAME =             plan9port-20180117
 
Index: patches/patch-src_libthread_thread_c
===================================================================
RCS file: patches/patch-src_libthread_thread_c
diff -N patches/patch-src_libthread_thread_c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_libthread_thread_c        21 Mar 2018 02:02:26 -0000
@@ -0,0 +1,46 @@
+$OpenBSD$
+
+Index: src/libthread/thread.c
+--- src/libthread/thread.c.orig
++++ src/libthread/thread.c
+@@ -107,12 +107,18 @@ threadalloc(void (*fn)(void*), void *arg, uint stack)
+       uint x, y;
+       ulong z;
+ 
+-      /* allocate the task and stack together */
+-      t = malloc(sizeof *t+stack);
++      /* allocate the task */
++      t = malloc(sizeof *t);
+       if(t == nil)
+               sysfatal("threadalloc malloc: %r");
+       memset(t, 0, sizeof *t);
+-      t->stk = (uchar*)(t+1);
++      /* allocate the real stack */
++      t->stk = mmap(NULL, stack, PROT_READ | PROT_WRITE,
++          MAP_PRIVATE | MAP_ANON | MAP_STACK, -1, 0);
++      if (t->stk == MAP_FAILED) {
++              free(t);
++              sysfatal("threadalloc malloc: %r");
++      }
+       t->stksize = stack;
+       t->id = incref(&threadidref);
+ //print("fn=%p arg=%p\n", fn, arg);
+@@ -133,8 +139,8 @@ threadalloc(void (*fn)(void*), void *arg, uint stack)
+ 
+       /* call makecontext to do the real work. */
+       /* leave a few words open on both ends */
+-      t->context.uc.uc_stack.ss_sp = (void*)(t->stk+8);
+-      t->context.uc.uc_stack.ss_size = t->stksize-64;
++      t->context.uc.uc_stack.ss_sp = t->stk;
++      t->context.uc.uc_stack.ss_size = t->stksize;
+ #if defined(__sun__) && !defined(__MAKECONTEXT_V2_SOURCE)             /* sigh 
*/
+       /* can avoid this with __MAKECONTEXT_V2_SOURCE but only on SunOS 5.9 */
+       t->context.uc.uc_stack.ss_sp = 
+@@ -364,6 +370,7 @@ procscheduler(Proc *p)
+                       delthreadinproc(p, t);
+                       p->nthread--;
+ /*print("nthread %d\n", p->nthread); */
++                      munmap(t->stk, t->stksize);
+                       free(t);
+               }
+       }
Index: patches/patch-src_libthread_threadimpl_h
===================================================================
RCS file: patches/patch-src_libthread_threadimpl_h
diff -N patches/patch-src_libthread_threadimpl_h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ patches/patch-src_libthread_threadimpl_h    21 Mar 2018 02:02:26 -0000
@@ -0,0 +1,14 @@
+$OpenBSD$
+
+Index: src/libthread/threadimpl.h
+--- src/libthread/threadimpl.h.orig
++++ src/libthread/threadimpl.h
+@@ -10,6 +10,8 @@
+ #             define _XOPEN_SOURCE    /* for Snow Leopard */
+ #     endif
+ #     include <ucontext.h>
++#elif defined(__OpenBSD__)
++#     include <sys/mman.h>
+ #endif
+ #include <sys/utsname.h>
+ #include "libc.h"

Reply via email to