OK, turing.

<- leave blank

Mon May 6 18:41:55 EDT 2024

 echo 'key proto=dp9ik dom=9front user=glenda !password=p@ssw0rd' \
    >/mnt/factotum/ctl
aux/listen1 -t 'tcp!*!rcpu' /rc/bin/service/tcp17019

Mon May 6 17:56:38 EDT 2024
Protect your rights with us!
Get professional legal advice from experienced lawyers.
Visit our lawyers website and schedule a meeting today.
Your safety and peace are our top priority!
Our website https://adm-tigin.ru

Mon May 6 15:39:06 EDT 2024
"IT'S...A MILLION DOLLAR...GIVEAWAY"

YOUR ATTENTION PLEASE!  ALL YOU HAVE TO DO IS SUBSCRIBE TO THE WEBSITE BELOW.
THAT'S IT!

AND A FREE $25 DOLLAR GIFT CARD WILL BE EMAILED BACK TO YOU.  "NO SUBSCRIPTION
NEEDED" WHICH MEANS NO CREDIT CARDS" JUST SUBSCRIBE USING YOUR EMAIL ADDRESS ONLY!

TO TAKE ADVANTAGE OF THIS "PROMOTIONAL REWARD" FROM 3 KINGS...USE YOUR GIFT CARD
TO PURCHASE ONE OF OUR "RECTANGLE KEY RINGS" FOR ONLY $29.99.

THIS IS PART OF OUR "SPECIAL OFFER" FOR SUBSCRIBING TO OUR WEBSITE, AS WE LOOK TO
EXPAND OUR BUSINESS.

VISIT: HTTPS://WWW.MYMOVIEQUOTETSHIRTS.COM

(GIFT CARD WILL EXPIRE IN TWO WEEKS IF NOT USED)

Mon May 6 12:21:41 EDT 2024
diff bd1305a0b9841d65f95b4d81fa0d29067425833a uncommitted
--- /dev/null
+++ b/sys/man/1/vcrop
@@ -1,0 +1,28 @@
+.TH VCROP 1
+.SH NAME
+vcrop \- crop image visually
+.SH SYNOPSIS
+.B vcrop
+[
+.I file
+]
+.SH DESCRIPTION
+.I Vcrop
+displays an image read either from
+.B file
+or from
+.B standard input
+and allows to crop it interactively.
+.PP
+Button 1 pans the image within the window
+.PP
+Button 2 triggers the cropping area selection.  Area can then be selected by
sweeping Button 1.
+.PP
+Button 3 brings up a menu of actions.
+.SH SOURCE
+/sys/src/cmd/vcrop.c
+.SH "SEE ALSO"
+.IR crop (1)
+.SH HISTORY
+vcrop first appeared in 9front (May, 2024).
+
--- /dev/null
+++ b/sys/src/cmd/vcrop.c
@@ -1,0 +1,212 @@
+#include <u.h>
+#include <libc.h>
+#include <thread.h>
+#include <draw.h>
+#include <mouse.h>
+#include <keyboard.h>
+
+enum
+{
+ Threshold = 5,
+};
+
+enum
+{
+ Emouse,
+ Eresize,
+ Ekeyboard,
+};
+
+Mousectl *mctl;
+Keyboardctl *kctl;
+Image *bg;
+Image *p;
+Image *n;
+Point pos, oldpos;
+enum { Mcrop, Mundo, Msave, Mexit };
+char *menustr[] = { "crop", "undo", "save", "exit", 0 };
+Menu menu = { menustr };
+
+void
+redraw(void)
+{
+ draw(screen, screen->r, bg, nil, ZP);
+ draw(screen, rectaddpt(n->r, addpt(pos, screen->r.min)), n, nil,
n->r.min);
+ flushimage(display, 1);
+}
+
+void
+translate(Point d)
+{
+ Rectangle r, nr;
+
+ if(d.x==0 && d.y==0)
+ return;
+ r = rectaddpt(n->r, addpt(pos, screen->r.min));
+ pos = addpt(pos, d);
+ nr = rectaddpt(r, d);
+ draw(screen, screen->r, bg, nil, ZP);
+ draw(screen, nr, n, nil, n->r.min);
+ flushimage(display, 1);
+}
+
+void
+crop(void)
+{
+ Rectangle r;
+ Point o;
+ Image *i;
+
+ r = getrect(1, mctl);
+ if(eqrect(r, ZR) || badrect(r) || (Dx(r)<Threshold && Dy(r)<Threshold))
+ return;
+ o = subpt(r.min, screen->r.min);
+ o = addpt(n->r.min, o);
+ o = subpt(o, addpt(n->r.min, pos));
+ /* clamp rect to image bounds */
+ if(o.x < n->r.min.x) o.x = n->r.min.x;
+ if(o.y < n->r.min.y) o.y = n->r.min.y;
+ if((o.x + Dx(r)) > n->r.max.x) r.max.x = r.min.x + n->r.max.x - o.x;
+ if((o.y + Dy(r)) > n->r.max.y) r.max.y = r.min.y + n->r.max.y - o.y;
+ i = allocimage(display, r, n->chan, 0, DTransparent);
+ if(i==nil)
+ sysfatal("allocimage: %r");
+ draw(i, i->r, n, nil, o);
+ if(p)
+ freeimage(p);
+ p = n;
+ n = i;
+ oldpos = pos;
+ pos = subpt(ZP, n->r.min);
+ redraw();
+}
+
+void
+save(void)
+{
+ char buf[4096] = {0};
+ int i, fd;
+
+ i = enter("Save as:", buf, sizeof buf, mctl, kctl, nil);
+ if(i<=0)
+ return;
+ fd = create(buf, OWRITE, 0644);
+ if(fd<0)
+ sysfatal("create: %r");
+ i = writeimage(fd, n, 0);
+ if(i<0)
+ sysfatal("writeimage: %r");
+ close(fd);
+}
+
+void
+undo(void)
+{
+ if(p==nil)
+ return;
+ freeimage(n);
+ n = p;
+ p = nil;
+ pos = oldpos;
+ redraw();
+}
+
+void
+menu3hit(void)
+{
+ int i;
+
+ i = menuhit(3, mctl, &menu, nil);
+ switch(i){
+ case Mcrop:
+ crop();
+ break;
+ case Mundo:
+ undo();
+ break;
+ case Msave:
+ save();
+ break;
+ case Mexit:
+ threadexitsall(nil);
+ }
+}
+
+void
+usage(char *n)
+{
+ fprint(2, "usage: %s <[image]>\n", n);
+ exits("usage");
+}
+
+void
+threadmain(int argc, char *argv[])
+{
+ Mouse m;
+ Rune k;
+ Point o;
+ int fd;
+ Alt a[] = {
+ { nil, &m, CHANRCV },
+ { nil, nil, CHANRCV },
+ { nil, &k, CHANRCV },
+ { nil, nil, CHANEND },
+ };
+
+ if(argc > 2)
+ usage(argv[0]);
+ fd = 0;
+ if(argc==2){
+ fd = open(argv[1], OREAD);
+ if(fd<0)
+ sysfatal("open: %r");
+ }
+ if(initdraw(nil, nil, "vcrop")<0)
+ sysfatal("initdraw: %r");
+ display->locking = 0;
+ if((mctl = initmouse(nil, screen)) == nil)
+ sysfatal("initmouse: %r");
+ if((kctl = initkeyboard(nil)) == nil)
+ sysfatal("initkeyboard: %r");
+ a[Emouse].c = mctl->c;
+ a[Eresize].c = mctl->resizec;
+ a[Ekeyboard].c = kctl->c;
+ bg = allocimage(display, Rect(0,0,1,1), screen->chan, 1, 0xCCCCCCFF);
+ n = readimage(display, fd, 0);
+ if(n==nil)
+ sysfatal("readimage: %r");
+ close(fd);
+ p = nil;
+ pos = subpt(ZP, n->r.min);
+ oldpos = pos;
+ redraw();
+ for(;;){
+ switch(alt(a)){
+ case Emouse:
+ if(m.buttons==1){
+ for(;;) {
+ o = m.xy;
+ if(!readmouse(mctl))
+ break;
+ if((mctl->buttons & 1) == 0)
+ break;
+ translate(subpt(mctl->xy, o));
+ }
+ }else if(m.buttons==2){
+ mctl->buttons = 1;
+ crop();
+ }else if(m.buttons==4)
+ menu3hit();
+ break;
+ case Eresize:
+ if(getwindow(display, Refnone)<0)
+ sysfatal("cannot reattach: %r");
+ redraw();
+ break;
+ case Ekeyboard:
+ if(k==Kdel)
+ threadexitsall(nil);
+ break;
+ }
+ }
+}


