summaryrefslogtreecommitdiff
path: root/libpthread
diff options
context:
space:
mode:
Diffstat (limited to 'libpthread')
-rw-r--r--libpthread/linuxthreads.old/internals.h24
-rw-r--r--libpthread/linuxthreads.old/pthread.c23
2 files changed, 30 insertions, 17 deletions
diff --git a/libpthread/linuxthreads.old/internals.h b/libpthread/linuxthreads.old/internals.h
index 637fcea62..110dd9d56 100644
--- a/libpthread/linuxthreads.old/internals.h
+++ b/libpthread/linuxthreads.old/internals.h
@@ -252,17 +252,25 @@ extern pthread_descr __pthread_main_thread;
Initially 0, meaning that the current thread is (by definition)
the initial thread. */
-/* For non-MMU systems also remember to stack top of the initial thread.
- * This is adapted when other stacks are malloc'ed since we don't know
- * the bounds a-priori. -StS */
-
extern char *__pthread_initial_thread_bos;
#ifndef __ARCH_USE_MMU__
-extern char *__pthread_initial_thread_tos;
+/* For non-MMU systems, we have no idea the bounds of the initial thread
+ * stack, so we have to track it on the fly relative to other stacks. Do
+ * so by scaling back our assumptions on the limits of the bos/tos relative
+ * to the known mid point. See also the comments in pthread_initialize(). */
+extern char *__pthread_initial_thread_tos, *__pthread_initial_thread_mid;
#define NOMMU_INITIAL_THREAD_BOUNDS(tos,bos) \
- if ((tos)>=__pthread_initial_thread_bos \
- && (bos)<__pthread_initial_thread_tos) \
- __pthread_initial_thread_bos = (tos)+1
+ do { \
+ char *__tos = (tos); \
+ char *__bos = (bos); \
+ if (__tos >= __pthread_initial_thread_bos && \
+ __bos < __pthread_initial_thread_tos) { \
+ if (__bos < __pthread_initial_thread_mid) \
+ __pthread_initial_thread_bos = __tos; \
+ else \
+ __pthread_initial_thread_tos = __bos; \
+ } \
+ } while (0)
#else
#define NOMMU_INITIAL_THREAD_BOUNDS(tos,bos) /* empty */
#endif /* __ARCH_USE_MMU__ */
diff --git a/libpthread/linuxthreads.old/pthread.c b/libpthread/linuxthreads.old/pthread.c
index ad392e34e..a8830b1a4 100644
--- a/libpthread/linuxthreads.old/pthread.c
+++ b/libpthread/linuxthreads.old/pthread.c
@@ -168,12 +168,10 @@ pthread_descr __pthread_main_thread = &__pthread_initial_thread;
char *__pthread_initial_thread_bos = NULL;
-/* For non-MMU systems also remember to stack top of the initial thread.
- * This is adapted when other stacks are malloc'ed since we don't know
- * the bounds a-priori. -StS */
-
#ifndef __ARCH_USE_MMU__
+/* See nommu notes in internals.h and pthread_initialize() below. */
char *__pthread_initial_thread_tos = NULL;
+char *__pthread_initial_thread_mid = NULL;
#endif /* __ARCH_USE_MMU__ */
/* File descriptor for sending requests to the thread manager. */
@@ -457,12 +455,19 @@ static void pthread_initialize(void)
setrlimit(RLIMIT_STACK, &limit);
}
#else
- /* For non-MMU assume __pthread_initial_thread_tos at upper page boundary, and
- * __pthread_initial_thread_bos at address 0. These bounds are refined as we
- * malloc other stack frames such that they don't overlap. -StS
+ /* For non-MMU, the initial thread stack can reside anywhere in memory.
+ * We don't have a way of knowing where the kernel started things -- top
+ * or bottom (well, that isn't exactly true, but the solution is fairly
+ * complex and error prone). All we can determine here is an address
+ * that lies within that stack. Save that address as a reference so that
+ * as other thread stacks are created, we can adjust the estimated bounds
+ * of the initial thread's stack appropriately.
+ *
+ * This checking is handled in NOMMU_INITIAL_THREAD_BOUNDS(), so see that
+ * for a few more details.
*/
- __pthread_initial_thread_tos =
- (char *)(((long)CURRENT_STACK_FRAME + getpagesize()) & ~(getpagesize() - 1));
+ __pthread_initial_thread_mid = CURRENT_STACK_FRAME;
+ __pthread_initial_thread_tos = (char *) -1;
__pthread_initial_thread_bos = (char *) 1; /* set it non-zero so we know we have been here */
PDEBUG("initial thread stack bounds: bos=%p, tos=%p\n",
__pthread_initial_thread_bos, __pthread_initial_thread_tos);