Implement RUSAGE_THREAD. Add td_rux to keep extended runtime and ticks
information for thread to allow calcru1() (re)use. Rename ruxagg()->ruxagg_locked(), ruxagg_tlock()->ruxagg() [1]. The ruxagg_locked() function no longer clears thread ticks nor td_incruntime. Requested by: attilio [1] Discussed with: attilio, bde Reviewed by: bde Based on submission by: Alexander Krizhanovsky <ak natsys-lab com> MFC after: 1 week X-MFC-Note: td_rux shall be moved to the end of struct thread
This commit is contained in:
+24
-13
@@ -76,7 +76,7 @@ static void calcru1(struct proc *p, struct rusage_ext *ruxp,
|
|||||||
struct timeval *up, struct timeval *sp);
|
struct timeval *up, struct timeval *sp);
|
||||||
static int donice(struct thread *td, struct proc *chgp, int n);
|
static int donice(struct thread *td, struct proc *chgp, int n);
|
||||||
static struct uidinfo *uilookup(uid_t uid);
|
static struct uidinfo *uilookup(uid_t uid);
|
||||||
static void ruxagg_tlock(struct proc *p, struct thread *td);
|
static void ruxagg(struct proc *p, struct thread *td);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Resource controls and accounting.
|
* Resource controls and accounting.
|
||||||
@@ -630,7 +630,7 @@ lim_cb(void *arg)
|
|||||||
return;
|
return;
|
||||||
PROC_SLOCK(p);
|
PROC_SLOCK(p);
|
||||||
FOREACH_THREAD_IN_PROC(p, td) {
|
FOREACH_THREAD_IN_PROC(p, td) {
|
||||||
ruxagg_tlock(p, td);
|
ruxagg(p, td);
|
||||||
}
|
}
|
||||||
PROC_SUNLOCK(p);
|
PROC_SUNLOCK(p);
|
||||||
if (p->p_rux.rux_runtime > p->p_cpulimit * cpu_tickrate()) {
|
if (p->p_rux.rux_runtime > p->p_cpulimit * cpu_tickrate()) {
|
||||||
@@ -841,7 +841,7 @@ calcru(struct proc *p, struct timeval *up, struct timeval *sp)
|
|||||||
FOREACH_THREAD_IN_PROC(p, td) {
|
FOREACH_THREAD_IN_PROC(p, td) {
|
||||||
if (td->td_incruntime == 0)
|
if (td->td_incruntime == 0)
|
||||||
continue;
|
continue;
|
||||||
ruxagg_tlock(p, td);
|
ruxagg(p, td);
|
||||||
}
|
}
|
||||||
calcru1(p, &p->p_rux, up, sp);
|
calcru1(p, &p->p_rux, up, sp);
|
||||||
}
|
}
|
||||||
@@ -961,6 +961,16 @@ kern_getrusage(struct thread *td, int who, struct rusage *rup)
|
|||||||
calccru(p, &rup->ru_utime, &rup->ru_stime);
|
calccru(p, &rup->ru_utime, &rup->ru_stime);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case RUSAGE_THREAD:
|
||||||
|
PROC_SLOCK(p);
|
||||||
|
ruxagg(p, td);
|
||||||
|
PROC_SUNLOCK(p);
|
||||||
|
thread_lock(td);
|
||||||
|
*rup = td->td_ru;
|
||||||
|
calcru1(p, &td->td_rux, &rup->ru_utime, &rup->ru_stime);
|
||||||
|
thread_unlock(td);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
}
|
}
|
||||||
@@ -1001,7 +1011,7 @@ ruadd(struct rusage *ru, struct rusage_ext *rux, struct rusage *ru2,
|
|||||||
* Aggregate tick counts into the proc's rusage_ext.
|
* Aggregate tick counts into the proc's rusage_ext.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
ruxagg(struct rusage_ext *rux, struct thread *td)
|
ruxagg_locked(struct rusage_ext *rux, struct thread *td)
|
||||||
{
|
{
|
||||||
|
|
||||||
THREAD_LOCK_ASSERT(td, MA_OWNED);
|
THREAD_LOCK_ASSERT(td, MA_OWNED);
|
||||||
@@ -1010,18 +1020,19 @@ ruxagg(struct rusage_ext *rux, struct thread *td)
|
|||||||
rux->rux_uticks += td->td_uticks;
|
rux->rux_uticks += td->td_uticks;
|
||||||
rux->rux_sticks += td->td_sticks;
|
rux->rux_sticks += td->td_sticks;
|
||||||
rux->rux_iticks += td->td_iticks;
|
rux->rux_iticks += td->td_iticks;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
ruxagg(struct proc *p, struct thread *td)
|
||||||
|
{
|
||||||
|
|
||||||
|
thread_lock(td);
|
||||||
|
ruxagg_locked(&p->p_rux, td);
|
||||||
|
ruxagg_locked(&td->td_rux, td);
|
||||||
td->td_incruntime = 0;
|
td->td_incruntime = 0;
|
||||||
td->td_uticks = 0;
|
td->td_uticks = 0;
|
||||||
td->td_iticks = 0;
|
td->td_iticks = 0;
|
||||||
td->td_sticks = 0;
|
td->td_sticks = 0;
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
ruxagg_tlock(struct proc *p, struct thread *td)
|
|
||||||
{
|
|
||||||
|
|
||||||
thread_lock(td);
|
|
||||||
ruxagg(&p->p_rux, td);
|
|
||||||
thread_unlock(td);
|
thread_unlock(td);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1039,7 +1050,7 @@ rufetch(struct proc *p, struct rusage *ru)
|
|||||||
*ru = p->p_ru;
|
*ru = p->p_ru;
|
||||||
if (p->p_numthreads > 0) {
|
if (p->p_numthreads > 0) {
|
||||||
FOREACH_THREAD_IN_PROC(p, td) {
|
FOREACH_THREAD_IN_PROC(p, td) {
|
||||||
ruxagg_tlock(p, td);
|
ruxagg(p, td);
|
||||||
rucollect(ru, &td->td_ru);
|
rucollect(ru, &td->td_ru);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -432,7 +432,7 @@ thread_exit(void)
|
|||||||
PROC_UNLOCK(p);
|
PROC_UNLOCK(p);
|
||||||
thread_lock(td);
|
thread_lock(td);
|
||||||
/* Save our tick information with both the thread and proc locked */
|
/* Save our tick information with both the thread and proc locked */
|
||||||
ruxagg(&p->p_rux, td);
|
ruxagg_locked(&p->p_rux, td);
|
||||||
PROC_SUNLOCK(p);
|
PROC_SUNLOCK(p);
|
||||||
td->td_state = TDS_INACTIVE;
|
td->td_state = TDS_INACTIVE;
|
||||||
#ifdef WITNESS
|
#ifdef WITNESS
|
||||||
|
|||||||
+2
-1
@@ -240,7 +240,8 @@ struct thread {
|
|||||||
u_int td_estcpu; /* (t) estimated cpu utilization */
|
u_int td_estcpu; /* (t) estimated cpu utilization */
|
||||||
int td_slptick; /* (t) Time at sleep. */
|
int td_slptick; /* (t) Time at sleep. */
|
||||||
int td_blktick; /* (t) Time spent blocked. */
|
int td_blktick; /* (t) Time spent blocked. */
|
||||||
struct rusage td_ru; /* (t) rusage information */
|
struct rusage td_ru; /* (t) rusage information. */
|
||||||
|
struct rusage_ext td_rux; /* (t) Internal rusage information. */
|
||||||
uint64_t td_incruntime; /* (t) Cpu ticks to transfer to proc. */
|
uint64_t td_incruntime; /* (t) Cpu ticks to transfer to proc. */
|
||||||
uint64_t td_runtime; /* (t) How many cpu ticks we've run. */
|
uint64_t td_runtime; /* (t) How many cpu ticks we've run. */
|
||||||
u_int td_pticks; /* (t) Statclock hits for profiling */
|
u_int td_pticks; /* (t) Statclock hits for profiling */
|
||||||
|
|||||||
@@ -56,6 +56,7 @@
|
|||||||
|
|
||||||
#define RUSAGE_SELF 0
|
#define RUSAGE_SELF 0
|
||||||
#define RUSAGE_CHILDREN -1
|
#define RUSAGE_CHILDREN -1
|
||||||
|
#define RUSAGE_THREAD 1
|
||||||
|
|
||||||
struct rusage {
|
struct rusage {
|
||||||
struct timeval ru_utime; /* user time used */
|
struct timeval ru_utime; /* user time used */
|
||||||
|
|||||||
@@ -131,7 +131,7 @@ void rucollect(struct rusage *ru, struct rusage *ru2);
|
|||||||
void rufetch(struct proc *p, struct rusage *ru);
|
void rufetch(struct proc *p, struct rusage *ru);
|
||||||
void rufetchcalc(struct proc *p, struct rusage *ru, struct timeval *up,
|
void rufetchcalc(struct proc *p, struct rusage *ru, struct timeval *up,
|
||||||
struct timeval *sp);
|
struct timeval *sp);
|
||||||
void ruxagg(struct rusage_ext *rux, struct thread *td);
|
void ruxagg_locked(struct rusage_ext *rux, struct thread *td);
|
||||||
int suswintr(void *base, int word);
|
int suswintr(void *base, int word);
|
||||||
struct uidinfo
|
struct uidinfo
|
||||||
*uifind(uid_t uid);
|
*uifind(uid_t uid);
|
||||||
|
|||||||
Reference in New Issue
Block a user