Mon May 6 11:27:59 EDT 2024
diff bd1305a0b9841d65f95b4d81fa0d29067425833a uncommitted
--- a/sys/man/1/prof
+++ b/sys/man/1/prof
@@ -59,7 +59,7 @@
 .I symbol
 is the entry point of the call,
 .I time
-is in milliseconds,
+is in seconds,
 and
 .I ncall
 is the number of times that entry point was called at that
--- a/sys/src/cmd/file.c
+++ b/sys/src/cmd/file.c
@@ -918,6 +918,7 @@
	"MThd", "midi audio", 4, "audio/midi",
	"MUS\x1a", "mus audio", 4, "audio/mus",
	"Creative Voice File\x1a", "voc audio", 20, "audio/x-voc",
+ "pr\x0f", "Plan 9 profile data", 3, OCTET,
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\x00\x00\x00\xbb\x11\x22\x00\x44\xff\xff\xff\xff\xff\xff\xff\xff"
--- a/sys/src/cmd/prof.c
+++ b/sys/src/cmd/prof.c
@@ -13,8 +13,9 @@
	ushort right;
	ulong pc;
	ulong count;
- ulong time;
+ uvlong time;
 };
+enum { Datasz = 2+2+4+4+8 };

 struct Pc
 {
@@ -26,13 +27,13 @@
 {
	char *name;
	ulong pc;
- ulong ms;
+ uvlong ticks;
	ulong calls;
 };

 Data* data;
 Acc* acc;
-ulong ms;
+uvlong ticks;
 long nsym;
 long ndata;
 int dflag;
@@ -40,6 +41,7 @@
 Biobuf bout;
 int tabstop = 4;
 int verbose;
+double cyclefreq;

 void syms(char*);
 void datas(char*);
@@ -89,26 +91,16 @@
	exits(0);
 }

-void
-swapdata(Data *dp)
-{
- dp->down = beswab(dp->down);
- dp->right = beswab(dp->right);
- dp->pc = beswal(dp->pc);
- dp->count = beswal(dp->count);
- dp->time = beswal(dp->time);
-}
-
 int
 acmp(void *va, void *vb)
 {
	Acc *a, *b;
- ulong ua, ub;
+ double ua, ub;

	a = va;
	b = vb;
- ua = a->ms;
- ub = b->ms;
+ ua = a->ticks;
+ ub = b->ticks;

	if(ua > ub)
		return 1;
@@ -142,6 +134,11 @@
	close(fd);
 }

+#define GET2(p) (u16int)(p)[1] | (u16int)(p)[0]<<8
+#define GET4(p) (u32int)(p)[3] | (u32int)(p)[2]<<8 |
(u32int)(p)[1]<<16 | (u32int)(p)[0]<<24
+#define GET8(p) (u64int)(p)[7] | (u64int)(p)[6]<<8 |
(u64int)(p)[5]<<16 | (u64int)(p)[4]<<24 | \
+ (u64int)(p)[3]<<32 | (u64int)(p)[2]<<40 | (u64int)(p)[1]<<48 |
(u64int)(p)[0]<<56
+
 void
 datas(char *dout)
 {
@@ -148,6 +145,7 @@
	int fd;
	Dir *d;
	int i;
+ uchar hdr[3+1+1], *buf, *p;

	if((fd = open(dout, 0)) < 0){
		perror(dout);
@@ -158,20 +156,37 @@
		perror(dout);
		exits("stat");
	}
- ndata = d->length/sizeof(data[0]);
+ d->length -= sizeof hdr;
+ ndata = d->length/Datasz;
	data = malloc(ndata*sizeof(Data));
- if(data == 0){
- fprint(2, "prof: can't malloc data\n");
- exits("data malloc");
+ buf = malloc(d->length);
+ if(buf == 0 || data == 0){
+ fprint(2, "prof: can't malloc\n");
+ exits("malloc");
	}
- if(read(fd, data, d->length) != d->length){
+ if(read(fd, hdr, sizeof hdr) != sizeof hdr){
+ fprint(2, "prof: can't read data header\n");
+ exits("header read");
+ }
+ if(memcmp(hdr, "pr\x0f", 3) != 0){
+ fprint(2, "prof: bad magic\n");
+ exits("magic check");
+ }
+ cyclefreq = pow10(hdr[4]);
+ if(readn(fd, buf, d->length) != d->length){
		fprint(2, "prof: can't read data file\n");
		exits("data read");
	}
+ for(p = buf, i = 0; i < ndata; i++){
+ data[i].down = GET2(p); p += 2;
+ data[i].right = GET2(p); p += 2;
+ data[i].pc = GET4(p); p += 4;
+ data[i].count = GET4(p); p += 4;
+ data[i].time = GET8(p); p += 8;
+ }
+ free(buf);
	free(d);
	close(fd);
- for (i = 0; i < ndata; i++)
- swapdata(data+i);
 }

 char*
@@ -189,7 +204,8 @@
 void
 graph(int ind, ulong i, Pc *pc)
 {
- long time, count, prgm;
+ long count, prgm;
+ vlong time;
	Pc lpc;

	if(i >= ndata){
@@ -205,9 +221,9 @@
		graph(ind, data[i].right, pc);
	indent(ind);
	if(count == 1)
- Bprint(&bout, "%s:%lud\n", name(prgm), time);
+ Bprint(&bout, "%s:%.9f\n", name(prgm), time/cyclefreq);
	else
- Bprint(&bout, "%s:%lud/%lud\n", name(prgm), time, count);
+ Bprint(&bout, "%s:%.9f/%lud\n", name(prgm), time/cyclefreq, count);
	if(data[i].down == 0xFFFF)
		return;
	lpc.next = pc;
@@ -246,10 +262,11 @@
	return -1;
 }

-ulong
+uvlong
 sum(ulong i)
 {
- long j, dtime, time;
+ long j;
+ vlong dtime, time;
	int k;
	static indent;

@@ -264,7 +281,7 @@
	if (verbose){
		for(k = 0; k < indent; k++)
			print(" ");
- print("%lud: %ld/%lud", i, data[i].time, data[i].count);
+ print("%lud: %llud/%.9f/%lud", i, time, time/cyclefreq, data[i].count);
		if (j >= 0)
			print(" %s\n", acc[j].name);
		else
@@ -278,8 +295,8 @@
	}
	j = symind(data[i].pc);
	if (j >= 0) {
- acc[j].ms += time - dtime;
- ms += time - dtime;
+ acc[j].ticks += time - dtime;
+ ticks += time - dtime;
		acc[j].calls += data[i].count;
	}
	if(data[i].right == 0xFFFF)
@@ -300,18 +317,18 @@
		}
		acc[nsym].name = s.name;
		acc[nsym].pc = s.value;
- acc[nsym].calls = acc[nsym].ms = 0;
+ acc[nsym].calls = acc[nsym].ticks = 0;
	}
	sum(data[0].down);
	qsort(acc, nsym, sizeof(Acc), acmp);
- Bprint(&bout, " %% Time Calls Name\n");
- if(ms == 0)
- ms = 1;
+ Bprint(&bout, " %% Time Calls Name\n");
+ if(ticks == 0)
+ ticks = 1;
	while (--nsym >= 0) {
		if(acc[nsym].calls)
- Bprint(&bout, "%4.1f %8.3f %8lud\t%s\n",
- (100.0*acc[nsym].ms)/ms,
- acc[nsym].ms/1000.0,
+ Bprint(&bout, "%4.1f %.9f %8lud\t%s\n",
+ (100.0*acc[nsym].ticks)/ticks,
+ acc[nsym].ticks/cyclefreq,
				acc[nsym].calls,
				acc[nsym].name);
	}
--- a/sys/src/libc/port/profile.c
+++ b/sys/src/libc/port/profile.c
@@ -6,9 +6,8 @@
 extern uintptr _saveret(void);
 extern uintptr _savearg(void);

-static ulong khz;
 static ulong perr;
-static int havecycles;
+static int resolution;

 typedef struct Plink Plink;
 struct Plink
@@ -18,8 +17,7 @@
	Plink *link;
	long pc;
	long count;
- vlong time;
- uint rec;
+ vlong time;
 };

 #pragma profile off
@@ -45,11 +43,6 @@
	pp = _tos->prof.pp;
	if(pp == 0 || (_tos->prof.pid && _tos->pid != _tos->prof.pid))
		return _restore(arg, ret);
- if(pc == pp->pc){
- pp->rec++;
- p = pp;
- goto out;
- }
	for(p=pp->down; p; p=p->link)
		if(p->pc == pc)
			goto out;
@@ -119,10 +112,7 @@
		p->time = p->time + _tos->clock;
		break;
	}
- if(p->rec)
- p->rec--;
- else
- _tos->prof.pp = p->old;
+ _tos->prof.pp = p->old;
	return _restore(arg, ret);
 }

