mirror of
https://git.FreeBSD.org/src.git
synced 2025-01-28 16:43:09 +00:00
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.
This commit is contained in:
parent
8d048bba15
commit
69186ed701
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=55193
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
Loading…
Reference in New Issue
Block a user