int main(int argc, char **argv) { estats_error* err = NULL; struct estats_nl_client* cl = NULL; estats_val_data* data = NULL; estats_record* record = NULL; estats_val val; char* str; int cid, i, j; struct estats_connection_tuple_ascii tuple_ascii; if (argc < 2) { usage(); exit(EXIT_FAILURE); } cid = atoi(argv[1]); Chk(estats_nl_client_init(&cl)); Chk(estats_val_data_new(&data)); Chk(estats_record_open(&record, "./test-record", "w")); Chk(estats_read_vars(data, cid, cl)); printf("Timestamp sec: %u, usec: %u\n", data->tv.sec, data->tv.usec); Chk(estats_connection_tuple_as_strings(&tuple_ascii, &data->tuple)); printf("Address: %s %s %s %s\n", tuple_ascii.local_addr, tuple_ascii.local_port, tuple_ascii.rem_addr, tuple_ascii.rem_port); for (i = 0; i < data->length; i++) { Chk(estats_val_as_string(&str, &data->val[i], estats_var_array[i].valtype)); printf("%s: %s\n", estats_var_array[i].name, str); free(str); } Chk(estats_record_write_data(record, data)); Cleanup: estats_val_data_free(&data); estats_record_close(&record); estats_nl_client_destroy(&cl); if (err != NULL) { PRINT_AND_FREE(err); return EXIT_FAILURE; } return EXIT_SUCCESS; }
/** * Stop snapWorker * @param workerThreadId Worker Thread's ID * @param snaplogenabled boolean indication whether snap logging is enabled * @param snapArgs_ptr pointer to a snapArgs object * */ void stop_snap_worker(pthread_t *workerThreadId, char snaplogenabled, SnapArgs* snapArgs_ptr) { if (*workerThreadId) { pthread_mutex_lock(&mainmutex); workerLoop = 0; pthread_mutex_unlock(&mainmutex); pthread_join(*workerThreadId, NULL); } // close writing snaplog, if snaplog recording is enabled #if USE_WEB100 if (snaplogenabled) { web100_log_close_write(snapArgs_ptr->log); } web100_snapshot_free(snapArgs_ptr->snap); #elif USE_WEB10G if (snaplogenabled) { estats_record_close(&snapArgs_ptr->log); } estats_val_data_free(&snapArgs_ptr->snap); #endif }
/** * Plot anything else. * * @param list A comma seperated list of Web100/Web10G names to * plot. * @param cnt The number of items in list to plot, starting from the * start. Shouldn't be larger than the number of items in 'list' * @param name The file name to output to (gets .<remport>.xpls * appended to the end). * @param snap Allocated storage for Web100 - NULL for Web10G * @param log A open Web100/Web10G log file * @param agent A Web100 agent - ignored by Web10G should be NULL * @param group A Web100 group - ignored by Web10G should be NULL * @param func (Can be NULL) A function that expects two integers for * its arguments and returns a new integer. The first interger * corrosponds to the item in 'list' 0 for the first etc. * The second the value in the snap. The returned value is * plotted. * Called once for every list item for ever snap in the log. */ void plot_var(char *list, int cnt, char *name, tcp_stat_snap* snap, tcp_stat_log* log, tcp_stat_agent* agent, tcp_stat_group* group, int(*func)(const int arg, const int value)) { #if USE_WEB10G estats_error* err = NULL; #endif char *varg; /*char buf[256]; web100_var* var;*/ char varlist[256], lname[256], remport[8]; char title[256]; int i, first = 0; float x1, x2, y1[32], y2[32]; FILE *fn; /* Write a xplot file out to the requested file. * Start by extracting the connection info for the * page title. Then its a series of line statements * with the x1 y1 x2 y2 coordinates. */ memset(lname, 0, 256); /* Get the first snap from the log */ #if USE_WEB100 if ((web100_snap_from_log(snap, log)) != WEB100_ERR_SUCCESS) { web100_perror("web100_snap_from_log"); return; } #elif USE_WEB10G if ((err = estats_record_read_data(&snap, log)) != NULL) { estats_record_close(&log); estats_error_print(stderr, err); estats_error_free(&err); return; } #endif get_title(snap, agent, group, title, remport); if (name == NULL) { fn = stdout; /* XXX writing into a NULL pointer?? */ // strncpy(name, "Unknown", 7); name = "Unknown"; } else { snprintf(lname, sizeof(lname), "%s.%s.xpl", name, remport); fn = fopen(lname, "w"); } fprintf(fn, "double double\ntitle\n"); fprintf(fn, "%s:%s (%s)\n", title, remport, name); if ((strncmp(name, "Throughput", 10)) == 0) fprintf(fn, "xlabel\nTime\nylabel\nMbits/sec\n"); else fprintf(fn, "xlabel\nTime\nylabel\nKilo Bytes\n"); x1 = x2 = 0; for (i = 0; i < 32; i++) { y1[i] = 0; y2[i] = 0; } first = 0; for (;;) { /* We've already read the first item to use with get_title */ if (first != 0) { #if USE_WEB100 if ((web100_snap_from_log(snap, log)) != WEB100_ERR_SUCCESS) { #elif USE_WEB10G if ((err = estats_record_read_data(&snap, log)) != NULL) { estats_error_free(&err); #endif fprintf(fn, "go\n"); return; } } strncpy(varlist, list, strlen(list) + 1); varg = strtok(varlist, ","); for (i = 0; i < cnt; i++) { if (i == 0) { if (first == 0) { if (func) { x1 = func( i, checkmz( tcp_stat_read_double(varg, snap, group, agent))); } else { x1 = checkmz( tcp_stat_read_double(varg, snap, group, agent)); } } else { x1 = x2; } } else { if (first == 0) { if (func) { y1[i - 1] = func( i, checkmz( tcp_stat_read_double(varg, snap, group, agent))); } else { y1[i - 1] = checkmz( tcp_stat_read_double(varg, snap, group, agent)); } } else { y1[i - 1] = y2[i - 1]; } } varg = strtok(NULL, ","); } first++; strncpy(varlist, list, strlen(list) + 1); varg = strtok(varlist, ","); for (i = 0; i < cnt; i++) { if (i == 0) { if (func) { x2 = func( i, checkmz( tcp_stat_read_double(varg, snap, group, agent))); } else { x2 = checkmz( tcp_stat_read_double(varg, snap, group, agent)); } } else { if (func) { y2[i - 1] = func( i, checkmz( tcp_stat_read_double(varg, snap, group, agent))); } else { y2[i - 1] = checkmz( tcp_stat_read_double(varg, snap, group, agent)); } fprintf(fn, "%s\nline %0.4f %0.4f %0.4f %0.4f\n", color[i - 1], x1 / 1000000, y1[i - 1] / 1024, x2 / 1000000, y2[i - 1] / 1024); } varg = strtok(NULL, ","); } #if USE_WEB10G estats_val_data_free(&snap); #endif } fprintf(fn, "go\n"); } /** * Make a plot CwndTime(%) against total time. * * @param name The file name to output to (gets .<remport>.xpls * appended to the end). * @param snap Allocated storage for Web100 - NULL for Web10G * @param log A open Web100/Web10G log file * @param agent A Web100 agent - ignored by Web10G should be NULL * @param group A Web100 group - ignored by Web10G should be NULL */ void plot_cwndtime(char *name, tcp_stat_snap* snap, tcp_stat_log* log, tcp_stat_agent* agent, tcp_stat_group* group) { #if USE_WEB10G estats_error* err = NULL; #endif double SndLimTimeRwin = 0, SndLimTimeSender = 0; char lname[256], remport[8]; char title[256]; char* variables[] = { ELAPSED_TIME, "SndLimTimeRwin", TIME_SENDER, "SndLimTimeCwnd" }; int i, first = 0; double x1, x2, y1, y2; FILE *fn; memset(lname, 0, 256); /* Get the first snap from the log */ #if USE_WEB100 if ((web100_snap_from_log(snap, log)) != WEB100_ERR_SUCCESS) { web100_perror("web100_snap_from_log"); return; } #elif USE_WEB10G if ((err = estats_record_read_data(&snap, log)) != NULL) { estats_record_close(&log); estats_error_print(stderr, err); estats_error_free(&err); return; } #endif get_title(snap, agent, group, title, remport); if (name == NULL) { fn = stdout; /* XXX writing into a NULL pointer?? */ // strncpy(name, "Unknown", 7); name = "Unknown"; } else { snprintf(lname, sizeof(lname), "%s.%s.xpl", name, remport); fn = fopen(lname, "w"); } fprintf(fn, "double double\ntitle\n"); fprintf(fn, "%s:%s (%s)\n", title, remport, name); fprintf(fn, "xlabel\nTime\nylabel\nPercentage\n"); x1 = x2 = y1 = y2 = 0; first = 0; for (;;) { /* We've already read the first item to use with get_title */ if (first != 0) { #if USE_WEB100 if ((web100_snap_from_log(snap, log)) != WEB100_ERR_SUCCESS) { #elif USE_WEB10G if ((err = estats_record_read_data(&snap, log)) != NULL) { estats_error_free(&err); #endif fprintf(fn, "go\n"); return; } } for (i = 0; i < 4; i++) { if (first == 0) { /* Give everything starting values */ switch (i) { case 0: /* ELAPSED_TIME */ x1 = tcp_stat_read_double(variables[i], snap, group, agent); break; case 1: /* "SndLimTimeRwin" */ SndLimTimeRwin = tcp_stat_read_double(variables[i], snap, group, agent); break; case 2: /* "SndLimTimeSender" */ SndLimTimeSender = tcp_stat_read_double(variables[i], snap, group, agent); break; case 3: /* "SndLimTimeCwnd" */ y1 = tcp_stat_read_double(variables[i], snap, group, agent); y1 = y1 / (SndLimTimeRwin + SndLimTimeSender + y1); break; } } else { switch (i) { case 0: /* ELAPSED_TIME */ x1 = x2; break; case 3: /* "SndLimTimeCwnd" */ y1 = y2; break; } } } first++; for (i = 0; i < 4; i++) { if (i == 0) { /* ELAPSED_TIME */ x2 = tcp_stat_read_double(variables[i], snap, group, agent); } else if (i == 1) { /* "SndLimTimeRwin" */ SndLimTimeRwin = tcp_stat_read_double(variables[i], snap, group, agent); } else if (i == 2) { /* "SndLimTimeSender" */ SndLimTimeSender = tcp_stat_read_double(variables[i], snap, group, agent); } else { /* "SndLimTimeCwnd" */ y2 = tcp_stat_read_double(variables[i], snap, group, agent); y2 = y2 / (SndLimTimeRwin + SndLimTimeSender + y2); fprintf(fn, "%s\nline %0.4f %0.4f %0.4f %0.4f\n", color[i - 1], x1 / 1000000, y1, x2 / 1000000, y2); } } #if USE_WEB10G estats_val_data_free(&snap); #endif } fprintf(fn, "go\n"); } /** * * Loop through the supplied list of variables and prints them to * stdout as a new row for every snap in the log file. * * A function 'func' can be provided to changed how these are printed. * * @param varlist A comma seperated list of Web100/Web10G names to * print. * @param snap Allocated storage for Web100 - NULL for Web10G * @param log A open Web100/Web10G log file * @param agent A Web100 agent - ignored by Web10G should be NULL * @param group A Web100 group - ignored by Web10G should be NULL * @param func (Can be NULL) A function that expects two integers for * its arguments. The first corrosponds to the item in varlist * 0 for the first etc. The second the value in the snap. * Called once for every varlist item for ever snap in the log. */ void print_var(char *varlist, tcp_stat_snap* snap, tcp_stat_log* log, tcp_stat_agent* agent, tcp_stat_group* group, void(*func)(const int arg, const int value)) { char *varg, savelist[256]; char title[256], remport[8]; int i, j; #if USE_WEB10G estats_error* err = NULL; #endif FILE* fn; fn = stdout; /* Get the first snap from the log */ #if USE_WEB100 if ((web100_snap_from_log(snap, log)) != WEB100_ERR_SUCCESS) { web100_perror("web100_snap_from_log"); return; } #elif USE_WEB10G if ((err = estats_record_read_data(&snap, log)) != NULL) { estats_record_close(&log); estats_error_print(stderr, err); estats_error_free(&err); return; } #endif get_title(snap, agent, group, title, remport); fprintf(fn, "Extracting Data from %s:%s connection\n\n", title, remport); strncpy(savelist, varlist, strlen(varlist) + 1); printf("Index\t"); varg = strtok(varlist, ","); /* Loop through varlist and print them out as the column names */ for (j = 0;; j++) { if (varg == NULL) break; if (func) { func(-1, j); } else { printf("%10s\t", varg); } varg = strtok(NULL, ","); } printf("\n"); /* Loop over the log file */ for (i = 0;; i++) { /* We've already read the first item to use with get_title */ if (i != 0) { #if USE_WEB100 if ((web100_snap_from_log(snap, log)) != WEB100_ERR_SUCCESS) { #elif USE_WEB10G if ((err = estats_record_read_data(&snap, log)) != NULL) { estats_error_free(&err); #endif printf("-------------- End Of Data --------------\n\n"); return; } } printf("%5d\t", i); strncpy(varlist, savelist, strlen(savelist) + 1); varg = strtok(varlist, ","); /* Loop over the vars we are printing out */ for (j = 0;; j++) { if (varg == NULL) { break; } if (func) { /* Let the provided function do the printing */ func(j, (int) tcp_stat_read_double(varg, snap, group, agent)); } else { /* Do it ourself */ double value = tcp_stat_read_double(varg, snap, group, agent); // weird magic number ((2^32) - 1) - 919 if ((int) value == 4294966376) { printf("%10s\t", "-1"); } else { printf("%10"PRId64"\t", (int64_t) value); } } varg = strtok(NULL, ","); } #if USE_WEB10G estats_val_data_free(&snap); #endif printf("\n"); } } /* workers */ void throughput(const int arg, const int value) { static int duration; if (arg == -1) { if (value) { printf("%10s\t", "Throughput (mB/s)"); } else { printf("%10s\t", ELAPSED_TIME); } return; } if (!arg) { /* duration */ duration = value; printf("%10d\t", value); } else { /* DataBytesOut */ printf( "%10.2f", ((8 * ((double) value)) / ((double) duration)) * 1000000.0 / 1024.0 / 1024.0); } } int throughputPlot(const int arg, const int value) { static int duration; if (!arg) { /* duration */ duration = value; return value; } else { /* DataBytesOut */ return (((double) value) / ((double) duration)) * 1000000.0; } } void cwndtime(const int arg, const int value) { static int SndLimTimeRwin, SndLimTimeSender; if (arg == -1) { if (value == 0) { printf("%10s\t", ELAPSED_TIME); } else if (value == 3) { printf("%10s\t", "CwndTime (%% of total time)"); } return; } if (arg == 0) { /* duration */ printf("%10d\t", value); } else if (arg == 1) { /* SndLimTimeRwin */ SndLimTimeRwin = value; } else if (arg == 2) { /* SndLimTimeSender */ SndLimTimeSender = value; } else { /* SndLimTimeCwnd */ printf( "%10.2f", ((double) value) / (((double) SndLimTimeRwin) + ((double) SndLimTimeSender) + ((double) value))); } } /* --- */ int main(int argc, char** argv) { tcp_stat_agent* agent = NULL; tcp_stat_connection conn = NULL; tcp_stat_group* group = NULL; tcp_stat_log* log = NULL; tcp_stat_snap* snap = NULL; #if USE_WEB10G estats_error* err = NULL; #endif char fn[128]; char *varlist = NULL, list[1024]; char *varg; int j, c, plotspd = 0, plotuser = 0; int plotboth = 0, plotcwnd = 0, plotrwin = 0; int plotcwndtime = 0; int k, txt = 0; while ((c = getopt_long(argc, argv, "hCScRbtm:v", long_options, 0)) != -1) { switch (c) { case 'b': plotboth = 1; break; case 'h': genplot_long_usage("ANL/Internet2 NDT version " VERSION " (genplot)", argv[0]); break; case 'v': printf("ANL/Internet2 NDT version %s (genplot)\n", VERSION); exit(0); break; case 't': txt = 1; break; case 'C': plotcwnd = 1; break; case 'R': plotrwin = 1; break; case 'S': plotspd = 1; break; case 'c': plotcwndtime = 1; break; case 'm': varlist = optarg; plotuser = 1; break; } } if (optind == argc) { short_usage(argv[0], "Missing snaplog file"); } if (argc == 1) { short_usage(argv[0], "ANL/Internet2 NDT version " VERSION " (genplot)"); } for (j = optind; j < argc; j++) { snprintf(fn, sizeof(fn), "%s", argv[j]); #if USE_WEB100 if ((log = web100_log_open_read(fn)) == NULL) { web100_perror("web100_log_open_read"); exit(EXIT_FAILURE); } if ((agent = web100_get_log_agent(log)) == NULL) { web100_perror("web100_get_log_agent"); exit(EXIT_FAILURE); } if ((group = web100_get_log_group(log)) == NULL) { web100_perror("web100_get_log_group"); exit(EXIT_FAILURE); } if ((conn = web100_get_log_connection(log)) == NULL) { web100_perror("web100_get_log_connection"); exit(EXIT_FAILURE); } #elif USE_WEB10G if ((err = estats_record_open(&log, fn, "r")) != NULL) { estats_error_print(stderr, err); estats_error_free(&err); exit(EXIT_FAILURE); } #endif fprintf(stderr, "Extracting data from Snaplog '%s'\n\n", fn); #if USE_WEB100 if ((snap = web100_snapshot_alloc_from_log(log)) == NULL) { web100_perror("web100_snapshot_alloc_from_log"); exit(EXIT_FAILURE); } #endif if (plotuser == 1) { memset(list, 0, 1024); strncpy(list, ELAPSED_TIME",", 1024); strncat(list, varlist, strlen(varlist)); varg = strtok(list, ","); for (k = 1;; k++) { if ((varg = strtok(NULL, ",")) == NULL) break; } memset(list, 0, 1024); strncpy(list, ELAPSED_TIME",", 1024); strncat(list, varlist, strlen(varlist)); if (txt == 1) print_var(list, snap, log, agent, group, NULL); else plot_var(list, k, "User Defined", snap, log, agent, group, NULL); } if (plotspd == 1) { memset(list, 0, 1024); strncpy(list, ELAPSED_TIME","DATA_OCT_OUT, 1024); if (txt == 1) print_var(list, snap, log, agent, group, throughput); else plot_var(list, 2, "Throughput", snap, log, agent, group, throughputPlot); } if (plotcwndtime == 1) { memset(list, 0, 1024); strncpy(list, ELAPSED_TIME",SndLimTimeRwin,"TIME_SENDER",SndLimTimeCwnd", 1024); if (txt == 1) print_var(list, snap, log, agent, group, cwndtime); else plot_cwndtime("Cwnd Time", snap, log, agent, group); } if (plotcwnd == 1) { memset(list, 0, 1024); strncpy(list, ELAPSED_TIME",CurCwnd", 1024); if (txt == 1) print_var(list, snap, log, agent, group, NULL); else plot_var(list, 2, "CurCwnd", snap, log, agent, group, NULL); } if (plotrwin == 1) { memset(list, 0, 1024); strncpy(list, ELAPSED_TIME",CurRwinRcvd", 1024); if (txt == 1) print_var(list, snap, log, agent, group, NULL); else plot_var(list, 2, "CurRwinRcvd", snap, log, agent, group, NULL); } if (plotboth == 1) { memset(list, 0, 1024); strncpy(list, ELAPSED_TIME",CurCwnd,CurRwinRcvd", 1024); if (txt == 1) print_var(list, snap, log, agent, group, NULL); else plot_var(list, 3, "Both", snap, log, agent, group, NULL); } #if USE_WEB100 web100_log_close_read(log); #elif USE_WEB10G estats_record_close(&log); #endif } exit(0); }
int main(int argc, char **argv) { estats_error* err = NULL; struct estats_nl_client* cl = NULL; estats_val_data* data = NULL; // TODO(aka) currently not used // The MIB is generated in the DLKM with the following code: /* hdr = genlmsg_put(msg, 0, 0, &genl_estats_family, 0, TCPE_CMD_INIT); if (nla_put_u32(msg, NLE_ATTR_NUM_TABLES, MAX_TABLE)) if (nla_put_u32(msg, NLE_ATTR_NUM_VARS, TOTAL_NUM_VARS)) for (tblnum = 0; tblnum < MAX_TABLE; tblnum++) { switch (tblnum) { case PERF_TABLE: nest[tblnum] = nla_nest_start(msg, NLE_ATTR_PERF_VARS | NLA_F_NESTED); break; case PATH_TABLE: nest[tblnum] = nla_nest_start(msg, NLE_ATTR_PATH_VARS | NLA_F_NESTED); break; case STACK_TABLE: nest[tblnum] = nla_nest_start(msg, NLE_ATTR_STACK_VARS | NLA_F_NESTED); break; case APP_TABLE: nest[tblnum] = nla_nest_start(msg, NLE_ATTR_APP_VARS | NLA_F_NESTED); break; case TUNE_TABLE: nest[tblnum] = nla_nest_start(msg, NLE_ATTR_TUNE_VARS | NLA_F_NESTED); break; case EXTRAS_TABLE: nest[tblnum] = nla_nest_start(msg, NLE_ATTR_EXTRAS_VARS | NLA_F_NESTED); break; } if (!nest[tblnum]) goto nla_put_failure; for (i=0; i < estats_max_index[tblnum]; i++) { entry_nest = nla_nest_start(msg, NLE_ATTR_VAR | NLA_F_NESTED); if (nla_put_string(msg, NEA_VAR_NAME, estats_var_array[tblnum][i].name)) goto nla_put_failure; if (nla_put_u32(msg, NEA_VAR_TYPE, estats_var_array[tblnum][i].vartype)) goto nla_put_failure; nla_nest_end(msg, entry_nest); } nla_nest_end(msg, nest[tblnum]); } genlmsg_end(msg, hdr); */ Chk(estats_nl_client_init(&cl)); Chk(estats_val_data_new(&data)); Chk(estats_get_mib(data, cl)); // the MIB is printed out in estats_get_mib() Cleanup: estats_val_data_free(&data); estats_nl_client_destroy(&cl); if (err != NULL) { PRINT_AND_FREE(err); return EXIT_FAILURE; } return EXIT_SUCCESS; }
int main(int argc, char **argv) { estats_error* err = NULL; estats_nl_client* cl = NULL; estats_val_data* data = NULL; int cid, i, j; int opt, option; int stdout_flag = 0; int header_flag = 0; int interval = 1000; char *strmask = NULL; const char delim = ','; uint64_t tmpmask; struct estats_mask mask; mask.masks[0] = DEFAULT_PERF_MASK; mask.masks[1] = DEFAULT_PATH_MASK; mask.masks[2] = DEFAULT_STACK_MASK; mask.masks[3] = DEFAULT_APP_MASK; mask.masks[4] = DEFAULT_TUNE_MASK; for (i = 0; i < MAX_TABLE; i++) { mask.if_mask[i] = 0; } if (argc < 2) { usage(); exit(EXIT_FAILURE); } while ((opt = getopt(argc, argv, "hm:si:")) != -1) { switch (opt) { case 'h': usage(); exit(EXIT_SUCCESS); break; case 'm': strmask = strdup(optarg); for (j = 0; j < 5; j++) { char *strtmp; strtmp = strsep(&strmask, &delim); if (strtmp && strlen(strtmp)) { char *str; str = (str = strchr(strtmp, 'x')) ? str+1 : strtmp; if (sscanf(str, "%"PRIx64, &tmpmask) == 1) { mask.masks[j] = tmpmask & mask.masks[j]; mask.if_mask[j] = 1; } } } option = opt; break; case 's': stdout_flag = 1; break; case 'i': interval = atoi(optarg); break; default: exit(EXIT_FAILURE); break; } } if ((option == 'm') && (optind+1 > argc)) { printf("Too few non-option args\n"); exit(EXIT_FAILURE); } cid = atoi(argv[optind]); Chk(estats_nl_client_init(&cl)); Chk(estats_nl_client_set_mask(cl, &mask)); Chk(estats_val_data_new(&data)); while (1) { Chk(estats_read_vars(data, cid, cl)); if ((stdout_flag) && (!header_flag)) { printf("sec,usec,"); for (j = 0; j < data->length; j++) { if (data->val[j].masked) continue; printf("%s\t", estats_var_array[j].name); } printf("\n"); header_flag = 1; } if (!stdout_flag) printf("Timestamp sec: %u, usec: %u\n", data->tv.sec, data->tv.usec); else printf("%u,%u,", data->tv.sec, data->tv.usec); for (j = 0; j < data->length; j++) { if (!stdout_flag) { if (j == 0) printf("\n\n Perf Table\n\n"); if (j == PERF_INDEX_MAX) printf("\n\n Path Table\n\n"); if (j == PERF_INDEX_MAX+PATH_INDEX_MAX) printf("\n\n Stack Table\n\n"); if (j == PERF_INDEX_MAX+PATH_INDEX_MAX+STACK_INDEX_MAX) printf("\n\n App Table\n\n"); if (j == PERF_INDEX_MAX+PATH_INDEX_MAX+STACK_INDEX_MAX+APP_INDEX_MAX) printf("\n\n Tune Table\n\n"); } if (data->val[j].masked) continue; /* I could have had an if in each case statement but that seems like * it would have been much more expensive - cjr */ if (!stdout_flag) { switch(estats_var_array[j].valtype) { case ESTATS_UNSIGNED64: printf("%s=%"PRIu64"\n", estats_var_array[j].name, data->val[j].uv64); break; case ESTATS_UNSIGNED32: printf("%s=%"PRIu32"\n", estats_var_array[j].name, data->val[j].uv32); break; case ESTATS_SIGNED32: printf("%s=%"PRId32"\n", estats_var_array[j].name, data->val[j].sv32); break; case ESTATS_UNSIGNED16: printf("%s=%"PRIu16"\n", estats_var_array[j].name, data->val[j].uv16); break; case ESTATS_UNSIGNED8: printf("%s=%"PRIu8"\n", estats_var_array[j].name, data->val[j].uv8); break; default: break; } } else { switch(estats_var_array[j].valtype) { case ESTATS_UNSIGNED64: printf("%"PRIu64",", data->val[j].uv64); break; case ESTATS_UNSIGNED32: printf("%"PRIu32",", data->val[j].uv32); break; case ESTATS_SIGNED32: printf("%"PRId32",", data->val[j].sv32); break; case ESTATS_UNSIGNED16: printf("%"PRIu16",", data->val[j].uv16); break; case ESTATS_UNSIGNED8: printf("%"PRIu8",", data->val[j].uv8); break; default: break; } } } usleep(interval * 1000); printf("\n"); if (!stdout_flag) printf("\n"); } Cleanup: estats_val_data_free(&data); estats_nl_client_destroy(&cl); if (err != NULL) { PRINT_AND_FREE(err); return EXIT_FAILURE; } return EXIT_SUCCESS; }