@@ -130,10 +120,12 @@
 _profdump(void)
 {
	int f;
- long n;
+ vlong n;
	Plink *p;
	char *vp;
	char filename[64];
+ double factor;
+ uchar hdr[3+1+1] = {'p', 'r', 0x0f, 0x2};

	if (_tos->prof.what == 0)
		return; /* No profiling */
@@ -168,8 +160,14 @@
		_tos->prof.first->time = _tos->clock;
		break;
	}
- vp = (char*)_tos->prof.first;
+ if(resolution)
+ factor = pow10(resolution) / _tos->cyclefreq;
+ else
+ factor = 1;
+ hdr[4] = resolution;
+ write(f, hdr, sizeof hdr);

+ vp = (char*)_tos->prof.first;
	for(p = _tos->prof.first; p <= _tos->prof.next; p++) {

		/*
@@ -214,16 +212,18 @@
		/*
		 * vlong time
		 */
- if (havecycles){
- n = (vlong)(p->time / (vlong)khz);
- }else
- n = p->time;
-
- vp[0] = n>>24;
- vp[1] = n>>16;
- vp[2] = n>>8;
- vp[3] = n;
- vp += 4;
+ n = p->time;
+ if(resolution)
+ n *= factor;
+ vp[0] = n>>56;
+ vp[1] = n>>48;
+ vp[2] = n>>40;
+ vp[3] = n>>32;
+ vp[4] = n>>24;
+ vp[5] = n>>16;
+ vp[6] = n>>8;
+ vp[7] = n;
+ vp += 8;
	}
	write(f, (char*)_tos->prof.first, vp - (char*)_tos->prof.first);
	close(f);
@@ -250,10 +250,11 @@
	int n, f;

	n = 256*1024;
- if (_tos->cyclefreq != 0LL){
- khz = _tos->cyclefreq / 1000; /* Report times in milliseconds */
- havecycles = 1;
- }
+ if(_tos->cyclefreq){
+ resolution = ceil(log10(_tos->cyclefreq));
+ resolution = resolution > 9 ? 9 : resolution;
+ } else
+ resolution = 0;
	f = open("/env/profsize", OREAD|OCEXEC);
	if(f >= 0) {
		memset(ename, 0, sizeof(ename));


Sun May 5 22:33:25 EDT 2024
diff bd1305a0b9841d65f95b4d81fa0d29067425833a uncommitted
--- a/sys/man/1/prof
+++ b/sys/man/1/prof
@@ -59,7 +59,7 @@
 .I symbol
 is the entry point of the call,
 .I time
-is in milliseconds,
+is in seconds,
 and
 .I ncall
 is the number of times that entry point was called at that
--- a/sys/src/cmd/file.c
+++ b/sys/src/cmd/file.c
@@ -918,6 +918,7 @@
	"MThd", "midi audio", 4, "audio/midi",
	"MUS\x1a", "mus audio", 4, "audio/mus",
	"Creative Voice File\x1a", "voc audio", 20, "audio/x-voc",
+ "pr\x0f", "Plan 9 profile data", 3, OCTET,
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\x00\x00\x00\xbb\x11\x22\x00\x44\xff\xff\xff\xff\xff\xff\xff\xff"
--- a/sys/src/cmd/prof.c
+++ b/sys/src/cmd/prof.c
@@ -13,8 +13,9 @@
	ushort right;
	ulong pc;
	ulong count;
- ulong time;
+ uvlong time;
 };
+enum { Datasz = 2+2+4+4+8 };

 struct Pc
 {
@@ -26,13 +27,13 @@
 {
	char *name;
	ulong pc;
- ulong ms;
+ uvlong ticks;
	ulong calls;
 };

 Data* data;
 Acc* acc;
-ulong ms;
+uvlong ticks;
 long nsym;
 long ndata;
 int dflag;
@@ -40,6 +41,7 @@
 Biobuf bout;
 int tabstop = 4;
 int verbose;
+double cyclefreq;

 void syms(char*);
 void datas(char*);
@@ -89,26 +91,16 @@
	exits(0);
 }

-void
-swapdata(Data *dp)
-{
- dp->down = beswab(dp->down);
- dp->right = beswab(dp->right);
- dp->pc = beswal(dp->pc);
- dp->count = beswal(dp->count);
- dp->time = beswal(dp->time);
-}
-
 int
 acmp(void *va, void *vb)
 {
	Acc *a, *b;
- ulong ua, ub;
+ double ua, ub;

	a = va;
	b = vb;
- ua = a->ms;
- ub = b->ms;
+ ua = a->ticks;
+ ub = b->ticks;

	if(ua > ub)
		return 1;
@@ -142,6 +134,11 @@
	close(fd);
 }

+#define GET2(p) (u16int)(p)[1] | (u16int)(p)[0]<<8
+#define GET4(p) (u32int)(p)[3] | (u32int)(p)[2]<<8 |
(u32int)(p)[1]<<16 | (u32int)(p)[0]<<24
+#define GET8(p) (u64int)(p)[7] | (u64int)(p)[6]<<8 |
(u64int)(p)[5]<<16 | (u64int)(p)[4]<<24 | \
+ (u64int)(p)[3]<<32 | (u64int)(p)[2]<<40 | (u64int)(p)[1]<<48 |
(u64int)(p)[0]<<56
+
 void
 datas(char *dout)
 {
@@ -148,6 +145,7 @@
	int fd;
	Dir *d;
	int i;
+ uchar hdr[3+1+1], *buf, *p;

	if((fd = open(dout, 0)) < 0){
		perror(dout);
@@ -158,20 +156,37 @@
		perror(dout);
		exits("stat");
	}
- ndata = d->length/sizeof(data[0]);
+ d->length -= sizeof hdr;
+ ndata = d->length/Datasz;
	data = malloc(ndata*sizeof(Data));
- if(data == 0){
- fprint(2, "prof: can't malloc data\n");
- exits("data malloc");
+ buf = malloc(d->length);
+ if(buf == 0 || data == 0){
+ fprint(2, "prof: can't malloc\n");
+ exits("malloc");
	}
- if(read(fd, data, d->length) != d->length){
+ if(read(fd, hdr, sizeof hdr) != sizeof hdr){
+ fprint(2, "prof: can't read data header\n");
+ exits("header read");
+ }
+ if(memcmp(hdr, "pr\x0f", 3) != 0){
+ fprint(2, "prof: bad magic\n");
+ exits("magic check");
+ }
+ cyclefreq = pow10(hdr[4]);
+ if(readn(fd, buf, d->length) != d->length){
		fprint(2, "prof: can't read data file\n");
		exits("data read");
	}
+ for(p = buf, i = 0; i < ndata; i++){
+ data[i].down = GET2(p); p += 2;
+ data[i].right = GET2(p); p += 2;
+ data[i].pc = GET4(p); p += 4;
+ data[i].count = GET4(p); p += 4;
+ data[i].time = GET8(p); p += 8;
+ }
+ free(buf);
	free(d);
	close(fd);
- for (i = 0; i < ndata; i++)
- swapdata(data+i);
 }

 char*
@@ -189,7 +204,8 @@
 void
 graph(int ind, ulong i, Pc *pc)
 {
- long time, count, prgm;
+ long count, prgm;
+ vlong time;
	Pc lpc;

	if(i >= ndata){
@@ -205,9 +221,9 @@
		graph(ind, data[i].right, pc);
	indent(ind);
	if(count == 1)
- Bprint(&bout, "%s:%lud\n", name(prgm), time);
+ Bprint(&bout, "%s:%.9f\n", name(prgm), time/cyclefreq);
	else
- Bprint(&bout, "%s:%lud/%lud\n", name(prgm), time, count);
+ Bprint(&bout, "%s:%.9f/%lud\n", name(prgm), time/cyclefreq, count);
	if(data[i].down == 0xFFFF)
		return;
	lpc.next = pc;
@@ -246,10 +262,11 @@
	return -1;
 }

-ulong
+uvlong
 sum(ulong i)
 {
- long j, dtime, time;
+ long j;
+ vlong dtime, time;
	int k;
	static indent;

@@ -264,7 +281,7 @@
	if (verbose){
		for(k = 0; k < indent; k++)
			print(" ");
- print("%lud: %ld/%lud", i, data[i].time, data[i].count);
+ print("%lud: %llud/%.9f/%lud", i, time, time/cyclefreq, data[i].count);
		if (j >= 0)
			print(" %s\n", acc[j].name);
		else
@@ -278,8 +295,8 @@
	}
	j = symind(data[i].pc);
	if (j >= 0) {
- acc[j].ms += time - dtime;
- ms += time - dtime;
+ acc[j].ticks += time - dtime;
+ ticks += time - dtime;
		acc[j].calls += data[i].count;
	}
	if(data[i].right == 0xFFFF)
@@ -300,18 +317,18 @@
		}
		acc[nsym].name = s.name;
		acc[nsym].pc = s.value;
- acc[nsym].calls = acc[nsym].ms = 0;
+ acc[nsym].calls = acc[nsym].ticks = 0;
	}
	sum(data[0].down);
	qsort(acc, nsym, sizeof(Acc), acmp);
- Bprint(&bout, " %% Time Calls Name\n");
- if(ms == 0)
- ms = 1;
+ Bprint(&bout, " %% Time Calls Name\n");
+ if(ticks == 0)
+ ticks = 1;
	while (--nsym >= 0) {
		if(acc[nsym].calls)
- Bprint(&bout, "%4.1f %8.3f %8lud\t%s\n",
- (100.0*acc[nsym].ms)/ms,
- acc[nsym].ms/1000.0,
+ Bprint(&bout, "%4.1f %.9f %8lud\t%s\n",
+ (100.0*acc[nsym].ticks)/ticks,
+ acc[nsym].ticks/cyclefreq,
				acc[nsym].calls,
				acc[nsym].name);
	}
--- a/sys/src/libc/port/profile.c
+++ b/sys/src/libc/port/profile.c
@@ -6,9 +6,8 @@
 extern uintptr _saveret(void);
 extern uintptr _savearg(void);

-static ulong khz;
 static ulong perr;
-static int havecycles;
+static int resolution;

 typedef struct Plink Plink;
 struct Plink
@@ -18,8 +17,7 @@
	Plink *link;
	long pc;
	long count;
- vlong time;
- uint rec;
+ vlong time;
 };

 #pragma profile off
@@ -45,11 +43,6 @@
	pp = _tos->prof.pp;
	if(pp == 0 || (_tos->prof.pid && _tos->pid != _tos->prof.pid))
		return _restore(arg, ret);
- if(pc == pp->pc){
- pp->rec++;
- p = pp;
- goto out;
- }
	for(p=pp->down; p; p=p->link)
		if(p->pc == pc)
			goto out;
@@ -119,10 +112,7 @@
		p->time = p->time + _tos->clock;
		break;
	}
- if(p->rec)
- p->rec--;
- else
- _tos->prof.pp = p->old;
+ _tos->prof.pp = p->old;
	return _restore(arg, ret);
 }

