summaryrefslogtreecommitdiff
path: root/nptl/pthread_create.c
diff options
context:
space:
mode:
authorCarlos O'Donell <carlos@systemhalted.org>2015-08-09 04:17:17 -0400
committerMike Frysinger <vapier@gentoo.org>2016-02-19 12:41:29 -0500
commitd615a47355699d29df01b28a120cef29c8a38091 (patch)
treea60b5cd1dddc6bb30e409601dad08f09a601993b /nptl/pthread_create.c
parent11fca9615fa7b98135d262066db5f4156dd72955 (diff)
nptl: support thread stacks that grow up
Gentoo has been carrying this for all arches since 2.17. URL: http://bugs.gentoo.org/301642
Diffstat (limited to 'nptl/pthread_create.c')
-rw-r--r--nptl/pthread_create.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/nptl/pthread_create.c b/nptl/pthread_create.c
index 5216041733..a834063ad5 100644
--- a/nptl/pthread_create.c
+++ b/nptl/pthread_create.c
@@ -427,12 +427,25 @@ START_THREAD_DEFN
#ifdef _STACK_GROWS_DOWN
char *sp = CURRENT_STACK_FRAME;
size_t freesize = (sp - (char *) pd->stackblock) & ~pagesize_m1;
-#else
-# error "to do"
-#endif
assert (freesize < pd->stackblock_size);
if (freesize > PTHREAD_STACK_MIN)
__madvise (pd->stackblock, freesize - PTHREAD_STACK_MIN, MADV_DONTNEED);
+#else
+ /* Page aligned start of memory to free (higher than or equal
+ to current sp plus the minimum stack size). */
+ void *freeblock = (void*)((size_t)(CURRENT_STACK_FRAME
+ + PTHREAD_STACK_MIN
+ + pagesize_m1)
+ & ~pagesize_m1);
+ char *free_end = (char *) (((uintptr_t) pd - pd->guardsize) & ~pagesize_m1);
+ /* Is there any space to free? */
+ if (free_end > (char *)freeblock)
+ {
+ size_t freesize = (size_t)(free_end - (char *)freeblock);
+ assert (freesize < pd->stackblock_size);
+ __madvise (freeblock, freesize, MADV_DONTNEED);
+ }
+#endif
/* If the thread is detached free the TCB. */
if (IS_DETACHED (pd))