diff options
Diffstat (limited to 'linuxthreads')
-rw-r--r-- | linuxthreads/ChangeLog | 8 | ||||
-rw-r--r-- | linuxthreads/manager.c | 22 | ||||
-rw-r--r-- | linuxthreads/pthread.c | 5 |
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); |