@@ -130,10 +120,12 @@
 _profdump(void)
 {
	int f;
- long n;
+ vlong n;
	Plink *p;
	char *vp;
	char filename[64];
+ double factor;
+ uchar hdr[3+1+1] = {'p', 'r', 0x0f, 0x2};

	if (_tos->prof.what == 0)
		return; /* No profiling */
@@ -168,8 +160,14 @@
		_tos->prof.first->time = _tos->clock;
		break;
	}
- vp = (char*)_tos->prof.first;
+ if(resolution)
+ factor = pow10(resolution) / _tos->cyclefreq;
+ else
+ factor = 1;
+ hdr[4] = resolution;
+ write(f, hdr, sizeof hdr);

+ vp = (char*)_tos->prof.first;
	for(p = _tos->prof.first; p <= _tos->prof.next; p++) {

		/*
@@ -214,16 +212,18 @@
		/*
		 * vlong time
		 */
- if (havecycles){
- n = (vlong)(p->time / (vlong)khz);
- }else
- n = p->time;
-
- vp[0] = n>>24;
- vp[1] = n>>16;
- vp[2] = n>>8;
- vp[3] = n;
- vp += 4;
+ n = p->time;
+ if(resolution)
+ n *= factor;
+ vp[0] = n>>56;
+ vp[1] = n>>48;
+ vp[2] = n>>40;
+ vp[3] = n>>32;
+ vp[4] = n>>24;
+ vp[5] = n>>16;
+ vp[6] = n>>8;
+ vp[7] = n;
+ vp += 8;
	}
	write(f, (char*)_tos->prof.first, vp - (char*)_tos->prof.first);
	close(f);
@@ -250,10 +250,10 @@
	int n, f;

	n = 256*1024;
- if (_tos->cyclefreq != 0LL){
- khz = _tos->cyclefreq / 1000; /* Report times in milliseconds */
- havecycles = 1;
- }
+ if(_tos->cyclefreq)
+ resolution = ceil(log10(_tos->cyclefreq));
+ else
+ resolution = 0;
	f = open("/env/profsize", OREAD|OCEXEC);
	if(f >= 0) {
		memset(ename, 0, sizeof(ename));


Sun May 5 22:31:41 EDT 2024
diff bd1305a0b9841d65f95b4d81fa0d29067425833a uncommitted
--- a/sys/man/1/prof
+++ b/sys/man/1/prof
@@ -59,7 +59,7 @@
 .I symbol
 is the entry point of the call,
 .I time
-is in milliseconds,
+is in seconds,
 and
 .I ncall
 is the number of times that entry point was called at that
--- a/sys/src/cmd/file.c
+++ b/sys/src/cmd/file.c
@@ -918,6 +918,7 @@
	"MThd", "midi audio", 4, "audio/midi",
	"MUS\x1a", "mus audio", 4, "audio/mus",
	"Creative Voice File\x1a", "voc audio", 20, "audio/x-voc",
+ "pr\x0f", "Plan 9 profile data", 3, OCTET,
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\x00\x00\x00\xbb\x11\x22\x00\x44\xff\xff\xff\xff\xff\xff\xff\xff"
--- a/sys/src/cmd/prof.c
+++ b/sys/src/cmd/prof.c
@@ -13,8 +13,9 @@
	ushort right;
	ulong pc;
	ulong count;
- ulong time;
+ uvlong time;
 };
+enum { Datasz = 2+2+4+4+8 };

 struct Pc
 {
@@ -26,13 +27,13 @@
 {
	char *name;
	ulong pc;
- ulong ms;
+ uvlong ticks;
	ulong calls;
 };

 Data* data;
 Acc* acc;
-ulong ms;
+uvlong ticks;
 long nsym;
 long ndata;
 int dflag;
@@ -40,6 +41,7 @@
 Biobuf bout;
 int tabstop = 4;
 int verbose;
+double cyclefreq;

 void syms(char*);
 void datas(char*);
@@ -89,26 +91,16 @@
	exits(0);
 }

-void
-swapdata(Data *dp)
-{
- dp->down = beswab(dp->down);
- dp->right = beswab(dp->right);
- dp->pc = beswal(dp->pc);
- dp->count = beswal(dp->count);
- dp->time = beswal(dp->time);
-}
-
 int
 acmp(void *va, void *vb)
 {
	Acc *a, *b;
- ulong ua, ub;
+ double ua, ub;

	a = va;
	b = vb;
- ua = a->ms;
- ub = b->ms;
+ ua = a->ticks;
+ ub = b->ticks;

	if(ua > ub)
		return 1;
@@ -142,6 +134,11 @@
	close(fd);
 }

