Module Name: src
Committed By: joerg
Date: Mon Mar 12 20:16:52 UTC 2012
Modified Files:
src/lib/libpthread: pthread.c pthread_int.h
Log Message:
Keep track of the size of the guard area, in case we want to make it
modifiable later. Only reuse the stack if it was allocated by libpthread
and if the expected thread size matches the current stack size.
To generate a diff of this commit:
cvs rdiff -u -r1.131 -r1.132 src/lib/libpthread/pthread.c
cvs rdiff -u -r1.83 -r1.84 src/lib/libpthread/pthread_int.h
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/lib/libpthread/pthread.c
diff -u src/lib/libpthread/pthread.c:1.131 src/lib/libpthread/pthread.c:1.132
--- src/lib/libpthread/pthread.c:1.131 Mon Mar 12 16:37:15 2012
+++ src/lib/libpthread/pthread.c Mon Mar 12 20:16:52 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread.c,v 1.131 2012/03/12 16:37:15 joerg Exp $ */
+/* $NetBSD: pthread.c,v 1.132 2012/03/12 20:16:52 joerg Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread.c,v 1.131 2012/03/12 16:37:15 joerg Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.132 2012/03/12 20:16:52 joerg Exp $");
#define __EXPOSE_STACK 1
@@ -317,10 +317,11 @@ pthread__scrubthread(pthread_t t, char *
}
static int
-pthread__newstack(pthread_t newthread, const pthread_attr_t *attr)
+pthread__getstack(pthread_t newthread, const pthread_attr_t *attr)
{
- void *stackbase, *redzone;
+ void *stackbase, *stackbase2, *redzone;
size_t stacksize, guardsize;
+ bool allocated;
if (attr != NULL) {
pthread_attr_getstack(attr, &stackbase, &stacksize);
@@ -331,28 +332,51 @@ pthread__newstack(pthread_t newthread, c
if (stacksize == 0)
stacksize = pthread__stacksize;
+ if (newthread->pt_stack_allocated) {
+ if (newthread->pt_stack.ss_size == stacksize)
+ return 0;
+ stackbase2 = newthread->pt_stack.ss_sp;
+#ifndef __MACHINE_STACK_GROWS_UP
+ stackbase2 = (char *)stackbase2 - newthread->pt_guardsize;
+#endif
+ munmap(stackbase2,
+ newthread->pt_stack.ss_size + newthread->pt_guardsize);
+ newthread->pt_stack.ss_sp = NULL;
+ newthread->pt_stack.ss_size = 0;
+ newthread->pt_guardsize = 0;
+ newthread->pt_stack_allocated = false;
+ }
+
+ newthread->pt_stack_allocated = false;
+
if (stackbase == NULL) {
- stacksize = (stacksize | (pthread__pagesize - 1)) + 1;
+ stacksize = ((stacksize - 1) | (pthread__pagesize - 1)) + 1;
guardsize = pthread__pagesize;
stackbase = mmap(NULL, stacksize + guardsize,
PROT_READ|PROT_WRITE, MAP_ANON|MAP_PRIVATE, -1, (off_t)0);
if (stackbase == MAP_FAILED)
return ENOMEM;
+ allocated = true;
} else {
guardsize = 0;
+ allocated = false;
}
- newthread->pt_stack.ss_size = stacksize;
#ifdef __MACHINE_STACK_GROWS_UP
- redzone = (char *)stackbase + newthread->pt_stack.ss_size;
- newthread->pt_stack.ss_sp = (char *)stackbase + guardsize;
+ redzone = (char *)stackbase + stacksize;
+ stackbase2 = (char *)stackbase;
#else
redzone = (char *)stackbase;
- newthread->pt_stack.ss_sp = (char *)stackbase + guardsize;
+ stackbase2 = (char *)stackbase + guardsize;
#endif
- if (guardsize && mprotect(redzone, guardsize, PROT_NONE) == -1) {
+ if (allocated && guardsize &&
+ mprotect(redzone, guardsize, PROT_NONE) == -1) {
munmap(stackbase, stacksize + guardsize);
return EPERM;
}
+ newthread->pt_stack.ss_size = stacksize;
+ newthread->pt_stack.ss_sp = stackbase2;
+ newthread->pt_guardsize = guardsize;
+ newthread->pt_stack_allocated = allocated;
return 0;
}
@@ -427,8 +451,9 @@ pthread_create(pthread_t *thread, const
free(name);
return ENOMEM;
}
+ newthread->pt_stack_allocated = false;
- if (pthread__newstack(newthread, attr)) {
+ if (pthread__getstack(newthread, attr)) {
free(newthread);
free(name);
return ENOMEM;
@@ -450,6 +475,16 @@ pthread_create(pthread_t *thread, const
/* Will be reset by the thread upon exit. */
pthread__initthread(newthread);
+ } else {
+ if (pthread__getstack(newthread, attr)) {
+ pthread_mutex_lock(&pthread__deadqueue_lock);
+ PTQ_INSERT_TAIL(&pthread__deadqueue, newthread, pt_deadq);
+ pthread_mutex_unlock(&pthread__deadqueue_lock);
+ return ENOMEM;
+ }
+ _INITCONTEXT_U(&newthread->pt_uc);
+ newthread->pt_uc.uc_stack = newthread->pt_stack;
+ newthread->pt_uc.uc_link = NULL;
}
/*
Index: src/lib/libpthread/pthread_int.h
diff -u src/lib/libpthread/pthread_int.h:1.83 src/lib/libpthread/pthread_int.h:1.84
--- src/lib/libpthread/pthread_int.h:1.83 Fri Mar 2 18:06:05 2012
+++ src/lib/libpthread/pthread_int.h Mon Mar 12 20:16:52 2012
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_int.h,v 1.83 2012/03/02 18:06:05 joerg Exp $ */
+/* $NetBSD: pthread_int.h,v 1.84 2012/03/12 20:16:52 joerg Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -52,9 +52,10 @@
#include <sys/atomic.h>
#include <sys/tree.h>
+#include <limits.h>
#include <lwp.h>
#include <signal.h>
-#include <limits.h>
+#include <stdbool.h>
#ifdef __GNUC__
#define PTHREAD_HIDE __attribute__ ((visibility("hidden")))
@@ -104,6 +105,8 @@ struct __pthread_st {
int pt_cancel; /* Deferred cancellation */
int pt_errno; /* Thread-specific errno. */
stack_t pt_stack; /* Our stack */
+ bool pt_stack_allocated;
+ size_t pt_guardsize;
void *pt_exitval; /* Read by pthread_join() */
char *pt_name; /* Thread's name, set by the app. */
int pt_willpark; /* About to park */