1
0
mirror of https://git.FreeBSD.org/src.git synced 2025-01-19 15:33:56 +00:00

Remove un-needed code.

Don't copyin() data we are about to overwrite.
Add a flag to tell userland that KSE is officially "DONE" with the
mailbox and has gone away.

Obtained from:	davidxu@
This commit is contained in:
Julian Elischer 2003-06-04 00:12:57 +00:00
parent de7f8045e0
commit 2b035cbe5a
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=115790
4 changed files with 56 additions and 100 deletions

View File

@ -422,21 +422,36 @@ kse_exit(struct thread *td, struct kse_exit_args *uap)
struct proc *p;
struct ksegrp *kg;
struct kse *ke;
struct kse_upcall *ku, *ku2;
int error, count;
p = td->td_proc;
if (td->td_upcall == NULL || TD_CAN_UNBIND(td))
if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td))
return (EINVAL);
kg = td->td_ksegrp;
/* Serialize removing upcall */
count = 0;
PROC_LOCK(p);
mtx_lock_spin(&sched_lock);
if ((kg->kg_numupcalls == 1) && (kg->kg_numthreads > 1)) {
FOREACH_UPCALL_IN_GROUP(kg, ku2) {
if (ku2->ku_flags & KUF_EXITING)
count++;
}
if ((kg->kg_numupcalls - count) == 1 &&
(kg->kg_numthreads > 1)) {
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
return (EDEADLK);
}
ke = td->td_kse;
ku->ku_flags |= KUF_EXITING;
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
error = suword(&ku->ku_mailbox->km_flags, ku->ku_mflags|KMF_DONE);
PROC_LOCK(p);
if (error)
psignal(p, SIGSEGV);
mtx_lock_spin(&sched_lock);
upcall_remove(td);
ke = td->td_kse;
if (p->p_numthreads == 1) {
kse_purge(p, td);
p->p_flag &= ~P_THREADED;
@ -720,41 +735,6 @@ kse_create(struct thread *td, struct kse_create_args *uap)
return (0);
}
/*
* Fill a ucontext_t with a thread's context information.
*
* This is an analogue to getcontext(3).
*/
void
thread_getcontext(struct thread *td, ucontext_t *uc)
{
get_mcontext(td, &uc->uc_mcontext, 0);
PROC_LOCK(td->td_proc);
uc->uc_sigmask = td->td_sigmask;
PROC_UNLOCK(td->td_proc);
}
/*
* Set a thread's context from a ucontext_t.
*
* This is an analogue to setcontext(3).
*/
int
thread_setcontext(struct thread *td, ucontext_t *uc)
{
int ret;
ret = set_mcontext(td, &uc->uc_mcontext);
if (ret == 0) {
SIG_CANTMASK(uc->uc_sigmask);
PROC_LOCK(td->td_proc);
td->td_sigmask = uc->uc_sigmask;
PROC_UNLOCK(td->td_proc);
}
return (ret);
}
/*
* Initialize global thread allocation resources.
*/
@ -948,27 +928,25 @@ thread_export_context(struct thread *td)
uintptr_t mbx;
void *addr;
int error,temp;
ucontext_t uc;
mcontext_t mc;
p = td->td_proc;
kg = td->td_ksegrp;
/* Export the user/machine context. */
addr = (void *)(&td->td_mailbox->tm_context);
error = copyin(addr, &uc, sizeof(ucontext_t));
if (error)
goto bad;
thread_getcontext(td, &uc);
error = copyout(&uc, addr, sizeof(ucontext_t));
if (error)
get_mcontext(td, &mc, 0);
addr = (void *)(&td->td_mailbox->tm_context.uc_mcontext);
error = copyout(&mc, addr, sizeof(mcontext_t));
if (error)
goto bad;
/* Exports clock ticks in kernel mode */
addr = (caddr_t)(&td->td_mailbox->tm_sticks);
temp = fuword(addr) + td->td_usticks;
if (suword(addr, temp))
if (suword(addr, temp)) {
error = EFAULT;
goto bad;
}
/* Get address in latest mbox of list pointer */
addr = (void *)(&td->td_mailbox->tm_next);

View File

@ -422,21 +422,36 @@ kse_exit(struct thread *td, struct kse_exit_args *uap)
struct proc *p;
struct ksegrp *kg;
struct kse *ke;
struct kse_upcall *ku, *ku2;
int error, count;
p = td->td_proc;
if (td->td_upcall == NULL || TD_CAN_UNBIND(td))
if ((ku = td->td_upcall) == NULL || TD_CAN_UNBIND(td))
return (EINVAL);
kg = td->td_ksegrp;
/* Serialize removing upcall */
count = 0;
PROC_LOCK(p);
mtx_lock_spin(&sched_lock);
if ((kg->kg_numupcalls == 1) && (kg->kg_numthreads > 1)) {
FOREACH_UPCALL_IN_GROUP(kg, ku2) {
if (ku2->ku_flags & KUF_EXITING)
count++;
}
if ((kg->kg_numupcalls - count) == 1 &&
(kg->kg_numthreads > 1)) {
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
return (EDEADLK);
}
ke = td->td_kse;
ku->ku_flags |= KUF_EXITING;
mtx_unlock_spin(&sched_lock);
PROC_UNLOCK(p);
error = suword(&ku->ku_mailbox->km_flags, ku->ku_mflags|KMF_DONE);
PROC_LOCK(p);
if (error)
psignal(p, SIGSEGV);
mtx_lock_spin(&sched_lock);
upcall_remove(td);
ke = td->td_kse;
if (p->p_numthreads == 1) {
kse_purge(p, td);
p->p_flag &= ~P_THREADED;
@ -720,41 +735,6 @@ kse_create(struct thread *td, struct kse_create_args *uap)
return (0);
}
/*
* Fill a ucontext_t with a thread's context information.
*
* This is an analogue to getcontext(3).
*/
void
thread_getcontext(struct thread *td, ucontext_t *uc)
{
get_mcontext(td, &uc->uc_mcontext, 0);
PROC_LOCK(td->td_proc);
uc->uc_sigmask = td->td_sigmask;
PROC_UNLOCK(td->td_proc);
}
/*
* Set a thread's context from a ucontext_t.
*
* This is an analogue to setcontext(3).
*/
int
thread_setcontext(struct thread *td, ucontext_t *uc)
{
int ret;
ret = set_mcontext(td, &uc->uc_mcontext);
if (ret == 0) {
SIG_CANTMASK(uc->uc_sigmask);
PROC_LOCK(td->td_proc);
td->td_sigmask = uc->uc_sigmask;
PROC_UNLOCK(td->td_proc);
}
return (ret);
}
/*
* Initialize global thread allocation resources.
*/
@ -948,27 +928,25 @@ thread_export_context(struct thread *td)
uintptr_t mbx;
void *addr;
int error,temp;
ucontext_t uc;
mcontext_t mc;
p = td->td_proc;
kg = td->td_ksegrp;
/* Export the user/machine context. */
addr = (void *)(&td->td_mailbox->tm_context);
error = copyin(addr, &uc, sizeof(ucontext_t));
if (error)
goto bad;
thread_getcontext(td, &uc);
error = copyout(&uc, addr, sizeof(ucontext_t));
if (error)
get_mcontext(td, &mc, 0);
addr = (void *)(&td->td_mailbox->tm_context.uc_mcontext);
error = copyout(&mc, addr, sizeof(mcontext_t));
if (error)
goto bad;
/* Exports clock ticks in kernel mode */
addr = (caddr_t)(&td->td_mailbox->tm_sticks);
temp = fuword(addr) + td->td_usticks;
if (suword(addr, temp))
if (suword(addr, temp)) {
error = EFAULT;
goto bad;
}
/* Get address in latest mbox of list pointer */
addr = (void *)(&td->td_mailbox->tm_next);

View File

@ -88,6 +88,7 @@ struct kse_mailbox {
/* These flags are kept in km_flags */
#define KMF_NOUPCALL 0x01
#define KMF_NOCOMPLETED 0x02
#define KMF_DONE 0x04
#ifndef _KERNEL
int kse_create(struct kse_mailbox *, int);

View File

@ -459,6 +459,7 @@ struct kse_upcall {
};
#define KUF_DOUPCALL 0x00001 /* Do upcall now, don't wait */
#define KUF_EXITING 0x00002 /* Upcall structure is exiting */
/*
* Kernel-scheduled entity group (KSEG). The scheduler considers each KSEG to
@ -900,11 +901,9 @@ struct thread *thread_alloc(void);
void thread_exit(void) __dead2;
int thread_export_context(struct thread *td);
void thread_free(struct thread *td);
void thread_getcontext(struct thread *td, ucontext_t *uc);
void thread_link(struct thread *td, struct ksegrp *kg);
void thread_reap(void);
struct thread *thread_schedule_upcall(struct thread *td, struct kse_upcall *ku);
int thread_setcontext(struct thread *td, ucontext_t *uc);
int thread_single(int how);
#define SINGLE_NO_EXIT 0 /* values for 'how' */
#define SINGLE_EXIT 1