+#define GET2(p) (u16int)(p)[1] | (u16int)(p)[0]<<8
+#define GET4(p) (u32int)(p)[3] | (u32int)(p)[2]<<8 |
(u32int)(p)[1]<<16 | (u32int)(p)[0]<<24
+#define GET8(p) (u64int)(p)[7] | (u64int)(p)[6]<<8 |
(u64int)(p)[5]<<16 | (u64int)(p)[4]<<24 | \
+ (u64int)(p)[3]<<32 | (u64int)(p)[2]<<40 | (u64int)(p)[1]<<48 |
(u64int)(p)[0]<<56
+
 void
 datas(char *dout)
 {
@@ -148,6 +145,7 @@
	int fd;
	Dir *d;
	int i;
+ uchar hdr[3+1+1], *buf, *p;

	if((fd = open(dout, 0)) < 0){
		perror(dout);
@@ -158,20 +156,37 @@
		perror(dout);
		exits("stat");
	}
- ndata = d->length/sizeof(data[0]);
+ d->length -= sizeof hdr;
+ ndata = d->length/Datasz;
	data = malloc(ndata*sizeof(Data));
- if(data == 0){
- fprint(2, "prof: can't malloc data\n");
- exits("data malloc");
+ buf = malloc(d->length);
+ if(buf == 0 || data == 0){
+ fprint(2, "prof: can't malloc\n");
+ exits("malloc");
	}
- if(read(fd, data, d->length) != d->length){
+ if(read(fd, hdr, sizeof hdr) != sizeof hdr){
+ fprint(2, "prof: can't read data header\n");
+ exits("header read");
+ }
+ if(memcmp(hdr, "pr\x0f", 3) != 0){
+ fprint(2, "prof: bad magic\n");
+ exits("magic check");
+ }
+ cyclefreq = pow10(hdr[4]);
+ if(readn(fd, buf, d->length) != d->length){
		fprint(2, "prof: can't read data file\n");
		exits("data read");
	}
+ for(p = buf, i = 0; i < ndata; i++){
+ data[i].down = GET2(p); p += 2;
+ data[i].right = GET2(p); p += 2;
+ data[i].pc = GET4(p); p += 4;
+ data[i].count = GET4(p); p += 4;
+ data[i].time = GET8(p); p += 8;
+ }
+ free(buf);
	free(d);
	close(fd);
- for (i = 0; i < ndata; i++)
- swapdata(data+i);
 }

 char*
@@ -189,7 +204,8 @@
 void
 graph(int ind, ulong i, Pc *pc)
 {
- long time, count, prgm;
+ long count, prgm;
+ vlong time;
	Pc lpc;

	if(i >= ndata){
@@ -205,9 +221,9 @@
		graph(ind, data[i].right, pc);
	indent(ind);
	if(count == 1)
- Bprint(&bout, "%s:%lud\n", name(prgm), time);
+ Bprint(&bout, "%s:%.9f\n", name(prgm), time/cyclefreq);
	else
- Bprint(&bout, "%s:%lud/%lud\n", name(prgm), time, count);
+ Bprint(&bout, "%s:%.9f/%lud\n", name(prgm), time/cyclefreq, count);
	if(data[i].down == 0xFFFF)
		return;
	lpc.next = pc;
@@ -246,10 +262,11 @@
	return -1;
 }

-ulong
+uvlong
 sum(ulong i)
 {
- long j, dtime, time;
+ long j;
+ vlong dtime, time;
	int k;
	static indent;

@@ -264,7 +281,7 @@
	if (verbose){
		for(k = 0; k < indent; k++)
			print(" ");
- print("%lud: %ld/%lud", i, data[i].time, data[i].count);
+ print("%lud: %llud/%.9f/%lud", i, time, time/cyclefreq, data[i].count);
		if (j >= 0)
			print(" %s\n", acc[j].name);
		else
@@ -278,8 +295,8 @@
	}
	j = symind(data[i].pc);
	if (j >= 0) {
- acc[j].ms += time - dtime;
- ms += time - dtime;
+ acc[j].ticks += (time - dtime);
+ ticks += (time - dtime);
		acc[j].calls += data[i].count;
	}
	if(data[i].right == 0xFFFF)
@@ -300,18 +317,18 @@
		}
		acc[nsym].name = s.name;
		acc[nsym].pc = s.value;
- acc[nsym].calls = acc[nsym].ms = 0;
+ acc[nsym].calls = acc[nsym].ticks = 0;
	}
	sum(data[0].down);
	qsort(acc, nsym, sizeof(Acc), acmp);
- Bprint(&bout, " %% Time Calls Name\n");
- if(ms == 0)
- ms = 1;
+ Bprint(&bout, " %% Time Calls Name\n");
+ if(ticks == 0)
+ ticks = 1;
	while (--nsym >= 0) {
		if(acc[nsym].calls)
- Bprint(&bout, "%4.1f %8.3f %8lud\t%s\n",
- (100.0*acc[nsym].ms)/ms,
- acc[nsym].ms/1000.0,
+ Bprint(&bout, "%4.1f %.9f %8lud\t%s\n",
+ (100.0*acc[nsym].ticks)/ticks,
+ acc[nsym].ticks/cyclefreq,
				acc[nsym].calls,
				acc[nsym].name);
	}
--- a/sys/src/libc/port/profile.c
+++ b/sys/src/libc/port/profile.c
@@ -6,9 +6,8 @@
 extern uintptr _saveret(void);
 extern uintptr _savearg(void);

-static ulong khz;
 static ulong perr;
-static int havecycles;
+static int resolution;

 typedef struct Plink Plink;
 struct Plink
@@ -18,8 +17,7 @@
	Plink *link;
	long pc;
	long count;
- vlong time;
- uint rec;
+ vlong time;
 };

 #pragma profile off
@@ -45,11 +43,6 @@
	pp = _tos->prof.pp;
	if(pp == 0 || (_tos->prof.pid && _tos->pid != _tos->prof.pid))
		return _restore(arg, ret);
- if(pc == pp->pc){
- pp->rec++;
- p = pp;
- goto out;
- }
	for(p=pp->down; p; p=p->link)
		if(p->pc == pc)
			goto out;
@@ -119,10 +112,7 @@
		p->time = p->time + _tos->clock;
		break;
	}
- if(p->rec)
- p->rec--;
- else
- _tos->prof.pp = p->old;
+ _tos->prof.pp = p->old;
	return _restore(arg, ret);
 }

@@ -130,10 +120,12 @@
 _profdump(void)
 {
	int f;
- long n;
+ vlong n;
	Plink *p;
	char *vp;
	char filename[64];
+ double factor;
+ uchar hdr[3+1+1] = {'p', 'r', 0x0f, 0x2};

	if (_tos->prof.what == 0)
		return; /* No profiling */
@@ -168,8 +160,14 @@
		_tos->prof.first->time = _tos->clock;
		break;
	}
- vp = (char*)_tos->prof.first;
+ if(resolution)
+ factor = pow10(resolution) / _tos->cyclefreq;
+ else
+ factor = 1;
+ hdr[4] = resolution;
+ write(f, hdr, sizeof hdr);

+ vp = (char*)_tos->prof.first;
	for(p = _tos->prof.first; p <= _tos->prof.next; p++) {

		/*
@@ -214,16 +212,18 @@
		/*
		 * vlong time
		 */
- if (havecycles){
- n = (vlong)(p->time / (vlong)khz);
- }else
- n = p->time;
-
- vp[0] = n>>24;
- vp[1] = n>>16;
- vp[2] = n>>8;
- vp[3] = n;
- vp += 4;
+ n = p->time;
+ if(resolution)
+ n *= factor;
+ vp[0] = n>>56;
+ vp[1] = n>>48;
+ vp[2] = n>>40;
+ vp[3] = n>>32;
+ vp[4] = n>>24;
+ vp[5] = n>>16;
+ vp[6] = n>>8;
+ vp[7] = n;
+ vp += 8;
	}
	write(f, (char*)_tos->prof.first, vp - (char*)_tos->prof.first);
	close(f);
@@ -250,10 +250,10 @@
	int n, f;

	n = 256*1024;
- if (_tos->cyclefreq != 0LL){
- khz = _tos->cyclefreq / 1000; /* Report times in milliseconds */
- havecycles = 1;
- }
+ if(_tos->cyclefreq)
+ resolution = ceil(log10(_tos->cyclefreq));
+ else
+ resolution = 0;
	f = open("/env/profsize", OREAD|OCEXEC);
	if(f >= 0) {
		memset(ename, 0, sizeof(ename));


Sun May 5 19:58:29 EDT 2024
diff bd1305a0b9841d65f95b4d81fa0d29067425833a uncommitted
--- a/sys/man/1/prof
+++ b/sys/man/1/prof
@@ -59,7 +59,7 @@
 .I symbol
 is the entry point of the call,
 .I time
-is in milliseconds,
+is in seconds,
 and
 .I ncall
 is the number of times that entry point was called at that
--- a/sys/src/cmd/file.c
+++ b/sys/src/cmd/file.c
@@ -918,6 +918,7 @@
	"MThd", "midi audio", 4, "audio/midi",
	"MUS\x1a", "mus audio", 4, "audio/mus",
	"Creative Voice File\x1a", "voc audio", 20, "audio/x-voc",
+ "pr\x0f", "Plan 9 profile data", 3, OCTET,
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff"
	"\x00\x00\x00\xbb\x11\x22\x00\x44\xff\xff\xff\xff\xff\xff\xff\xff"
--- a/sys/src/cmd/prof.c
+++ b/sys/src/cmd/prof.c
@@ -13,8 +13,9 @@
	ushort right;
	ulong pc;
	ulong count;
- ulong time;
+ uvlong time;
 };
+enum { Datasz = 2+2+4+4+8 };

 struct Pc
 {
@@ -26,13 +27,13 @@
 {
	char *name;
	ulong pc;
- ulong ms;
+ double sec;
	ulong calls;
 };

 Data* data;
 Acc* acc;
-ulong ms;
+double sec;
 long nsym;
 long ndata;
 int dflag;
@@ -40,6 +41,7 @@
 Biobuf bout;
 int tabstop = 4;
 int verbose;
+double cyclefreq;

 void syms(char*);
 void datas(char*);
@@ -89,26 +91,16 @@
	exits(0);
 }

