kirkenda@psueea.uucp (Steve Kirkendall) (07/19/89)
At the end of this article is a profiler for Minix-ST. But first... In article <2892@ast.cs.vu.nl> ast@cs.vu.nl (Andy Tanenbaum) writes: >In article <1385@bruce.OZ> mark@bruce.OZ (Mark Goodwin) writes: >>Has anyone ported vi to Minix? >I have stevie running on MINIX. It is pretty vi like, but keeps the file >being edited in core, which limits it to files of around 50K. It really >is not well polished. If you are really a vi addict, you could >volunteer to finish it off :-) The source is 56 files and 375K bytes C text. >That shouldn't deter a real vi addict. Emacs is 10 times that. I >think the source should be in the archives. I am not wild about sending >375K to Australia, but will do it if you can't find it elsewhere. I've been working on a vi clone that uses temp files, like the real vi. I can even recover files in case of a crash! (Crashes are pretty common at this stage in development.) So far, I have most EX commands implemented and many of the VI movement commands, but almost none of the VI editing commands. My greatest concern at this time is *speed* -- on my ST, it has a hard time keeping up with auto-repeating keys. (Zips along pleasantly on a 20MHz '386 running Xenix, though; it can even keep up with auto-repeat of the <PgDn> key!) Last night I had an inspiration which may allow me to speed things up. I was fixing a bug, and thought, "Ugh! Why would I have done something like that? Oh, I see, it's simpler, faster, more compact, and less error-prone. Hmmm..." Size: About 50K text + 60K data. That's on an ST; an 8086 would have smaller text. I don't expect the data size to grow much, but text will probably grow by about 20K more. In short: It *might* run under MINIX-PC. The source is perhaps 100K at this time; it will probably peak at about 125k. <<<----------------------------------------------------------------------->>> <<< VAPORWARE ALERT: I work on this as I find time. Lately I have found >>> <<< plenty of time, and have made good progress, but I can't *promise* a >>> <<< delivery date. Also, don't expect an exact clone; I'm writing this >>> <<< precisely because there are a few things about VI that I don't like. >>> <<<----------------------------------------------------------------------->>> Having said that, I can tell you that I *hope* to have something worthwhile in about two months. Most differences concern the way text is displayed; keystrokes won't differ much. =============================================================================== Change of subject: In working to speed up VI, I have been doing a lot of profiling. The ACK compiler supports profiling via the "-p" flag, but the library lacks the necessary support functions. So I wrote my own. This code was developed for Minix-ST. It should be compiled WITHOUT the "-p" flag and added to /usr/lib/libc.a. You should then compile your program WITH "-p" and it will link in this code. This code collects statistics and then, when you return from main(), it writes the statistics to a file called profile.out. Note that you must *return* from main(); if you call exit(), then profile.out will not be created. This code also prints a stack trace in the event of a deadly signal. ------ cut here ---------- cut here ---------- cut here -------- cat >/usr/src/lib/profile.c /* profile.c */ /* This file contains functions which implement profiling. It depends on the * compiler to generate calls to procentry("funcname") at the start of every * function and procexit("funcname") at the end of each function. Also, * these functions dump a stack trace in the event of a deadly signal. */ #include <sys/types.h> #include <sys/times.h> #include <stdio.h> #include <signal.h> static struct { char *name; /* name of a function */ long time; /* accumulates time */ short cnt; /* number of calls */ } f[200]; /* tracks individual functions */ static struct { char *name; /* name of the function */ long time; /* records start time, used to calc elapsed time */ long xtime; /* time spent in sub functions */ } stack[30]; /* tracks nested active functions */ static int ns, nf; /* This function prints a stack trace */ static trace(signo) int signo; { static char *signames[] = { "", "SIGHUP", "SIGINT", "SIGQUIT", "SIGILL", "SIGTRAP", "SIGIOT", "SIGEMT", "SIGFPE", "SIGKILL", "SIGBUS", "SIGSEGV", "SIGSYS", "SIGPIPE", "SIGALRM", "SIGTERM" }; fprintf(stderr, "\r\n%s", signames[signo]); do { ns--; fprintf(stderr, "\t%s()\r\n", stack[ns].name); } while (ns > 0); exit(signo); } /* This function dumps the profiling info out to a file */ static pdump() { int i; FILE *fp; fp = fopen("profile.out", "w"); if (!fp) return; fprintf(fp, " time cnt name\n"); for (i = 0; i < nf; i++) { fprintf(fp, "%8ld%5d %s\n", f[i].time, f[i].cnt, f[i].name); } fclose(fp); } /* This function is called at the start of every user function. It records * the functions name (for stack tracing) and start time (for computation * of elapsed time). The first time, it also arranges for trace() to be * run when a deadly signal happens. */ procentry(name) char *name; { struct tms tbuf; /* initialize tracing? */ if (ns == 0) { signal(SIGQUIT, trace); /* ctrl-backslash */ signal(SIGILL, trace); /* illegal instruction */ signal(SIGFPE, trace); /* floating point exception */ signal(SIGBUS, trace); /* bus error */ signal(SIGSEGV, trace); /* segmentation violation */ } /* record this function call */ stack[ns].name = name; times(&tbuf); stack[ns].time = tbuf.tms_utime + tbuf.tms_stime; stack[ns].xtime = 0L; ns++; } /* This function is called at the end of each user function. It updates the * function's time & cnt accumulators, and, if we're returning from main(), * it calls dump() to write the profile info to a file */ procexit(name) char *name; { struct tms tbuf; int i; times(&tbuf); /* find the function's slot */ for (i = 0; i < nf && f[i].name != name; i++) { } if (i == nf) f[nf++].name = name; /* update it */ ns--; stack[ns].time = tbuf.tms_utime + tbuf.tms_stime - stack[ns].time - stack[ns].xtime; f[i].time += stack[ns].time; f[i].cnt++; /* if exiting main(), write the report */ if (ns == 0) { pdump(); } else { /* don't count the time as part of caller's time */ stack[ns - 1].xtime += stack[ns].time + stack[ns].xtime; } } ------ cut here ---------- cut here ---------- cut here -------- -- Steve Kirkendall ...uunet!tektronix!psu-cs!kirkenda