1
0
Files
2022-09-29 17:59:04 +03:00

163 lines
3.5 KiB
C

#include <string.h>
#include <ctype.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include "util.h"
#define roundup(x, y) ((((x)+((y)-1))/(y))*(y))
int numb_processors = 1;
const char* appName = "";
const char* hostname = "";
static void
proc_syntax(const char* what)
{
fatal("syntax error in processor list; %s", what);
}
void
parse_proc_str(const char* arg, uint64_t mask[])
{
const char* cp = arg;
memset(mask, 0, roundup(numb_processors,64)>>3);
while (*cp) {
int m, n;
if (!isdigit(*cp))
proc_syntax("expecting CPU number");
m = 0;
do {
m = 10*m + (*cp-'0');
} while (isdigit(*++cp));
if (*cp == '-') {
cp++;
if (isdigit(*cp)) {
n = 0;
do {
n = 10*n + (*cp-'0');
} while (isdigit(*++cp));
} else if (*cp == '\0') { /* e.g. 2- */
n = numb_processors-1;
} else
proc_syntax("expecting CPU number");
} else if (*cp == ',') {
cp++;
n = m;
} else if (*cp == '\0') {
n = m;
} else
proc_syntax("expecting ',' or '-' after CPU number");
if (m > n)
fatal("inverted CPU range, %d > %d", m, n);
if (m >= numb_processors)
fatal("%d: CPU number out of range; %s has only %d processors",
m, hostname, numb_processors);
for (; m <= n; m++)
mask[m>>6] |= ((uint64_t) 1)<<(m&0x3f);
}
}
static void
event_syntax(const char* what)
{
fatal("syntax error in event list; %s", what);
}
typedef struct {
const char* name;
uint64_t mask;
} maskname_t;
static uint64_t
event_mask_name(const char* tp, size_t n)
{
#define N(a) (sizeof (a) / sizeof (a[0]))
static maskname_t masks[] = {
{ "debug", RTMON_DEBUG },
{ "signal", RTMON_SIGNAL },
{ "syscall", RTMON_SYSCALL },
{ "task", RTMON_TASK },
{ "taskproc", RTMON_TASKPROC },
{ "intr", RTMON_INTR },
{ "framesched", RTMON_FRAMESCHED },
{ "profile", RTMON_PROFILE },
{ "vm", RTMON_VM },
{ "scheduler", RTMON_SCHEDULER },
{ "disk", RTMON_DISK },
{ "netsched", RTMON_NETSCHED },
{ "netflow", RTMON_NETFLOW },
{ "alloc", RTMON_ALLOC },
{ "all", RTMON_ALL },
{ "network", RTMON_NETSCHED|RTMON_NETFLOW },
{ "io", RTMON_DISK|RTMON_INTR },
{ "par", RTMON_PAR },
};
maskname_t* mp;
uint64_t maskval;
char *sval;
sval = (char *) malloc(n + 1);
if (sval == NULL) {
fatal("cannot allocate working storage");
/*NOTREACHED*/
}
strncpy(sval,tp,n);
sval[n] = 0;
for (mp = masks; mp < &masks[N(masks)]; mp++)
if (strcasecmp(mp->name, sval) == 0) {
free((void *) sval);
return (mp->mask);
}
if (sscanf(sval,"%lli",&maskval) == 1) {
free((void *) sval);
return(maskval);
}
free((void *) sval);
fatal("%.*s: Uknown event mask name", n, tp);
/*NOTREACHED*/
#undef N
}
uint64_t
parse_event_str(const char* arg)
{
const char* cp = arg;
uint64_t mask = 0;
int incl = 1;
while (*cp) {
if (isalnum(*cp)) {
const char* tp = cp;
do {
*cp++;
} while (isalnum(*cp));
if (incl)
mask |= event_mask_name(tp, cp-tp);
else
mask &= ~event_mask_name(tp, cp-tp);
} else
event_syntax("expecting event mask name");
if (*cp == ',' || *cp == '|' || *cp == '+' || *cp == '-')
incl = (*cp++ != '-');
else if (*cp != '\0')
event_syntax("expecting ',' after event mask name");
}
return (mask);
}
void
fatal(const char* fmt, ...)
{
va_list ap;
fprintf(stderr, "%s: ", appName);
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
fputc('\n', stderr);
exit(EXIT_FAILURE);
}