summaryrefslogtreecommitdiffstats
path: root/lib/libc_r
diff options
context:
space:
mode:
authormarcel <marcel@FreeBSD.org>2003-01-06 00:56:23 +0000
committermarcel <marcel@FreeBSD.org>2003-01-06 00:56:23 +0000
commite9cd0e2e144baaddc464791fba38ef829193b155 (patch)
tree5c81c5d4df8691906e30b75b5583d89f7b456055 /lib/libc_r
parent27381a0d4574e98d6ac003f4e5266631aca601f7 (diff)
downloadFreeBSD-src-e9cd0e2e144baaddc464791fba38ef829193b155.zip
FreeBSD-src-e9cd0e2e144baaddc464791fba38ef829193b155.tar.gz
Port libc_r to ia64. We need to do things slightly different
because we have 2 stacks per thread: the regular downward memory stack and the irregular upward register stack. This implementation lets both stacks grow toward each other. An alternative scheme is to have them grow away from each other. The alternate scheme has the advantage that both stack grow toward guard pages. Since libc_r is virtually dead and we really want the *context stuff for thread switching, we don't try to be perfect, just functional.
Diffstat (limited to 'lib/libc_r')
-rw-r--r--lib/libc_r/uthread/pthread_private.h23
-rw-r--r--lib/libc_r/uthread/uthread_create.c5
-rw-r--r--lib/libc_r/uthread/uthread_init.c5
-rw-r--r--lib/libc_r/uthread/uthread_sig.c11
4 files changed, 44 insertions, 0 deletions
diff --git a/lib/libc_r/uthread/pthread_private.h b/lib/libc_r/uthread/pthread_private.h
index e8e85b0..b2f7a61 100644
--- a/lib/libc_r/uthread/pthread_private.h
+++ b/lib/libc_r/uthread/pthread_private.h
@@ -102,6 +102,21 @@
(jb)[0]._jb[R_RA + 4] = (long)(ra); \
(jb)[0]._jb[R_T12 + 4] = (long)(ra); \
} while (0)
+#elif defined(__ia64__)
+#define GET_BSP_JB(jb) (*((unsigned long*)JMPBUF_ADDR_OF(jb,J_BSP)))
+#define GET_STACK_JB(jb) (*((unsigned long*)JMPBUF_ADDR_OF(jb,J_SP)))
+#define GET_STACK_SJB(sjb) GET_STACK_JB(sjb)
+#define SET_RETURN_ADDR_JB(jb, ra) \
+do { \
+ *((unsigned long*)JMPBUF_ADDR_OF(jb,J_B0)) = ((long*)(ra))[0]; \
+ *((unsigned long*)JMPBUF_ADDR_OF(jb,J_PFS)) &= ~0x1FFFFFFFFFUL; \
+} while (0)
+#define SET_STACK_JB(jb, stk, sz) \
+do { \
+ UPD_STACK_JB(jb, stk + sz - 16); \
+ GET_BSP_JB(jb) = (long)(stk); \
+} while (0)
+#define UPD_STACK_JB(jb, stk) GET_STACK_JB(jb) = (long)(stk)
#elif defined(__sparc64__)
#include <machine/frame.h>
@@ -432,7 +447,11 @@ struct pthread_attr {
/*
* Miscellaneous definitions.
*/
+#if !defined(__ia64__)
#define PTHREAD_STACK_DEFAULT 65536
+#else
+#define PTHREAD_STACK_DEFAULT 0x40000
+#endif
/*
* Size of default red zone at the end of each stack. In actuality, this "red
* zone" is merely an unmapped region, except in the case of the initial stack.
@@ -450,7 +469,11 @@ extern int _pthread_page_size;
* than the stacks of other threads, since many applications are likely to run
* almost entirely on this stack.
*/
+#if !defined(__ia64__)
#define PTHREAD_STACK_INITIAL 0x100000
+#else
+#define PTHREAD_STACK_INITIAL 0x400000
+#endif
/*
* Define the different priority ranges. All applications have thread
diff --git a/lib/libc_r/uthread/uthread_create.c b/lib/libc_r/uthread/uthread_create.c
index d101721..2ea87b2 100644
--- a/lib/libc_r/uthread/uthread_create.c
+++ b/lib/libc_r/uthread/uthread_create.c
@@ -144,10 +144,15 @@ _pthread_create(pthread_t *thread, const pthread_attr_t *attr,
*/
SET_RETURN_ADDR_JB(new_thread->ctx.jb, _thread_start);
+#if !defined(__ia64__)
/* The stack starts high and builds down: */
SET_STACK_JB(new_thread->ctx.jb,
(long)new_thread->stack + pattr->stacksize_attr
- sizeof(double));
+#else
+ SET_STACK_JB(new_thread->ctx.jb,
+ (long)new_thread->stack, pattr->stacksize_attr);
+#endif
/* Copy the thread attributes: */
memcpy(&new_thread->attr, pattr, sizeof(struct pthread_attr));
diff --git a/lib/libc_r/uthread/uthread_init.c b/lib/libc_r/uthread/uthread_init.c
index d1d116e..41737b1 100644
--- a/lib/libc_r/uthread/uthread_init.c
+++ b/lib/libc_r/uthread/uthread_init.c
@@ -373,8 +373,13 @@ _thread_init(void)
/* Setup the context for the scheduler: */
_setjmp(_thread_kern_sched_jb);
+#if !defined(__ia64__)
SET_STACK_JB(_thread_kern_sched_jb, _thread_kern_sched_stack +
sched_stack_size - sizeof(double));
+#else
+ SET_STACK_JB(_thread_kern_sched_jb, _thread_kern_sched_stack,
+ sched_stack_size);
+#endif
SET_RETURN_ADDR_JB(_thread_kern_sched_jb, _thread_kern_scheduler);
/*
diff --git a/lib/libc_r/uthread/uthread_sig.c b/lib/libc_r/uthread/uthread_sig.c
index 5e3c9b9..b99c64d 100644
--- a/lib/libc_r/uthread/uthread_sig.c
+++ b/lib/libc_r/uthread/uthread_sig.c
@@ -1043,15 +1043,20 @@ thread_sigframe_add(struct pthread *thread, int sig, int has_args)
/* Get the top of the threads stack: */
stackp = GET_STACK_JB(thread->ctx.jb);
+#if !defined(__ia64__)
/*
* Leave a little space on the stack and round down to the
* nearest aligned word:
*/
stackp -= sizeof(double);
stackp &= ~0x3UL;
+#endif
/* Allocate room on top of the stack for a new signal frame: */
stackp -= sizeof(struct pthread_signal_frame);
+#if defined(__ia64__)
+ stackp &= ~0xFUL;
+#endif
psf = (struct pthread_signal_frame *) stackp;
@@ -1080,9 +1085,15 @@ thread_sigframe_add(struct pthread *thread, int sig, int has_args)
/*
* Set up the context:
*/
+#if !defined(__ia64__)
stackp -= sizeof(double);
+#endif
_setjmp(thread->ctx.jb);
+#if !defined(__ia64__)
SET_STACK_JB(thread->ctx.jb, stackp);
+#else
+ UPD_STACK_JB(thread->ctx.jb, stackp - 16);
+#endif
SET_RETURN_ADDR_JB(thread->ctx.jb, _thread_sig_wrapper);
}
OpenPOWER on IntegriCloud