-void
-swapdata(Data *dp)
-{
- dp->down = beswab(dp->down);
- dp->right = beswab(dp->right);
- dp->pc = beswal(dp->pc);
- dp->count = beswal(dp->count);
- dp->time = beswal(dp->time);
-}
-
 int
 acmp(void *va, void *vb)
 {
	Acc *a, *b;
- ulong ua, ub;
+ double ua, ub;

	a = va;
	b = vb;
- ua = a->ms;
- ub = b->ms;
+ ua = a->sec;
+ ub = b->sec;

	if(ua > ub)
		return 1;
@@ -142,6 +134,11 @@
	close(fd);
 }

+#define GET2(p) (u16int)(p)[1] | (u16int)(p)[0]<<8
+#define GET4(p) (u32int)(p)[3] | (u32int)(p)[2]<<8 |
(u32int)(p)[1]<<16 | (u32int)(p)[0]<<24
+#define GET8(p) (u64int)(p)[7] | (u64int)(p)[6]<<8 |
(u64int)(p)[5]<<16 | (u64int)(p)[4]<<24 | \
+ (u64int)(p)[3]<<32 | (u64int)(p)[2]<<40 | (u64int)(p)[1]<<48 |
(u64int)(p)[0]<<56
+
 void
 datas(char *dout)
 {
@@ -148,6 +145,8 @@
	int fd;
	Dir *d;
	int i;
+ uchar hdr[4+8], *buf, *p;
+ uvlong freq;

	if((fd = open(dout, 0)) < 0){
		perror(dout);
@@ -158,20 +157,40 @@
		perror(dout);
		exits("stat");
	}
- ndata = d->length/sizeof(data[0]);
+ d->length -= sizeof hdr;
+ ndata = d->length/Datasz;
	data = malloc(ndata*sizeof(Data));
- if(data == 0){
- fprint(2, "prof: can't malloc data\n");
- exits("data malloc");
+ buf = malloc(d->length);
+ if(buf == 0 || data == 0){
+ fprint(2, "prof: can't malloc\n");
+ exits("malloc");
	}
- if(read(fd, data, d->length) != d->length){
+ if(read(fd, hdr, sizeof hdr) != sizeof hdr){
+ fprint(2, "prof: can't read data header\n");
+ exits("header read");
+ }
+ if(memcmp(hdr, "pr\x0f", 3) != 0){
+ fprint(2, "prof: bad magic\n");
+ exits("magic check");
+ }
+ freq = GET8(hdr+4);
+ if(freq == 0)
+ freq = 1000;
+ cyclefreq = (double)freq;
+ if(readn(fd, buf, d->length) != d->length){
		fprint(2, "prof: can't read data file\n");
		exits("data read");
	}
+ for(p = buf, i = 0; i < ndata; i++){
+ data[i].down = GET2(p); p += 2;
+ data[i].right = GET2(p); p += 2;
+ data[i].pc = GET4(p); p += 4;
+ data[i].count = GET4(p); p += 4;
+ data[i].time = GET8(p); p += 8;
+ }
+ free(buf);
	free(d);
	close(fd);
- for (i = 0; i < ndata; i++)
- swapdata(data+i);
 }

 char*
@@ -189,7 +208,8 @@
 void
 graph(int ind, ulong i, Pc *pc)
 {
- long time, count, prgm;
+ long count, prgm;
+ vlong time;
	Pc lpc;

	if(i >= ndata){
@@ -205,9 +225,9 @@
		graph(ind, data[i].right, pc);
	indent(ind);
	if(count == 1)
- Bprint(&bout, "%s:%lud\n", name(prgm), time);
+ Bprint(&bout, "%s:%.9f\n", name(prgm), time/cyclefreq);
	else
- Bprint(&bout, "%s:%lud/%lud\n", name(prgm), time, count);
+ Bprint(&bout, "%s:%.9f/%lud\n", name(prgm), time/cyclefreq, count);
	if(data[i].down == 0xFFFF)
		return;
	lpc.next = pc;
@@ -246,10 +266,11 @@
	return -1;
 }

-ulong
+uvlong
 sum(ulong i)
 {
- long j, dtime, time;
+ long j;
+ vlong dtime, time;
	int k;
	static indent;

@@ -264,7 +285,7 @@
	if (verbose){
		for(k = 0; k < indent; k++)
			print(" ");
- print("%lud: %ld/%lud", i, data[i].time, data[i].count);
+ print("%lud: %llud/%.9f/%lud", i, time, time/cyclefreq, data[i].count);
		if (j >= 0)
			print(" %s\n", acc[j].name);
		else
@@ -278,8 +299,8 @@
	}
	j = symind(data[i].pc);
	if (j >= 0) {
- acc[j].ms += time - dtime;
- ms += time - dtime;
+ acc[j].sec += (time - dtime)/cyclefreq;
+ sec += (time - dtime)/cyclefreq;
		acc[j].calls += data[i].count;
	}
	if(data[i].right == 0xFFFF)
@@ -300,18 +321,18 @@
		}
		acc[nsym].name = s.name;
		acc[nsym].pc = s.value;
- acc[nsym].calls = acc[nsym].ms = 0;
+ acc[nsym].calls = acc[nsym].sec = 0;
	}
	sum(data[0].down);
	qsort(acc, nsym, sizeof(Acc), acmp);
	Bprint(&bout, " %% Time Calls Name\n");
- if(ms == 0)
- ms = 1;
+ if(sec == 0)
+ sec = 1;
	while (--nsym >= 0) {
		if(acc[nsym].calls)
			Bprint(&bout, "%4.1f %8.3f %8lud\t%s\n",
- (100.0*acc[nsym].ms)/ms,
- acc[nsym].ms/1000.0,
+ (100.0*acc[nsym].sec)/sec,
+ acc[nsym].sec,
				acc[nsym].calls,
				acc[nsym].name);
	}
--- a/sys/src/libc/port/profile.c
+++ b/sys/src/libc/port/profile.c
@@ -6,9 +6,7 @@
 extern uintptr _saveret(void);
 extern uintptr _savearg(void);

-static ulong khz;
 static ulong perr;
-static int havecycles;

 typedef struct Plink Plink;
 struct Plink
@@ -18,8 +16,7 @@
	Plink *link;
	long pc;
	long count;
- vlong time;
- uint rec;
+ vlong time;
 };

 #pragma profile off
@@ -45,11 +42,6 @@
	pp = _tos->prof.pp;
	if(pp == 0 || (_tos->prof.pid && _tos->pid != _tos->prof.pid))
		return _restore(arg, ret);
- if(pc == pp->pc){
- pp->rec++;
- p = pp;
- goto out;
- }
	for(p=pp->down; p; p=p->link)
		if(p->pc == pc)
			goto out;
@@ -119,10 +111,7 @@
		p->time = p->time + _tos->clock;
		break;
	}
- if(p->rec)
- p->rec--;
- else
- _tos->prof.pp = p->old;
+ _tos->prof.pp = p->old;
	return _restore(arg, ret);
 }

@@ -130,10 +119,11 @@
 _profdump(void)
 {
	int f;
- long n;
+ vlong n;
	Plink *p;
	char *vp;
	char filename[64];
+ uchar hdr[4+8] = {'p', 'r', 0x0f, 0x2};

	if (_tos->prof.what == 0)
		return; /* No profiling */
@@ -168,8 +158,17 @@
		_tos->prof.first->time = _tos->clock;
		break;
	}
- vp = (char*)_tos->prof.first;
+ hdr[4+0] = _tos->cyclefreq>>56;
+ hdr[4+1] = _tos->cyclefreq>>48;
+ hdr[4+2] = _tos->cyclefreq>>40;
+ hdr[4+3] = _tos->cyclefreq>>32;
+ hdr[4+4] = _tos->cyclefreq>>24;
+ hdr[4+5] = _tos->cyclefreq>>16;
+ hdr[4+6] = _tos->cyclefreq>>8;
+ hdr[4+7] = _tos->cyclefreq;
+ write(f, hdr, sizeof hdr);

