summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordeischen <deischen@FreeBSD.org>1999-12-28 18:12:07 +0000
committerdeischen <deischen@FreeBSD.org>1999-12-28 18:12:07 +0000
commit9321f383a24bce8e6555df4e36441e9bfcff4a27 (patch)
treee0b9cc982b20ee21e845e703f20fa492e2abb29c
parent2a6c7913a06dc521fa0fdb7e0fcc2a1ccd24800e (diff)
downloadFreeBSD-src-9321f383a24bce8e6555df4e36441e9bfcff4a27.zip
FreeBSD-src-9321f383a24bce8e6555df4e36441e9bfcff4a27.tar.gz
Change stack allocation algorithm to make better use of memory
(it was leaving an unused block). Also protect the global stack pointer from context changes while fiddling with it.
-rw-r--r--lib/libc_r/uthread/uthread_create.c30
-rw-r--r--lib/libc_r/uthread/uthread_init.c12
-rw-r--r--lib/libkse/thread/thr_create.c30
-rw-r--r--lib/libkse/thread/thr_init.c12
-rw-r--r--lib/libpthread/thread/thr_create.c30
-rw-r--r--lib/libpthread/thread/thr_init.c12
6 files changed, 60 insertions, 66 deletions
diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c
index 8621c05..a392cba 100644
--- a/lib/libc_r/uthread/uthread_create.c
+++ b/lib/libc_r/uthread/uthread_create.c
@@ -118,12 +118,9 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
+ (void *) spare_stack
- PTHREAD_STACK_DEFAULT;
} else {
- /* Unlock the garbage collector mutex. */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot unlock gc mutex");
-
/* Allocate a new stack. */
stack = _next_stack + PTHREAD_STACK_GUARD;
+
/*
* Even if stack allocation fails, we don't want
* to try to use this location again, so
@@ -133,23 +130,26 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* overflow of the adjacent thread stack.
*/
_next_stack -= (PTHREAD_STACK_DEFAULT
- + PTHREAD_STACK_GUARD);
+ + PTHREAD_STACK_GUARD);
+
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
/* Red zone: */
- if (mmap(_next_stack, PTHREAD_STACK_GUARD, 0,
- MAP_ANON, -1, 0) == MAP_FAILED) {
+ if (mmap(stack - PTHREAD_STACK_GUARD,
+ PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED) {
ret = EAGAIN;
free(new_thread);
}
/* Stack: */
- else if (mmap(stack,
- PTHREAD_STACK_DEFAULT,
- PROT_READ | PROT_WRITE,
- MAP_STACK,
- -1, 0) == MAP_FAILED) {
+ else if (mmap(stack, PTHREAD_STACK_DEFAULT,
+ PROT_READ | PROT_WRITE, MAP_STACK,
+ -1, 0) == MAP_FAILED) {
ret = EAGAIN;
- munmap(_next_stack,
- PTHREAD_STACK_GUARD);
+ munmap(stack - PTHREAD_STACK_GUARD,
+ PTHREAD_STACK_GUARD);
free(new_thread);
}
}
@@ -159,7 +159,7 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* really know what they want, and simply malloc the stack.
*/
else if ((stack = (void *) malloc(pattr->stacksize_attr))
- == NULL) {
+ == NULL) {
/* Insufficient memory to create a thread: */
ret = EAGAIN;
free(new_thread);
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
index bab7e5b..c888697 100644
--- a/lib/libc_r/uthread/uthread_init.c
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -187,13 +187,11 @@ _thread_init(void)
SLIST_INIT(&_stackq);
/* Create the red zone for the main stack. */
- if (mmap((void *) USRSTACK
- - PTHREAD_STACK_INITIAL,
- PTHREAD_STACK_GUARD, 0, MAP_ANON,
- -1, 0) == MAP_FAILED) {
+ if (mmap((void *) USRSTACK - PTHREAD_STACK_INITIAL -
+ PTHREAD_STACK_GUARD, PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED)
PANIC("Cannot allocate red zone for initial thread");
- }
-
+
/*
* Write a magic value to the thread structure
* to help identify valid ones:
@@ -248,7 +246,7 @@ _thread_init(void)
/* Get the signal handler details: */
else if (_thread_sys_sigaction(i, NULL,
- &_thread_sigact[i - 1]) != 0) {
+ &_thread_sigact[i - 1]) != 0) {
/*
* Abort this process if signal
* initialisation fails:
diff --git a/lib/libkse/thread/thr_create.c b/lib/libkse/thread/thr_create.c
index 8621c05..a392cba 100644
--- a/lib/libkse/thread/thr_create.c
+++ b/lib/libkse/thread/thr_create.c
@@ -118,12 +118,9 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
+ (void *) spare_stack
- PTHREAD_STACK_DEFAULT;
} else {
- /* Unlock the garbage collector mutex. */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot unlock gc mutex");
-
/* Allocate a new stack. */
stack = _next_stack + PTHREAD_STACK_GUARD;
+
/*
* Even if stack allocation fails, we don't want
* to try to use this location again, so
@@ -133,23 +130,26 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* overflow of the adjacent thread stack.
*/
_next_stack -= (PTHREAD_STACK_DEFAULT
- + PTHREAD_STACK_GUARD);
+ + PTHREAD_STACK_GUARD);
+
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
/* Red zone: */
- if (mmap(_next_stack, PTHREAD_STACK_GUARD, 0,
- MAP_ANON, -1, 0) == MAP_FAILED) {
+ if (mmap(stack - PTHREAD_STACK_GUARD,
+ PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED) {
ret = EAGAIN;
free(new_thread);
}
/* Stack: */
- else if (mmap(stack,
- PTHREAD_STACK_DEFAULT,
- PROT_READ | PROT_WRITE,
- MAP_STACK,
- -1, 0) == MAP_FAILED) {
+ else if (mmap(stack, PTHREAD_STACK_DEFAULT,
+ PROT_READ | PROT_WRITE, MAP_STACK,
+ -1, 0) == MAP_FAILED) {
ret = EAGAIN;
- munmap(_next_stack,
- PTHREAD_STACK_GUARD);
+ munmap(stack - PTHREAD_STACK_GUARD,
+ PTHREAD_STACK_GUARD);
free(new_thread);
}
}
@@ -159,7 +159,7 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* really know what they want, and simply malloc the stack.
*/
else if ((stack = (void *) malloc(pattr->stacksize_attr))
- == NULL) {
+ == NULL) {
/* Insufficient memory to create a thread: */
ret = EAGAIN;
free(new_thread);
diff --git a/lib/libkse/thread/thr_init.c b/lib/libkse/thread/thr_init.c
index bab7e5b..c888697 100644
--- a/lib/libkse/thread/thr_init.c
+++ b/lib/libkse/thread/thr_init.c
@@ -187,13 +187,11 @@ _thread_init(void)
SLIST_INIT(&_stackq);
/* Create the red zone for the main stack. */
- if (mmap((void *) USRSTACK
- - PTHREAD_STACK_INITIAL,
- PTHREAD_STACK_GUARD, 0, MAP_ANON,
- -1, 0) == MAP_FAILED) {
+ if (mmap((void *) USRSTACK - PTHREAD_STACK_INITIAL -
+ PTHREAD_STACK_GUARD, PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED)
PANIC("Cannot allocate red zone for initial thread");
- }
-
+
/*
* Write a magic value to the thread structure
* to help identify valid ones:
@@ -248,7 +246,7 @@ _thread_init(void)
/* Get the signal handler details: */
else if (_thread_sys_sigaction(i, NULL,
- &_thread_sigact[i - 1]) != 0) {
+ &_thread_sigact[i - 1]) != 0) {
/*
* Abort this process if signal
* initialisation fails:
diff --git a/lib/libpthread/thread/thr_create.c b/lib/libpthread/thread/thr_create.c
index 8621c05..a392cba 100644
--- a/lib/libpthread/thread/thr_create.c
+++ b/lib/libpthread/thread/thr_create.c
@@ -118,12 +118,9 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
+ (void *) spare_stack
- PTHREAD_STACK_DEFAULT;
} else {
- /* Unlock the garbage collector mutex. */
- if (pthread_mutex_unlock(&_gc_mutex) != 0)
- PANIC("Cannot unlock gc mutex");
-
/* Allocate a new stack. */
stack = _next_stack + PTHREAD_STACK_GUARD;
+
/*
* Even if stack allocation fails, we don't want
* to try to use this location again, so
@@ -133,23 +130,26 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* overflow of the adjacent thread stack.
*/
_next_stack -= (PTHREAD_STACK_DEFAULT
- + PTHREAD_STACK_GUARD);
+ + PTHREAD_STACK_GUARD);
+
+ /* Unlock the garbage collector mutex. */
+ if (pthread_mutex_unlock(&_gc_mutex) != 0)
+ PANIC("Cannot unlock gc mutex");
/* Red zone: */
- if (mmap(_next_stack, PTHREAD_STACK_GUARD, 0,
- MAP_ANON, -1, 0) == MAP_FAILED) {
+ if (mmap(stack - PTHREAD_STACK_GUARD,
+ PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED) {
ret = EAGAIN;
free(new_thread);
}
/* Stack: */
- else if (mmap(stack,
- PTHREAD_STACK_DEFAULT,
- PROT_READ | PROT_WRITE,
- MAP_STACK,
- -1, 0) == MAP_FAILED) {
+ else if (mmap(stack, PTHREAD_STACK_DEFAULT,
+ PROT_READ | PROT_WRITE, MAP_STACK,
+ -1, 0) == MAP_FAILED) {
ret = EAGAIN;
- munmap(_next_stack,
- PTHREAD_STACK_GUARD);
+ munmap(stack - PTHREAD_STACK_GUARD,
+ PTHREAD_STACK_GUARD);
free(new_thread);
}
}
@@ -159,7 +159,7 @@ pthread_create(pthread_t * thread, const pthread_attr_t * attr,
* really know what they want, and simply malloc the stack.
*/
else if ((stack = (void *) malloc(pattr->stacksize_attr))
- == NULL) {
+ == NULL) {
/* Insufficient memory to create a thread: */
ret = EAGAIN;
free(new_thread);
diff --git a/lib/libpthread/thread/thr_init.c b/lib/libpthread/thread/thr_init.c
index bab7e5b..c888697 100644
--- a/lib/libpthread/thread/thr_init.c
+++ b/lib/libpthread/thread/thr_init.c
@@ -187,13 +187,11 @@ _thread_init(void)
SLIST_INIT(&_stackq);
/* Create the red zone for the main stack. */
- if (mmap((void *) USRSTACK
- - PTHREAD_STACK_INITIAL,
- PTHREAD_STACK_GUARD, 0, MAP_ANON,
- -1, 0) == MAP_FAILED) {
+ if (mmap((void *) USRSTACK - PTHREAD_STACK_INITIAL -
+ PTHREAD_STACK_GUARD, PTHREAD_STACK_GUARD, 0, MAP_ANON,
+ -1, 0) == MAP_FAILED)
PANIC("Cannot allocate red zone for initial thread");
- }
-
+
/*
* Write a magic value to the thread structure
* to help identify valid ones:
@@ -248,7 +246,7 @@ _thread_init(void)
/* Get the signal handler details: */
else if (_thread_sys_sigaction(i, NULL,
- &_thread_sigact[i - 1]) != 0) {
+ &_thread_sigact[i - 1]) != 0) {
/*
* Abort this process if signal
* initialisation fails:
OpenPOWER on IntegriCloud