static void * pcpu_sucker(void *dummy) { int i, j, loops, sts; double array[100]; long iterations; for (loops = 0; loops < 10; loops++) { if ((sts = pmtracebegin("pcpu_sucker")) < 0) { fprintf(stderr, "%s: pcpu_sucker begin (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return NULL; } iterations = lrand48() % CPU_UPPER_LIMIT; memset((void *)array, 0, 100*sizeof(double)); for (i = 0; i < iterations; i++) for (j = 0; j < 100; j++) array[j] = (double)(j*iterations); if ((sts = pmtraceend("pcpu_sucker")) < 0) { fprintf(stderr, "%s: pcpu_sucker end (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return NULL; } } fprintf(stderr, "%s: finished %d cpu-bound iterations.\n", prog, loops); return NULL; }
static void cpu_sucker(void) { int i, j, sts; double array[100]; long iterations; if ((sts = pmtracebegin("cpu_sucker")) < 0) { fprintf(stderr, "%s: cpu_sucker begin (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return; } iterations = lrand48() % CPU_UPPER_LIMIT; memset((void *)array, 0, 100*sizeof(double)); for (i = 0; i < iterations; i++) for (j = 0; j < 100; j++) array[j] = (double)(j*iterations); if ((sts = pmtraceend("cpu_sucker")) < 0) { fprintf(stderr, "%s: cpu_sucker end (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return; } }
static void io_sucker(void) { long characters; FILE *foo; int i, sts; if ((sts = pmtracebegin("io_sucker")) < 0) { fprintf(stderr, "%s: io_sucker start (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return; } if ((foo = fopen("/dev/null", "rw")) == NULL) { fprintf(stderr, "%s: io_sucker can't open /dev/null.\n", prog); return; } characters = lrand48() % IO_UPPER_LIMIT; for (i = 0; i < characters; i++) { fgetc(foo); fputc('!', foo); } fclose(foo); if ((sts = pmtraceend("io_sucker")) < 0) { fprintf(stderr, "%s: io_sucker end (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return; } }
static void * pio_sucker(void *dummy) { long characters; FILE *foo; int i, loops, sts; for (loops = 0; loops < 10; loops++) { if ((sts = pmtracebegin("pio_sucker")) < 0) { fprintf(stderr, "%s: pio_sucker start (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return NULL; } if ((foo = fopen("/dev/null", "rw")) == NULL) { fprintf(stderr, "%s: pio_sucker can't open /dev/null.\n", prog); return NULL; } characters = lrand48() % IO_UPPER_LIMIT; for (i = 0; i < characters; i++) { fgetc(foo); fputc('!', foo); } fclose(foo); if ((sts = pmtraceend("pio_sucker")) < 0) { fprintf(stderr, "%s: pio_sucker end (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return NULL; } } fprintf(stderr, "%s: finished %d io-bound iterations.\n", prog, loops); return NULL; }
static void * ptime_sucker(void *dummy) { long seconds; int loops, sts; for (loops = 0; loops < 10; loops++) { if ((sts = pmtracebegin("ptime_sucker")) < 0) { fprintf(stderr, "%s: ptime_sucker start (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return NULL; } seconds = lrand48() % TIME_UPPER_LIMIT; sleep((unsigned int)seconds); if ((sts = pmtraceend("ptime_sucker")) < 0) { fprintf(stderr, "%s: ptime_sucker end (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return NULL; } } fprintf(stderr, "%s: finished %d timer iterations.\n", prog, loops); return NULL; }
int main(int argc, char **argv) { int sts; char *prog; prog = argv[0]; sts = pmtracestate(PMTRACE_STATE_API|PMTRACE_STATE_COMMS|PMTRACE_STATE_PDU); fprintf(stderr, "%s: start: %s (state=0x%x)\n", prog, pmtraceerrstr(0), sts); /* force call to all library symbols */ if ((sts = pmtracebegin("simple")) < 0) { fprintf(stderr, "%s: pmtracebegin error: %s\n", prog, pmtraceerrstr(sts)); exit(1); } if (sleep(2) != 0) { fprintf(stderr, "%s: sleep prematurely awaken\n", prog); pmtraceabort("simple"); } if ((sts = pmtraceend("simple")) < 0) { fprintf(stderr, "%s: pmtraceend error: %s\n", prog, pmtraceerrstr(sts)); exit(1); } if ((sts = pmtracebegin("ascanbe")) < 0) { fprintf(stderr, "%s: pmtracebegin error: %s\n", prog, pmtraceerrstr(sts)); exit(1); } sleep(1); if ((sts = pmtraceend("ascanbe")) < 0) { fprintf(stderr, "%s: pmtraceend error: %s\n", prog, pmtraceerrstr(sts)); exit(1); } if ((sts = pmtraceobs("observe", 101.0)) < 0) { fprintf(stderr, "%s: pmtraceobs error: %s\n", prog, pmtraceerrstr(sts)); exit(1); } if ((sts = pmtracecounter("counter", 101.1)) < 0) { fprintf(stderr, "%s: pmtracecounter error: %s\n", prog, pmtraceerrstr(sts)); exit(1); } if ((sts = pmtracepoint("imouttahere")) < 0) { fprintf(stderr, "%s: pmtracepoint error: %s\n", prog, pmtraceerrstr(sts)); exit(1); } exit(0); }
int main(int argc, char **argv) { int i, sts; prog = argv[0]; srand48(time(0)); /* uncomment this for debugging information */ /* pmtracestate(PMTRACE_STATE_API|PMTRACE_STATE_COMMS|PMTRACE_STATE_PDU); */ /* uncomment this to use the asynchronous protocol */ /* pmtracestate(PMTRACE_STATE_ASYNC); */ for (i = 0;; i++) { if ((sts = pmtracepoint("mainloop")) < 0) { fprintf(stderr, "%s: mainloop point trace failed (%d): %s\n", prog, sts, pmtraceerrstr(sts)); exit(1); } switch(i % 3) { case 0: time_sucker(); break; case 1: io_sucker(); break; case 2: cpu_sucker(); break; } } }
static void time_sucker(void) { long seconds; int sts; if ((sts = pmtracebegin("time_sucker")) < 0) { fprintf(stderr, "%s: time_sucker start (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return; } seconds = lrand48() % TIME_UPPER_LIMIT; sleep((unsigned int)seconds); if ((sts = pmtraceend("time_sucker")) < 0) { fprintf(stderr, "%s: time_sucker end (%d): %s\n", prog, sts, pmtraceerrstr(sts)); return; } }
int __pmtracegetPDU(int fd, int timeout, __pmTracePDU **result) { int need, len; char *handle; static int maxsize = TRACE_PDU_CHUNK; __pmTracePDU *pdubuf; __pmTracePDU *pdubuf_prev; __pmTracePDUHdr *php; /* * This stuff is a little tricky. What we try to do is read() * an amount of data equal to the largest PDU we have (or are * likely to have) seen thus far. In the majority of cases * this returns exactly one PDU's worth, i.e. read() returns * a length equal to php->len. * * For this to work, we have a special "mode" of -1 * to pduread() which means read, but return after the * first read(), rather than trying to read up to the request * length with multiple read()s, which would of course "hang" * after the first PDU arrived. * * We need to handle the following tricky cases: * 1. We get _more_ than we need for a single PDU -- happens * when PDU's arrive together. This requires "moreinput" * to handle leftovers here (it gets even uglier if we * have part, but not all of the second PDU). * 2. We get _less_ than we need for a single PDU -- this * requires at least another read(), and possibly acquiring * another pdubuf and doing a memcpy() for the partial PDU * from the earlier call. */ if (__pmtracemoreinput(fd)) { /* some leftover from last time ... handle -> start of PDU */ pdubuf = more[fd].pdubuf; len = more[fd].len; __pmtracenomoreinput(fd); } else { if ((pdubuf = __pmtracefindPDUbuf(maxsize)) == NULL) return -oserror(); len = pduread(fd, (void *)pdubuf, maxsize, -1, timeout); } php = (__pmTracePDUHdr *)pdubuf; if (len < (int)sizeof(__pmTracePDUHdr)) { if (len == -1) { if (oserror() == ECONNRESET|| oserror() == ETIMEDOUT || oserror() == ENETDOWN || oserror() == ENETUNREACH || oserror() == EHOSTDOWN || oserror() == EHOSTUNREACH || oserror() == ECONNREFUSED) /* * failed as a result of pmdatrace exiting and the * connection being reset, or as a result of the kernel * ripping down the connection (most likely because the * host at the other end just took a dive) * * treat this like end of file on input * * from irix/kern/fs/nfs/bds.c seems like all of the * following are peers here: * ECONNRESET (pmdatrace terminated?) * ETIMEDOUT ENETDOWN ENETUNREACH EHOSTDOWN EHOSTUNREACH * ECONNREFUSED * peers for bds but not here: * ENETRESET ENONET ESHUTDOWN (cache_fs only?) * ECONNABORTED (accept, user req only?) * ENOTCONN (udp?) * EPIPE EAGAIN (nfs, bds & ..., but not ip or tcp?) */ len = 0; else fprintf(stderr, "__pmtracegetPDU: fd=%d hdr: %s", fd, osstrerror()); } else if (len > 0) fprintf(stderr, "__pmtracegetPDU: fd=%d hdr: len=%d, not %d?", fd, len, (int)sizeof(__pmTracePDUHdr)); else if (len == PMTRACE_ERR_TIMEOUT) return PMTRACE_ERR_TIMEOUT; else if (len < 0) fprintf(stderr, "__pmtracegetPDU: fd=%d hdr: %s", fd, pmtraceerrstr(len)); return len ? PMTRACE_ERR_IPC : 0; } php->len = ntohl(php->len); if (php->len < 0) { fprintf(stderr, "__pmtracegetPDU: fd=%d illegal len=%d in hdr\n", fd, php->len); return PMTRACE_ERR_IPC; } if (len == php->len) /* return below */ ; else if (len > php->len) { /* * read more than we need for this one, save it up for next time */ handle = (char *)pdubuf; moreinput(fd, (__pmTracePDU *)&handle[php->len], len - php->len); } else { int tmpsize; /* * need to read more ... */ __pmtracepinPDUbuf(pdubuf); pdubuf_prev = pdubuf; if (php->len > maxsize) tmpsize = TRACE_PDU_CHUNK * ( 1 + php->len / TRACE_PDU_CHUNK); else tmpsize = maxsize; if ((pdubuf = __pmtracefindPDUbuf(tmpsize)) == NULL) { __pmtraceunpinPDUbuf(pdubuf_prev); return -oserror(); } if (php->len > maxsize) maxsize = tmpsize; memmove((void *)pdubuf, (void *)php, len); __pmtraceunpinPDUbuf(pdubuf_prev); php = (__pmTracePDUHdr *)pdubuf; need = php->len - len; handle = (char *)pdubuf; /* block until all of the PDU is received this time */ len = pduread(fd, (void *)&handle[len], need, 0, timeout); if (len != need) { if (len == PMTRACE_ERR_TIMEOUT) return PMTRACE_ERR_TIMEOUT; if (len < 0) fprintf(stderr, "__pmtracegetPDU: error (%d) fd=%d: %s\n", (int)oserror(), fd, osstrerror()); else fprintf(stderr, "__pmtracegetPDU: len=%d, not %d? (fd=%d)\n", len, need, fd); fprintf(stderr, "hdr: len=0x%08x type=0x%08x from=0x%08x\n", php->len, (int)ntohl(php->type), (int)ntohl(php->from)); return PMTRACE_ERR_IPC; } } *result = (__pmTracePDU *)php; php->type = ntohl(php->type); php->from = ntohl(php->from); #ifdef PMTRACE_DEBUG if (__pmstate & PMTRACE_STATE_PDU) { int j; int jend = (int)(php->len+(int)sizeof(__pmTracePDU)-1)/(int)sizeof(__pmTracePDU); char *p; /* for Purify ... */ p = (char *)*result + php->len; while (p < (char *)*result + jend*sizeof(__pmTracePDU)) *p++ = '~'; /* buffer end */ fprintf(stderr, "[%" FMT_PID "]__pmtracegetPDU: %s fd=%d len=%d from=%d", (pid_t)getpid(), pdutypestr(php->type), fd, php->len, php->from); for (j = 0; j < jend; j++) { if ((j % 8) == 0) fprintf(stderr, "\n%03d: ", j); fprintf(stderr, "%8x ", (*result)[j]); } putc('\n', stderr); } #endif return php->type; }