aboutsummaryrefslogtreecommitdiff
path: root/linuxthreads
diff options
context:
space:
mode:
Diffstat (limited to 'linuxthreads')
-rw-r--r--linuxthreads/ChangeLog8
-rw-r--r--linuxthreads/manager.c22
-rw-r--r--linuxthreads/pthread.c5
3 files changed, 19 insertions, 16 deletions
diff --git a/linuxthreads/ChangeLog b/linuxthreads/ChangeLog
index 7d161b8254..9bdf83e951 100644
--- a/linuxthreads/ChangeLog
+++ b/linuxthreads/ChangeLog
@@ -1,3 +1,11 @@
+1999-12-18 Ulrich Drepper <drepper@cygnus.com>
+
+ * manager.c (pthread_allocate_stack): Correct computation of
+ new_thread_bottom. Correct handling of stack size and when the
+ rlimit method to guard for stack growth is used.
+ * pthread.c (pthread_initialize): Stack limit must be STACK_SIZE
+ minus one pagesize (not two).
+
1999-12-03 Andreas Jaeger <aj@suse.de>
* Versions: Add __res_state with version GLIBC_2.2.
diff --git a/linuxthreads/manager.c b/linuxthreads/manager.c
index 307ce63721..0cbb426c9d 100644
--- a/linuxthreads/manager.c
+++ b/linuxthreads/manager.c
@@ -289,9 +289,12 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
}
else
{
+ stacksize = STACK_SIZE - pagesize;
+ if (attr != NULL)
+ stacksize = MIN (stacksize, roundup(attr->__stacksize, pagesize));
/* Allocate space for stack and thread descriptor at default address */
new_thread = default_new_thread;
- new_thread_bottom = (char *) new_thread - STACK_SIZE;
+ new_thread_bottom = (char *) (new_thread + 1) - stacksize;
if (mmap((caddr_t)((char *)(new_thread + 1) - INITIAL_STACK_SIZE),
INITIAL_STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED | MAP_GROWSDOWN,
@@ -300,14 +303,10 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
return -1;
/* We manage to get a stack. Now see whether we need a guard
and allocate it if necessary. Notice that the default
- attributes (stack_size = STACK_SIZE - pagesize and
- guardsize = pagesize) do not need a guard page, since
- the RLIMIT_STACK soft limit prevents stacks from
- running into one another. */
- if (attr == NULL ||
- attr->__guardsize == 0 ||
- (attr->__guardsize == pagesize &&
- attr->__stacksize == STACK_SIZE - pagesize))
+ attributes (stack_size = STACK_SIZE - pagesize) do not need
+ a guard page, since the RLIMIT_STACK soft limit prevents stacks
+ from running into one another. */
+ if (stacksize == STACK_SIZE - pagesize)
{
/* We don't need a guard page. */
guardaddr = NULL;
@@ -316,10 +315,7 @@ static int pthread_allocate_stack(const pthread_attr_t *attr,
else
{
/* Put a bad page at the bottom of the stack */
- stacksize = roundup(attr->__stacksize, pagesize);
- if (stacksize >= STACK_SIZE - pagesize)
- stacksize = STACK_SIZE - pagesize;
- guardaddr = (void *)new_thread - stacksize;
+ guardaddr = (void *)new_thread_bottom - stacksize;
guardsize = attr->__guardsize;
if (mmap ((caddr_t) guardaddr, guardsize, 0, MAP_FIXED, -1, 0)
== MAP_FAILED)
diff --git a/linuxthreads/pthread.c b/linuxthreads/pthread.c
index 41d09a833c..a9083635b6 100644
--- a/linuxthreads/pthread.c
+++ b/linuxthreads/pthread.c
@@ -300,10 +300,9 @@ static void pthread_initialize(void)
__pthread_initial_thread_bos =
(char *)(((long)CURRENT_STACK_FRAME - 2 * STACK_SIZE) & ~(STACK_SIZE - 1));
/* Play with the stack size limit to make sure that no stack ever grows
- beyond STACK_SIZE minus two pages (one page for the thread descriptor
- immediately beyond, and one page to act as a guard page). */
+ beyond STACK_SIZE minus one page (to act as a guard page). */
getrlimit(RLIMIT_STACK, &limit);
- max_stack = STACK_SIZE - 2 * __getpagesize();
+ max_stack = STACK_SIZE - __getpagesize();
if (limit.rlim_cur > max_stack) {
limit.rlim_cur = max_stack;
setrlimit(RLIMIT_STACK, &limit);