Add a simple facility to allow round roubin in userland.
Reviewed by: julain
This commit is contained in:
parent
48d4ffc119
commit
4b4866ed42
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=111515
@ -97,8 +97,7 @@ MTX_SYSINIT(kse_zombie_lock, &kse_zombie_lock, "kse zombie lock", MTX_SPIN);
|
|||||||
|
|
||||||
static void kse_purge(struct proc *p, struct thread *td);
|
static void kse_purge(struct proc *p, struct thread *td);
|
||||||
static void kse_purge_group(struct thread *td);
|
static void kse_purge_group(struct thread *td);
|
||||||
static int thread_update_usr_ticks(struct thread *td);
|
static int thread_update_usr_ticks(struct thread *td, int user);
|
||||||
static int thread_update_sys_ticks(struct thread *td);
|
|
||||||
static void thread_alloc_spare(struct thread *td, struct thread *spare);
|
static void thread_alloc_spare(struct thread *td, struct thread *spare);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1000,6 +999,11 @@ thread_export_context(struct thread *td)
|
|||||||
if (suword(addr, temp))
|
if (suword(addr, temp))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
addr = (caddr_t)(&td->td_mailbox->tm_slices);
|
||||||
|
temp = fuword(addr) - td->td_usticks;
|
||||||
|
if (suword(addr, temp))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
/* Get address in latest mbox of list pointer */
|
/* Get address in latest mbox of list pointer */
|
||||||
addr = (void *)(&td->td_mailbox->tm_next);
|
addr = (void *)(&td->td_mailbox->tm_next);
|
||||||
/*
|
/*
|
||||||
@ -1101,16 +1105,17 @@ thread_statclock(int user)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Export user mode state clock ticks
|
* Export state clock ticks for userland
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
thread_update_usr_ticks(struct thread *td)
|
thread_update_usr_ticks(struct thread *td, int user)
|
||||||
{
|
{
|
||||||
struct proc *p = td->td_proc;
|
struct proc *p = td->td_proc;
|
||||||
struct kse_thr_mailbox *tmbx;
|
struct kse_thr_mailbox *tmbx;
|
||||||
struct kse_upcall *ku;
|
struct kse_upcall *ku;
|
||||||
caddr_t addr;
|
caddr_t addr;
|
||||||
uint uticks;
|
uint uticks;
|
||||||
|
int slices;
|
||||||
|
|
||||||
if ((ku = td->td_upcall) == NULL)
|
if ((ku = td->td_upcall) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -1118,45 +1123,38 @@ thread_update_usr_ticks(struct thread *td)
|
|||||||
tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
|
tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
|
||||||
if ((tmbx == NULL) || (tmbx == (void *)-1))
|
if ((tmbx == NULL) || (tmbx == (void *)-1))
|
||||||
return (-1);
|
return (-1);
|
||||||
uticks = td->td_uuticks;
|
if (user) {
|
||||||
td->td_uuticks = 0;
|
uticks = td->td_uuticks;
|
||||||
if (uticks) {
|
td->td_uuticks = 0;
|
||||||
addr = (caddr_t)&tmbx->tm_uticks;
|
addr = (caddr_t)&tmbx->tm_uticks;
|
||||||
uticks += fuword(addr);
|
} else {
|
||||||
if (suword(addr, uticks)) {
|
uticks = td->td_usticks;
|
||||||
|
td->td_usticks = 0;
|
||||||
|
addr = (caddr_t)&tmbx->tm_sticks;
|
||||||
|
}
|
||||||
|
if (uticks) {
|
||||||
|
if (suword(addr, uticks+fuword(addr))) {
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
psignal(p, SIGSEGV);
|
psignal(p, SIGSEGV);
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
return (-2);
|
return (-2);
|
||||||
}
|
}
|
||||||
}
|
addr = (caddr_t)&tmbx->tm_slices;
|
||||||
return (0);
|
slices = (int)fuword(addr);
|
||||||
}
|
if (slices > 0) {
|
||||||
|
slices -= (int)uticks;
|
||||||
/*
|
if (suword(addr, slices)) {
|
||||||
* Export kernel mode state clock ticks
|
PROC_LOCK(p);
|
||||||
*/
|
psignal(p, SIGSEGV);
|
||||||
|
PROC_UNLOCK(p);
|
||||||
static int
|
return (-2);
|
||||||
thread_update_sys_ticks(struct thread *td)
|
}
|
||||||
{
|
if (slices <= 0) {
|
||||||
struct proc *p = td->td_proc;
|
mtx_lock_spin(&sched_lock);
|
||||||
caddr_t addr;
|
td->td_upcall->ku_flags |= KUF_DOUPCALL;
|
||||||
int sticks;
|
mtx_unlock_spin(&sched_lock);
|
||||||
|
}
|
||||||
if (td->td_mailbox == NULL)
|
}
|
||||||
return (-1);
|
|
||||||
if (td->td_usticks == 0)
|
|
||||||
return (0);
|
|
||||||
addr = (caddr_t)&td->td_mailbox->tm_sticks;
|
|
||||||
sticks = fuword(addr);
|
|
||||||
sticks += td->td_usticks;
|
|
||||||
td->td_usticks = 0;
|
|
||||||
if (suword(addr, sticks)) {
|
|
||||||
PROC_LOCK(p);
|
|
||||||
psignal(p, SIGSEGV);
|
|
||||||
PROC_UNLOCK(p);
|
|
||||||
return (-2);
|
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1580,10 +1578,13 @@ thread_userret(struct thread *td, struct trapframe *frame)
|
|||||||
* userland time for UTS.
|
* userland time for UTS.
|
||||||
*/
|
*/
|
||||||
if (td->td_flags & TDF_USTATCLOCK) {
|
if (td->td_flags & TDF_USTATCLOCK) {
|
||||||
thread_update_usr_ticks(td);
|
thread_update_usr_ticks(td, 1);
|
||||||
mtx_lock_spin(&sched_lock);
|
mtx_lock_spin(&sched_lock);
|
||||||
td->td_flags &= ~TDF_USTATCLOCK;
|
td->td_flags &= ~TDF_USTATCLOCK;
|
||||||
mtx_unlock_spin(&sched_lock);
|
mtx_unlock_spin(&sched_lock);
|
||||||
|
if (kg->kg_completed ||
|
||||||
|
(td->td_upcall->ku_flags & KUF_DOUPCALL))
|
||||||
|
thread_user_enter(p, td);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1598,9 +1599,12 @@ thread_userret(struct thread *td, struct trapframe *frame)
|
|||||||
mtx_unlock_spin(&sched_lock);
|
mtx_unlock_spin(&sched_lock);
|
||||||
if ((kg->kg_completed == NULL) &&
|
if ((kg->kg_completed == NULL) &&
|
||||||
(td->td_upcall->ku_flags & KUF_DOUPCALL) == 0) {
|
(td->td_upcall->ku_flags & KUF_DOUPCALL) == 0) {
|
||||||
thread_update_sys_ticks(td);
|
thread_update_usr_ticks(td, 0);
|
||||||
td->td_mailbox = NULL;
|
if (kg->kg_completed ||
|
||||||
return (0);
|
(td->td_upcall->ku_flags & KUF_DOUPCALL)) {
|
||||||
|
td->td_mailbox = NULL;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
error = thread_export_context(td);
|
error = thread_export_context(td);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -97,8 +97,7 @@ MTX_SYSINIT(kse_zombie_lock, &kse_zombie_lock, "kse zombie lock", MTX_SPIN);
|
|||||||
|
|
||||||
static void kse_purge(struct proc *p, struct thread *td);
|
static void kse_purge(struct proc *p, struct thread *td);
|
||||||
static void kse_purge_group(struct thread *td);
|
static void kse_purge_group(struct thread *td);
|
||||||
static int thread_update_usr_ticks(struct thread *td);
|
static int thread_update_usr_ticks(struct thread *td, int user);
|
||||||
static int thread_update_sys_ticks(struct thread *td);
|
|
||||||
static void thread_alloc_spare(struct thread *td, struct thread *spare);
|
static void thread_alloc_spare(struct thread *td, struct thread *spare);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -1000,6 +999,11 @@ thread_export_context(struct thread *td)
|
|||||||
if (suword(addr, temp))
|
if (suword(addr, temp))
|
||||||
goto bad;
|
goto bad;
|
||||||
|
|
||||||
|
addr = (caddr_t)(&td->td_mailbox->tm_slices);
|
||||||
|
temp = fuword(addr) - td->td_usticks;
|
||||||
|
if (suword(addr, temp))
|
||||||
|
goto bad;
|
||||||
|
|
||||||
/* Get address in latest mbox of list pointer */
|
/* Get address in latest mbox of list pointer */
|
||||||
addr = (void *)(&td->td_mailbox->tm_next);
|
addr = (void *)(&td->td_mailbox->tm_next);
|
||||||
/*
|
/*
|
||||||
@ -1101,16 +1105,17 @@ thread_statclock(int user)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Export user mode state clock ticks
|
* Export state clock ticks for userland
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
thread_update_usr_ticks(struct thread *td)
|
thread_update_usr_ticks(struct thread *td, int user)
|
||||||
{
|
{
|
||||||
struct proc *p = td->td_proc;
|
struct proc *p = td->td_proc;
|
||||||
struct kse_thr_mailbox *tmbx;
|
struct kse_thr_mailbox *tmbx;
|
||||||
struct kse_upcall *ku;
|
struct kse_upcall *ku;
|
||||||
caddr_t addr;
|
caddr_t addr;
|
||||||
uint uticks;
|
uint uticks;
|
||||||
|
int slices;
|
||||||
|
|
||||||
if ((ku = td->td_upcall) == NULL)
|
if ((ku = td->td_upcall) == NULL)
|
||||||
return (-1);
|
return (-1);
|
||||||
@ -1118,45 +1123,38 @@ thread_update_usr_ticks(struct thread *td)
|
|||||||
tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
|
tmbx = (void *)fuword((void *)&ku->ku_mailbox->km_curthread);
|
||||||
if ((tmbx == NULL) || (tmbx == (void *)-1))
|
if ((tmbx == NULL) || (tmbx == (void *)-1))
|
||||||
return (-1);
|
return (-1);
|
||||||
uticks = td->td_uuticks;
|
if (user) {
|
||||||
td->td_uuticks = 0;
|
uticks = td->td_uuticks;
|
||||||
if (uticks) {
|
td->td_uuticks = 0;
|
||||||
addr = (caddr_t)&tmbx->tm_uticks;
|
addr = (caddr_t)&tmbx->tm_uticks;
|
||||||
uticks += fuword(addr);
|
} else {
|
||||||
if (suword(addr, uticks)) {
|
uticks = td->td_usticks;
|
||||||
|
td->td_usticks = 0;
|
||||||
|
addr = (caddr_t)&tmbx->tm_sticks;
|
||||||
|
}
|
||||||
|
if (uticks) {
|
||||||
|
if (suword(addr, uticks+fuword(addr))) {
|
||||||
PROC_LOCK(p);
|
PROC_LOCK(p);
|
||||||
psignal(p, SIGSEGV);
|
psignal(p, SIGSEGV);
|
||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
return (-2);
|
return (-2);
|
||||||
}
|
}
|
||||||
}
|
addr = (caddr_t)&tmbx->tm_slices;
|
||||||
return (0);
|
slices = (int)fuword(addr);
|
||||||
}
|
if (slices > 0) {
|
||||||
|
slices -= (int)uticks;
|
||||||
/*
|
if (suword(addr, slices)) {
|
||||||
* Export kernel mode state clock ticks
|
PROC_LOCK(p);
|
||||||
*/
|
psignal(p, SIGSEGV);
|
||||||
|
PROC_UNLOCK(p);
|
||||||
static int
|
return (-2);
|
||||||
thread_update_sys_ticks(struct thread *td)
|
}
|
||||||
{
|
if (slices <= 0) {
|
||||||
struct proc *p = td->td_proc;
|
mtx_lock_spin(&sched_lock);
|
||||||
caddr_t addr;
|
td->td_upcall->ku_flags |= KUF_DOUPCALL;
|
||||||
int sticks;
|
mtx_unlock_spin(&sched_lock);
|
||||||
|
}
|
||||||
if (td->td_mailbox == NULL)
|
}
|
||||||
return (-1);
|
|
||||||
if (td->td_usticks == 0)
|
|
||||||
return (0);
|
|
||||||
addr = (caddr_t)&td->td_mailbox->tm_sticks;
|
|
||||||
sticks = fuword(addr);
|
|
||||||
sticks += td->td_usticks;
|
|
||||||
td->td_usticks = 0;
|
|
||||||
if (suword(addr, sticks)) {
|
|
||||||
PROC_LOCK(p);
|
|
||||||
psignal(p, SIGSEGV);
|
|
||||||
PROC_UNLOCK(p);
|
|
||||||
return (-2);
|
|
||||||
}
|
}
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1580,10 +1578,13 @@ thread_userret(struct thread *td, struct trapframe *frame)
|
|||||||
* userland time for UTS.
|
* userland time for UTS.
|
||||||
*/
|
*/
|
||||||
if (td->td_flags & TDF_USTATCLOCK) {
|
if (td->td_flags & TDF_USTATCLOCK) {
|
||||||
thread_update_usr_ticks(td);
|
thread_update_usr_ticks(td, 1);
|
||||||
mtx_lock_spin(&sched_lock);
|
mtx_lock_spin(&sched_lock);
|
||||||
td->td_flags &= ~TDF_USTATCLOCK;
|
td->td_flags &= ~TDF_USTATCLOCK;
|
||||||
mtx_unlock_spin(&sched_lock);
|
mtx_unlock_spin(&sched_lock);
|
||||||
|
if (kg->kg_completed ||
|
||||||
|
(td->td_upcall->ku_flags & KUF_DOUPCALL))
|
||||||
|
thread_user_enter(p, td);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1598,9 +1599,12 @@ thread_userret(struct thread *td, struct trapframe *frame)
|
|||||||
mtx_unlock_spin(&sched_lock);
|
mtx_unlock_spin(&sched_lock);
|
||||||
if ((kg->kg_completed == NULL) &&
|
if ((kg->kg_completed == NULL) &&
|
||||||
(td->td_upcall->ku_flags & KUF_DOUPCALL) == 0) {
|
(td->td_upcall->ku_flags & KUF_DOUPCALL) == 0) {
|
||||||
thread_update_sys_ticks(td);
|
thread_update_usr_ticks(td, 0);
|
||||||
td->td_mailbox = NULL;
|
if (kg->kg_completed ||
|
||||||
return (0);
|
(td->td_upcall->ku_flags & KUF_DOUPCALL)) {
|
||||||
|
td->td_mailbox = NULL;
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
error = thread_export_context(td);
|
error = thread_export_context(td);
|
||||||
if (error) {
|
if (error) {
|
||||||
|
@ -59,6 +59,7 @@ struct kse_thr_mailbox {
|
|||||||
void *tm_udata; /* For use by the UTS */
|
void *tm_udata; /* For use by the UTS */
|
||||||
unsigned int tm_uticks;
|
unsigned int tm_uticks;
|
||||||
unsigned int tm_sticks;
|
unsigned int tm_sticks;
|
||||||
|
int tm_slices;
|
||||||
int tm_spare[8];
|
int tm_spare[8];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user