diff options
author | marcel <marcel@FreeBSD.org> | 2003-12-07 19:34:29 +0000 |
---|---|---|
committer | marcel <marcel@FreeBSD.org> | 2003-12-07 19:34:29 +0000 |
commit | 2ba380839b51268fdea62444f179aed76fb83b0e (patch) | |
tree | 08f2958e6ff4c6406aee376ff848a178ecfeda26 /sys/kern/kern_kse.c | |
parent | 0e8712116d44b45f10cfd5b1b09b736cffff4b76 (diff) | |
download | FreeBSD-src-2ba380839b51268fdea62444f179aed76fb83b0e.zip FreeBSD-src-2ba380839b51268fdea62444f179aed76fb83b0e.tar.gz |
Add kse_switchin(2). This syscall can be used by KSE implementations
to have the kernel switch to a new thread, instead of doing it in
userland. It is in fact needed on ia64 where syscall restarts do not
return to userland first. It's completely handled inside the kernel.
As such, any context created by the kernel as part of an upcall and
caused by some syscall needs to be restored by the kernel.
Diffstat (limited to 'sys/kern/kern_kse.c')
-rw-r--r-- | sys/kern/kern_kse.c | 24 |
1 files changed, 24 insertions, 0 deletions
diff --git a/sys/kern/kern_kse.c b/sys/kern/kern_kse.c index 985fce2..f47beec 100644 --- a/sys/kern/kern_kse.c +++ b/sys/kern/kern_kse.c @@ -382,6 +382,30 @@ proc_linkup(struct proc *p, struct ksegrp *kg, thread_link(td, kg); } +#ifndef _SYS_SYSPROTO_H_ +struct kse_switchin_args { + const struct __mcontext *mcp; + long val; + long *loc; +}; +#endif + +int +kse_switchin(struct thread *td, struct kse_switchin_args *uap) +{ + mcontext_t mc; + int error; + + error = (uap->mcp == NULL) ? EINVAL : 0; + if (!error) + error = copyin(uap->mcp, &mc, sizeof(mc)); + if (!error) + error = set_mcontext(td, &mc); + if (!error && uap->loc != NULL) + suword(uap->loc, uap->val); + return ((error == 0) ? EJUSTRETURN : error); +} + /* struct kse_thr_interrupt_args { struct kse_thr_mailbox * tmbx; |