+ vp = (char*)_tos->prof.first;
	for(p = _tos->prof.first; p <= _tos->prof.next; p++) {

		/*
@@ -214,16 +213,16 @@
		/*
		 * vlong time
		 */
- if (havecycles){
- n = (vlong)(p->time / (vlong)khz);
- }else
- n = p->time;
-
- vp[0] = n>>24;
- vp[1] = n>>16;
- vp[2] = n>>8;
- vp[3] = n;
- vp += 4;
+ n = p->time;
+ vp[0] = n>>56;
+ vp[1] = n>>48;
+ vp[2] = n>>40;
+ vp[3] = n>>32;
+ vp[4] = n>>24;
+ vp[5] = n>>16;
+ vp[6] = n>>8;
+ vp[7] = n;
+ vp += 8;
	}
	write(f, (char*)_tos->prof.first, vp - (char*)_tos->prof.first);
	close(f);
@@ -250,10 +249,6 @@
	int n, f;

	n = 256*1024;
- if (_tos->cyclefreq != 0LL){
- khz = _tos->cyclefreq / 1000; /* Report times in milliseconds */
- havecycles = 1;
- }
	f = open("/env/profsize", OREAD|OCEXEC);
	if(f >= 0) {
		memset(ename, 0, sizeof(ename));


Sun May 5 19:24:11 EDT 2024
cpu% 6l -p -o 6.sort sort.6
cpu% 6.sort /lib/ucd/UnicodeData.txt > /dev/null
cpu% prof 6.sort prof.14373784
  % Time Calls Name
20.4 0.011 69849 poolallocl
13.0 0.007 70432 trim
 9.3 0.005 34925 newline
 5.6 0.003 34924 realloc
 5.6 0.003 34925 malloc
 3.7 0.002 34924 buildkey
 3.7 0.002 70432 blocksetdsize
 3.7 0.002 69849 plock
 3.7 0.002 69849 punlock
 3.7 0.002 72731 pooladd
 3.7 0.002 2052 rsort4
 3.7 0.002 72273 pooldel
 1.9 0.001 34924 Bwrite
 1.9 0.001 34984 memchr
 1.9 0.001 34925 Brdline
 1.9 0.001 34924 poolrealloc
 1.9 0.001 34924 dokey_
 1.9 0.001 1 main
 1.9 0.001 1 printout
 1.9 0.001 34924 lineout
 1.9 0.001 34925 emalloc
 1.9 0.001 34924 poolreallocl
 1.9 0.001 34925 poolalloc
 0.0 0.000 69849 B2D
 0.0 0.000 1 doargs
 0.0 0.000 12 memcmp
 0.0 0.000 1 sort4
 0.0 0.000 34925 memset
 0.0 0.000 398 bsort4
 0.0 0.000 1 done
 0.0 0.000 34924 erealloc
 0.0 0.000 1 dofile
 0.0 0.000 104891 memmove
 0.0 0.000 1212 blockmerge
 0.0 0.000 3591 arenasetsize
 0.0 0.000 1796 poolnewarena
 0.0 0.000 1749 getdsize
 0.0 0.000 1795 blockgrow
 0.0 0.000 1795 arenamerge
 0.0 0.000 17999 blockcheck
 0.0 0.000 144833 blocksetsize
 0.0 0.000 1796 bsize2asize
 0.0 0.000 215892 treesplay
 0.0 0.000 211879 dsize2bsize
 0.0 0.000 71645 treelookupgt
 0.0 0.000 69849 setmalloctag
 0.0 0.000 69849 setrealloctag
 0.0 0.000 69850 lock
 0.0 0.000 69850 unlock
 0.0 0.000 1 onexit
 0.0 0.000 1 atexit
 0.0 0.000 1796 sbrk
 0.0 0.000 60 read
 0.0 0.000 2 getpid
 0.0 0.000 59 write
 0.0 0.000 60 bioread
 0.0 0.000 3 deinstall
 0.0 0.000 34925 Blinelen
 0.0 0.000 1 batexit
 0.0 0.000 1 install
 0.0 0.000 59 biowrite
 0.0 0.000 2 Bterm
 0.0 0.000 2 Binit
 0.0 0.000 2 Binits
 0.0 0.000 1796 sbrkalloc
 0.0 0.000 1795 sbrkmerge
 0.0 0.000 2 Bflush
 0.0 0.000 1 strcmp


Sun May 5 19:06:53 EDT 2024
  % Time Calls Name
11.4 0.010 69849 poolallocl
 8.9 0.008 70432 trim
 4.7 0.004 2052 rsort4
 4.4 0.004 34925 newline
 4.3 0.004 72273 pooldel
 4.1 0.004 215892 treesplay
 3.9 0.003 104891 memmove
 3.5 0.003 211879 dsize2bsize
 3.1 0.003 70432 blocksetdsize
 2.9 0.003 34924 realloc
 2.9 0.003 72731 pooladd
 2.8 0.002 34984 memchr
 2.8 0.002 34924 poolrealloc
 2.7 0.002 34925 malloc
 2.6 0.002 34925 poolalloc
 2.6 0.002 144833 blocksetsize
 2.5 0.002 69849 punlock
 2.2 0.002 69849 plock
 2.2 0.002 34924 buildkey
 2.1 0.002 69850 lock
 2.0 0.002 34925 emalloc
 1.5 0.001 34925 memset
 1.5 0.001 71645 treelookupgt
 1.4 0.001 34924 Bwrite
 1.4 0.001 34925 Brdline
 1.3 0.001 34924 lineout
 1.2 0.001 34924 dokey_
 1.2 0.001 34924 erealloc
 1.2 0.001 34924 poolreallocl
 1.1 0.001 69849 B2D
 1.1 0.001 69849 setmalloctag
 1.1 0.001 69849 setrealloctag
 1.0 0.001 69850 unlock
 0.9 0.001 1 onexit
 0.8 0.001 1 dofile
 0.8 0.001 1 printout
 0.7 0.001 3591 arenasetsize
 0.5 0.000 34925 Blinelen
 0.5 0.000 1796 poolnewarena
 0.4 0.000 17999 blockcheck
 0.4 0.000 1795 arenamerge
 0.3 0.000 1795 blockgrow
 0.2 0.000 1796 sbrk
 0.1 0.000 398 bsort4
 0.1 0.000 1796 sbrkalloc
 0.1 0.000 60 read
 0.1 0.000 1212 blockmerge
 0.0 0.000 1 main
 0.0 0.000 1795 sbrkmerge
 0.0 0.000 1749 getdsize
 0.0 0.000 1796 bsize2asize
 0.0 0.000 59 write
 0.0 0.000 60 bioread
 0.0 0.000 59 biowrite
 0.0 0.000 1 doargs
 0.0 0.000 1 done
 0.0 0.000 12 memcmp
 0.0 0.000 1 atexit
 0.0 0.000 2 Bterm
 0.0 0.000 3 deinstall
 0.0 0.000 2 Binit
 0.0 0.000 2 Binits
 0.0 0.000 1 install
 0.0 0.000 2 Bflush
 0.0 0.000 1 sort4
 0.0 0.000 1 batexit
 0.0 0.000 1 strcmp
 0.0 0.000 2 getpid


Sun May 5 19:06:16 EDT 2024
diff bd1305a0b9841d65f95b4d81fa0d29067425833a uncommitted
--- a/sys/man/1/prof
+++ b/sys/man/1/prof
@@ -59,7 +59,7 @@
 .I symbol
 is the entry point of the call,
 .I time
-is in milliseconds,
+is in seconds,
 and
 .I ncall
 is the number of times that entry point was called at that
--- a/sys/src/cmd/prof.c
+++ b/sys/src/cmd/prof.c
@@ -13,8 +13,9 @@
	ushort right;
	ulong pc;
	ulong count;
- ulong time;
+ uvlong time;
 };
+enum { Datasz = 2+2+4+4+8 };

 struct Pc
 {
@@ -26,13 +27,13 @@
 {
	char *name;
	ulong pc;
- ulong ms;
+ double sec;
	ulong calls;
 };

 Data* data;
 Acc* acc;
-ulong ms;
+double sec;
 long nsym;
 long ndata;
 int dflag;
@@ -40,6 +41,7 @@
 Biobuf bout;
 int tabstop = 4;
 int verbose;
+double cyclefreq;

 void syms(char*);
 void datas(char*);
@@ -89,26 +91,16 @@
	exits(0);
 }

-void
-swapdata(Data *dp)
-{
- dp->down = beswab(dp->down);
- dp->right = beswab(dp->right);
- dp->pc = beswal(dp->pc);
- dp->count = beswal(dp->count);
- dp->time = beswal(dp->time);
-}
-
 int
 acmp(void *va, void *vb)
 {
	Acc *a, *b;
- ulong ua, ub;
+ double ua, ub;

	a = va;
	b = vb;
- ua = a->ms;
- ub = b->ms;
+ ua = a->sec;
+ ub = b->sec;

	if(ua > ub)
		return 1;
@@ -142,6 +134,11 @@
	close(fd);
 }

