summaryrefslogtreecommitdiffstats
path: root/sys/sparc64
diff options
context:
space:
mode:
authorjulian <julian@FreeBSD.org>2002-06-29 17:26:22 +0000
committerjulian <julian@FreeBSD.org>2002-06-29 17:26:22 +0000
commitaa2dc0a5d9e7a19420c153cd414fefa8498eab71 (patch)
tree0a0483a267784fa8e2bf86857d8727edb5b122e9 /sys/sparc64
parent6dbff7f2c1f8150887038aed666e11675adf0b4e (diff)
downloadFreeBSD-src-aa2dc0a5d9e7a19420c153cd414fefa8498eab71.zip
FreeBSD-src-aa2dc0a5d9e7a19420c153cd414fefa8498eab71.tar.gz
Part 1 of KSE-III
The ability to schedule multiple threads per process (one one cpu) by making ALL system calls optionally asynchronous. to come: ia64 and power-pc patches, patches for gdb, test program (in tools) Reviewed by: Almost everyone who counts (at various times, peter, jhb, matt, alfred, mini, bernd, and a cast of thousands) NOTE: this is still Beta code, and contains lots of debugging stuff. expect slight instability in signals..
Diffstat (limited to 'sys/sparc64')
-rw-r--r--sys/sparc64/sparc64/genassym.c2
-rw-r--r--sys/sparc64/sparc64/swtch.S3
-rw-r--r--sys/sparc64/sparc64/swtch.s3
-rw-r--r--sys/sparc64/sparc64/trap.c33
-rw-r--r--sys/sparc64/sparc64/vm_machdep.c36
5 files changed, 72 insertions, 5 deletions
diff --git a/sys/sparc64/sparc64/genassym.c b/sys/sparc64/sparc64/genassym.c
index 4f47a75..eee4abc 100644
--- a/sys/sparc64/sparc64/genassym.c
+++ b/sys/sparc64/sparc64/genassym.c
@@ -232,6 +232,8 @@ ASSYM(TD_KSE, offsetof(struct thread, td_kse));
ASSYM(TD_KSTACK, offsetof(struct thread, td_kstack));
ASSYM(TD_PCB, offsetof(struct thread, td_pcb));
ASSYM(TD_PROC, offsetof(struct thread, td_proc));
+ASSYM(TD_STATE, offsetof(struct thread, td_state));
+ASSYM(TDS_RUNNING, TDS_RUNNING);
ASSYM(PCB_SIZEOF, sizeof(struct pcb));
ASSYM(PCB_FPSTATE, offsetof(struct pcb, pcb_fpstate));
diff --git a/sys/sparc64/sparc64/swtch.S b/sys/sparc64/sparc64/swtch.S
index 429e961..a8a753a 100644
--- a/sys/sparc64/sparc64/swtch.S
+++ b/sys/sparc64/sparc64/swtch.S
@@ -109,6 +109,9 @@ ENTRY(cpu_switch)
stx %o0, [PCPU(CURTHREAD)]
stx %o1, [PCPU(CURPCB)]
+ mov TDS_RUNNING, %o2
+ stw %o2, [%o0 + TD_STATE]
+
SET(sched_lock, %o3, %o2)
stx %o0, [%o2 + MTX_LOCK]
diff --git a/sys/sparc64/sparc64/swtch.s b/sys/sparc64/sparc64/swtch.s
index 429e961..a8a753a 100644
--- a/sys/sparc64/sparc64/swtch.s
+++ b/sys/sparc64/sparc64/swtch.s
@@ -109,6 +109,9 @@ ENTRY(cpu_switch)
stx %o0, [PCPU(CURTHREAD)]
stx %o1, [PCPU(CURPCB)]
+ mov TDS_RUNNING, %o2
+ stw %o2, [%o0 + TD_STATE]
+
SET(sched_lock, %o3, %o2)
stx %o0, [%o2 + MTX_LOCK]
diff --git a/sys/sparc64/sparc64/trap.c b/sys/sparc64/sparc64/trap.c
index 61e3b44..f39d2f6 100644
--- a/sys/sparc64/sparc64/trap.c
+++ b/sys/sparc64/sparc64/trap.c
@@ -49,6 +49,7 @@
#include <sys/bus.h>
#include <sys/interrupt.h>
#include <sys/ktr.h>
+#include <sys/kse.h>
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/systm.h>
@@ -190,6 +191,11 @@ trap(struct trapframe *tf)
td->td_frame = tf;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
+ if ((p->p_flag & P_WEXIT) && (p->p_singlethread != td)) {
+ mtx_lock_spin(&sched_lock);
+ thread_exit();
+ /* NOTREACHED */
+ }
} else {
sticks = 0;
if ((type & ~T_KERNEL) != T_BREAKPOINT)
@@ -528,6 +534,23 @@ syscall(struct trapframe *tf)
td->td_frame = tf;
if (td->td_ucred != p->p_ucred)
cred_update_thread(td);
+ if (p->p_flag & P_KSES) {
+ /*
+ * If we are doing a syscall in a KSE environment,
+ * note where our mailbox is. There is always the
+ * possibility that we could do this lazily (in sleep()),
+ * but for now do it every time.
+ */
+ td->td_mailbox = (void *)fuword((caddr_t)td->td_kse->ke_mailbox
+ + offsetof(struct kse_mailbox, kmbx_current_thread));
+ if ((td->td_mailbox == NULL) ||
+ (td->td_mailbox == (void *)-1)) {
+ td->td_mailbox = NULL; /* single thread it.. */
+ td->td_flags &= ~TDF_UNBOUND;
+ } else {
+ td->td_flags |= TDF_UNBOUND;
+ }
+ }
code = tf->tf_global[1];
/*
@@ -634,17 +657,17 @@ syscall(struct trapframe *tf)
}
/*
- * Handle reschedule and other end-of-syscall issues
- */
- userret(td, tf, sticks);
-
- /*
* Release Giant if we had to get it. Don't use mtx_owned(),
* we want to catch broken syscalls.
*/
if ((callp->sy_narg & SYF_MPSAFE) == 0)
mtx_unlock(&Giant);
+ /*
+ * Handle reschedule and other end-of-syscall issues
+ */
+ userret(td, tf, sticks);
+
#ifdef KTRACE
if (KTRPOINT(td, KTR_SYSRET))
ktrsysret(code, error, td->td_retval[0]);
diff --git a/sys/sparc64/sparc64/vm_machdep.c b/sys/sparc64/sparc64/vm_machdep.c
index a896754..8282e93 100644
--- a/sys/sparc64/sparc64/vm_machdep.c
+++ b/sys/sparc64/sparc64/vm_machdep.c
@@ -108,6 +108,42 @@ cpu_sched_exit(struct thread *td)
}
}
+void
+cpu_thread_exit(struct thread *td)
+{
+}
+
+void
+cpu_thread_setup(struct thread *td)
+{
+}
+
+void
+cpu_save_upcall(struct thread *td, struct kse *newkse)
+{
+}
+
+void
+cpu_set_upcall(struct thread *td, void *pcb)
+{
+}
+
+void
+cpu_set_args(struct thread *td, struct kse *ke)
+{
+}
+
+void
+cpu_free_kse_mdstorage(struct kse *ke)
+{
+}
+
+int
+cpu_export_context(struct thread *td)
+{
+ return (0);
+}
+
/*
* Finish a fork operation, with process p2 nearly set up.
* Copy and update the pcb, set up the stack so that the child
OpenPOWER on IntegriCloud