summaryrefslogtreecommitdiff
path: root/sys/src/9/port/proc.c
diff options
context:
space:
mode:
authorcinap_lenrek <cinap_lenrek@felloff.net>2020-12-20 22:34:41 +0100
committercinap_lenrek <cinap_lenrek@felloff.net>2020-12-20 22:34:41 +0100
commite4ce6aadac9e1de8d5ea625e9680d24cabce0e1a (patch)
tree63c0b00f6f2c8eac29d4a0354d402206bc61397a /sys/src/9/port/proc.c
parent08c1622b0d8de92c2650d7b0338d9abf20985827 (diff)
kernel: handle tos and per process pcycle counters in port/
we might as well handle the per process cycle counter in the portable part instead of duplicating the code in every arch and have inconsistent implementations. we now have a portable kenter() and kexit() function, that is ment to be used in trap/syscall from user, which updates the counters. some kernels missed initializing Mach.cyclefreq.
Diffstat (limited to 'sys/src/9/port/proc.c')
-rw-r--r--sys/src/9/port/proc.c105
1 files changed, 73 insertions, 32 deletions
diff --git a/sys/src/9/port/proc.c b/sys/src/9/port/proc.c
index 211adf9d7..63289d2dc 100644
--- a/sys/src/9/port/proc.c
+++ b/sys/src/9/port/proc.c
@@ -6,6 +6,8 @@
#include "../port/error.h"
#include "edf.h"
#include <trace.h>
+#include "tos.h"
+#include "ureg.h"
int schedgain = 30; /* units in seconds */
int nrdy;
@@ -109,6 +111,58 @@ schedinit(void) /* never returns */
sched();
}
+int
+kenter(Ureg *ureg)
+{
+ int user;
+
+ user = userureg(ureg);
+ if(user){
+ up->dbgreg = ureg;
+ cycles(&up->kentry);
+ }
+ return user;
+}
+
+void
+kexit(Ureg*)
+{
+ uvlong t;
+ Tos *tos;
+
+ cycles(&t);
+
+ /* precise time accounting, kernel exit */
+ tos = (Tos*)(USTKTOP-sizeof(Tos));
+ tos->kcycles += t - up->kentry;
+ tos->pcycles = t + up->pcycles;
+ tos->pid = up->pid;
+}
+
+static void
+procswitch(void)
+{
+ uvlong t;
+
+ /* statistics */
+ m->cs++;
+
+ cycles(&t);
+ up->kentry -= t;
+ up->pcycles += t;
+
+ procsave(up);
+
+ if(!setlabel(&up->sched))
+ gotolabel(&m->sched);
+
+ procrestore(up);
+
+ cycles(&t);
+ up->kentry += t;
+ up->pcycles -= t;
+}
+
/*
* If changing this routine, look also at sleep(). It
* contains a copy of the guts of sched().
@@ -151,19 +205,10 @@ sched(void)
return;
}
up->delaysched = 0;
-
splhi();
-
- /* statistics */
- m->cs++;
-
- procsave(up);
- if(setlabel(&up->sched)){
- procrestore(up);
- spllo();
- return;
- }
- gotolabel(&m->sched);
+ procswitch();
+ spllo();
+ return;
}
p = runproc();
if(p->edf == nil){
@@ -758,25 +803,9 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
pt(up, SSleep, 0);
up->state = Wakeme;
up->r = r;
-
- /* statistics */
- m->cs++;
-
- procsave(up);
- if(setlabel(&up->sched)) {
- /*
- * here when the process is awakened
- */
- procrestore(up);
- spllo();
- } else {
- /*
- * here to go to sleep (i.e. stop Running)
- */
- unlock(&up->rlock);
- unlock(r);
- gotolabel(&m->sched);
- }
+ unlock(&up->rlock);
+ unlock(r);
+ procswitch();
}
if(up->notepending) {
@@ -1376,6 +1405,14 @@ procflushothers(void)
procflushmmu(matchother, up);
}
+static void
+linkproc(void)
+{
+ spllo();
+ (*up->kpfun)(up->kparg);
+ pexit("kproc exiting", 0);
+}
+
void
kproc(char *name, void (*func)(void *), void *arg)
{
@@ -1406,7 +1443,9 @@ kproc(char *name, void (*func)(void *), void *arg)
p->hang = 0;
p->kp = 1;
- kprocchild(p, func, arg);
+ p->kpfun = func;
+ p->kparg = arg;
+ kprocchild(p, linkproc);
kstrdup(&p->text, name);
kstrdup(&p->user, eve);
@@ -1422,6 +1461,8 @@ kproc(char *name, void (*func)(void *), void *arg)
p->insyscall = 1;
memset(p->time, 0, sizeof(p->time));
p->time[TReal] = MACHP(0)->ticks;
+ cycles(&p->kentry);
+ p->pcycles = -p->kentry;
pidalloc(p);