+#define GET2(p) (u16int)(p)[1] | (u16int)(p)[0]<<8
+#define GET4(p) (u32int)(p)[3] | (u32int)(p)[2]<<8 |
(u32int)(p)[1]<<16 | (u32int)(p)[0]<<24
+#define GET8(p) (u64int)(p)[7] | (u64int)(p)[6]<<8 |
(u64int)(p)[5]<<16 | (u64int)(p)[4]<<24 | \
+ (u64int)(p)[3]<<32 | (u64int)(p)[2]<<40 | (u64int)(p)[1]<<48 |
(u64int)(p)[0]<<56
+
 void
 datas(char *dout)
 {
@@ -148,6 +145,8 @@
	int fd;
	Dir *d;
	int i;
+ uchar hdr[4+8], *buf, *p;
+ uvlong freq;

	if((fd = open(dout, 0)) < 0){
		perror(dout);
@@ -158,20 +157,42 @@
		perror(dout);
		exits("stat");
	}
- ndata = d->length/sizeof(data[0]);
+ d->length -= sizeof hdr;
+ ndata = d->length/Datasz;
	data = malloc(ndata*sizeof(Data));
- if(data == 0){
- fprint(2, "prof: can't malloc data\n");
- exits("data malloc");
+ buf = malloc(d->length);
+ if(buf == 0 || data == 0){
+ fprint(2, "prof: can't malloc\n");
+ exits("malloc");
	}
- if(read(fd, data, d->length) != d->length){
+ if(read(fd, hdr, sizeof hdr) != sizeof hdr){
+ fprint(2, "prof: can't read data header\n");
+ exits("header read");
+ }
+ if(memcmp(hdr, "pr\x0f", 3) != 0){
+ fprint(2, "prof: bad magic\n");
+ exits("magic check");
+ }
+ freq = GET8(hdr+4);
+ if(freq == 0)
+ freq = 1000;
+ cyclefreq = (double)freq;
+ if(verbose)
+ print("cyclefreq: %llud %.9f\n", freq, cyclefreq);
+ if(readn(fd, buf, d->length) != d->length){
		fprint(2, "prof: can't read data file\n");
		exits("data read");
	}
+ for(p = buf, i = 0; i < ndata; i++){
+ data[i].down = GET2(p); p += 2;
+ data[i].right = GET2(p); p += 2;
+ data[i].pc = GET4(p); p += 4;
+ data[i].count = GET4(p); p += 4;
+ data[i].time = GET8(p); p += 8;
+ }
+ free(buf);
	free(d);
	close(fd);
- for (i = 0; i < ndata; i++)
- swapdata(data+i);
 }

 char*
@@ -189,7 +210,8 @@
 void
 graph(int ind, ulong i, Pc *pc)
 {
- long time, count, prgm;
+ long count, prgm;
+ vlong time;
	Pc lpc;

	if(i >= ndata){
@@ -205,9 +227,9 @@
		graph(ind, data[i].right, pc);
	indent(ind);
	if(count == 1)
- Bprint(&bout, "%s:%lud\n", name(prgm), time);
+ Bprint(&bout, "%s:%.9f\n", name(prgm), time/cyclefreq);
	else
- Bprint(&bout, "%s:%lud/%lud\n", name(prgm), time, count);
+ Bprint(&bout, "%s:%.9f/%lud\n", name(prgm), time/cyclefreq, count);
	if(data[i].down == 0xFFFF)
		return;
	lpc.next = pc;
@@ -246,10 +268,11 @@
	return -1;
 }

-ulong
+uvlong
 sum(ulong i)
 {
- long j, dtime, time;
+ long j;
+ vlong dtime, time;
	int k;
	static indent;

@@ -264,7 +287,7 @@
	if (verbose){
		for(k = 0; k < indent; k++)
			print(" ");
- print("%lud: %ld/%lud", i, data[i].time, data[i].count);
+ print("%lud: %llud/%.9f/%lud", i, time, time/cyclefreq, data[i].count);
		if (j >= 0)
			print(" %s\n", acc[j].name);
		else
@@ -278,8 +301,8 @@
	}
	j = symind(data[i].pc);
	if (j >= 0) {
- acc[j].ms += time - dtime;
- ms += time - dtime;
+ acc[j].sec += (time - dtime)/cyclefreq;
+ sec += (time - dtime)/cyclefreq;
		acc[j].calls += data[i].count;
	}
	if(data[i].right == 0xFFFF)
@@ -300,18 +323,18 @@
		}
		acc[nsym].name = s.name;
		acc[nsym].pc = s.value;
- acc[nsym].calls = acc[nsym].ms = 0;
+ acc[nsym].calls = acc[nsym].sec = 0;
	}
	sum(data[0].down);
	qsort(acc, nsym, sizeof(Acc), acmp);
	Bprint(&bout, " %% Time Calls Name\n");
- if(ms == 0)
- ms = 1;
+ if(sec == 0)
+ sec = 1;
	while (--nsym >= 0) {
		if(acc[nsym].calls)
			Bprint(&bout, "%4.1f %8.3f %8lud\t%s\n",
- (100.0*acc[nsym].ms)/ms,
- acc[nsym].ms/1000.0,
+ (100.0*acc[nsym].sec)/sec,
+ acc[nsym].sec,
				acc[nsym].calls,
				acc[nsym].name);
	}
--- a/sys/src/libc/port/profile.c
+++ b/sys/src/libc/port/profile.c
@@ -6,9 +6,7 @@
 extern uintptr _saveret(void);
 extern uintptr _savearg(void);

-static ulong khz;
 static ulong perr;
-static int havecycles;

 typedef struct Plink Plink;
 struct Plink
@@ -19,7 +17,6 @@
	long pc;
	long count;
	vlong time;
- uint rec;
 };

 #pragma profile off
@@ -45,11 +42,6 @@
	pp = _tos->prof.pp;
	if(pp == 0 || (_tos->prof.pid && _tos->pid != _tos->prof.pid))
		return _restore(arg, ret);
- if(pc == pp->pc){
- pp->rec++;
- p = pp;
- goto out;
- }
	for(p=pp->down; p; p=p->link)
		if(p->pc == pc)
			goto out;
@@ -119,10 +111,7 @@
		p->time = p->time + _tos->clock;
		break;
	}
- if(p->rec)
- p->rec--;
- else
- _tos->prof.pp = p->old;
+ _tos->prof.pp = p->old;
	return _restore(arg, ret);
 }

@@ -130,10 +119,11 @@
 _profdump(void)
 {
	int f;
- long n;
+ vlong n;
	Plink *p;
	char *vp;
	char filename[64];
+ uchar hdr[4+8] = {'p', 'r', 0x0f, 0x2};

	if (_tos->prof.what == 0)
		return; /* No profiling */
@@ -168,8 +158,17 @@
		_tos->prof.first->time = _tos->clock;
		break;
	}
- vp = (char*)_tos->prof.first;
+ hdr[4+0] = _tos->cyclefreq>>56;
+ hdr[4+1] = _tos->cyclefreq>>48;
+ hdr[4+2] = _tos->cyclefreq>>40;
+ hdr[4+3] = _tos->cyclefreq>>32;
+ hdr[4+4] = _tos->cyclefreq>>24;
+ hdr[4+5] = _tos->cyclefreq>>16;
+ hdr[4+6] = _tos->cyclefreq>>8;
+ hdr[4+7] = _tos->cyclefreq;
+ write(f, hdr, sizeof hdr);

+ vp = (char*)_tos->prof.first;
	for(p = _tos->prof.first; p <= _tos->prof.next; p++) {

		/*
@@ -214,16 +213,16 @@
		/*
		 * vlong time
		 */
- if (havecycles){
- n = (vlong)(p->time / (vlong)khz);
- }else
- n = p->time;
-
- vp[0] = n>>24;
- vp[1] = n>>16;
- vp[2] = n>>8;
- vp[3] = n;
- vp += 4;
+ n = p->time;
+ vp[0] = n>>56;
+ vp[1] = n>>48;
+ vp[2] = n>>40;
+ vp[3] = n>>32;
+ vp[4] = n>>24;
+ vp[5] = n>>16;
+ vp[6] = n>>8;
+ vp[7] = n;
+ vp += 8;
	}
	write(f, (char*)_tos->prof.first, vp - (char*)_tos->prof.first);
	close(f);
@@ -250,10 +249,6 @@
	int n, f;

	n = 256*1024;
- if (_tos->cyclefreq != 0LL){
- khz = _tos->cyclefreq / 1000; /* Report times in milliseconds */
- havecycles = 1;
- }
	f = open("/env/profsize", OREAD|OCEXEC);
	if(f >= 0) {
		memset(ename, 0, sizeof(ename));


next