home *** CD-ROM | disk | FTP | other *** search
- #include <std.h>
- #include <iostream.h>
- #include <sys/stat.h>
- #include <new.h>
- #include "bmonout.h"
-
- const char* bmonout::nowname = 0;
-
- void bmonout::newhandler(void)
- {
- cerr << nowname << " probably has the wrong format\n";
- exit(1);
- }
-
- /* Note: bmon.c uses unsigned longs as addresses, while all this uses
- unsigned ints. I suppose one should really use caddr_t (usually
- char *), but the kernel thinks that eip is an unsigned long. */
-
- bmonout::bmonout(const char* file)
- {
- int fd = open(file, O_RDONLY);
- if (fd == -1) {
- perror(file);
- exit(1);
- }
-
- stat flstat;
- if (stat(file, &flstat) == -1) {
- perror("Cannot stat bmon file");
- exit(1);
- }
- size_t filesize = flstat.st_size/(2*sizeof(unsigned int));
- if (!filesize ||
- filesize*2*sizeof(unsigned int) != flstat.st_size) {
- cerr << file << " has a wrong length\n";
- exit(1);
- }
- _mtime = flstat.st_mtime;
-
- read(fd, &lowpc, sizeof(lowpc));
- lseek(fd, -2*sizeof(unsigned int), SEEK_END);
- read(fd, &highpc, sizeof(highpc));
- unsigned int diff = highpc - lowpc + 1;
-
- /* If this is the wrong file, highpc and lowpc can be anything and
- the new will probably fail miserably. So if it fails suspect a
- wrong file. */
- nowname = file;
- set_new_handler(newhandler);
- count = new unsigned int[diff];
- set_new_handler(0);
- memset(count, 0, diff * sizeof(unsigned int));
-
- lseek(fd, 0, SEEK_SET);
- unsigned int ticks[2];
- for (int i = 0; i < filesize; i++) {
- read(fd, ticks, sizeof(ticks));
- int index = ticks[0] - lowpc;
- if (index < 0 || index >= diff) {
- cerr << file << " has the wrong format\n";
- exit(1);
- }
- count[ticks[0]-lowpc] = ticks[1];
- }
-
- close(fd);
- }
-
- bmonout::~bmonout(void)
- {
- delete[] count;
- }
-
- unsigned int bmonout::operator[](unsigned int pc) const
- {
- if (pc < lowpc || pc > highpc)
- return 0;
- return count[pc-lowpc];
- }
-