/** * @brief Verifies and translates multiple monitoring config strings into * internal PID monitoring configuration * * @param arg argument passed to -p command line option */ void selfn_monitor_pids(const char *arg) { char *cp = NULL, *str = NULL; char *saveptr = NULL; if (arg == NULL) parse_error(arg, "NULL pointer!"); if (strlen(arg) <= 0) parse_error(arg, "Empty string!"); selfn_strdup(&cp, arg); for (str = cp; ; str = NULL) { char *token = NULL; token = strtok_r(str, ";", &saveptr); if (token == NULL) break; sel_store_process_id(token); } free(cp); }
/** * @brief Function to set the descriptions and cores for each core group * * Takes a string containing individual cores and groups of cores and * breaks it into substrings which are used to set core group values * * @param s string containing cores to be divided into substrings * @param tab table of core groups to set values in * @param max maximum number of core groups allowed * * @return Number of core groups set up * @retval -1 on error */ static int strtocgrps(char *s, struct core_group *tab, const unsigned max) { unsigned i, n, index = 0; uint64_t cbuf[PQOS_MAX_CORES]; char *non_grp = NULL; ASSERT(tab != NULL); ASSERT(max > 0); if (s == NULL) return index; while ((non_grp = strsep(&s, "[")) != NULL) { int ret; /** * If group contains single core */ if ((strlen(non_grp)) > 0) { n = strlisttotab(non_grp, cbuf, (max-index)); if ((index+n) > max) return -1; /* set core group info */ for (i = 0; i < n; i++) { char *desc = uinttostr((unsigned)cbuf[i]); ret = set_cgrp(&tab[index], desc, &cbuf[i], 1); if (ret < 0) return -1; index++; } } /** * If group contains multiple cores */ char *grp = strsep(&s, "]"); if (grp != NULL) { char *desc = NULL; selfn_strdup(&desc, grp); n = strlisttotab(grp, cbuf, (max-index)); if (index+n > max) { free(desc); return -1; } /* set core group info */ ret = set_cgrp(&tab[index], desc, cbuf, n); if (ret < 0) { free(desc); return -1; } index++; } } return index; }
/** * @brief Function to safely translate an unsigned int * value to a string * * @param val value to be translated * * @return Pointer to allocated string */ static char* uinttostr(const unsigned val) { char buf[16], *str = NULL; memset(buf, 0, sizeof(buf)); snprintf(buf, sizeof(buf), "%u", val); selfn_strdup(&str, buf); return str; }
void selfn_allocation_assoc(const char *arg) { char *cp = NULL, *str = NULL; char *saveptr = NULL; if (arg == NULL) parse_error(arg, "NULL pointer!"); if (strlen(arg) <= 0) parse_error(arg, "Empty string!"); selfn_strdup(&cp, arg); for (str = cp; ; str = NULL) { char *token = NULL; token = strtok_r(str, ";", &saveptr); if (token == NULL) break; parse_allocation_assoc(token); } free(cp); }
void selfn_monitor_file(const char *arg) { selfn_strdup(&sel_output_file, arg); }
int main(int argc, char **argv) { struct pqos_config cfg; const struct pqos_cpuinfo *p_cpu = NULL; const struct pqos_cap *p_cap = NULL; const struct pqos_capability *cap_mon = NULL, *cap_l3ca = NULL; unsigned sock_count, sockets[PQOS_MAX_SOCKETS]; int cmd, ret, exit_val = EXIT_SUCCESS; int opt_index = 0; m_cmd_name = argv[0]; print_warning(); while ((cmd = getopt_long(argc, argv, "Hhf:i:m:Tt:l:o:u:e:c:a:p:S:srvVR", long_cmd_opts, &opt_index)) != -1) { switch (cmd) { case 'h': print_help(1); return EXIT_SUCCESS; case 'H': profile_l3ca_list(stdout); return EXIT_SUCCESS; case 'S': selfn_set_config(optarg); break; case 'f': if (sel_config_file != NULL) { printf("Only one config file argument is " "accepted!\n"); return EXIT_FAILURE; } selfn_strdup(&sel_config_file, optarg); parse_config_file(sel_config_file); break; case 'i': selfn_monitor_interval(optarg); break; case 'p': selfn_monitor_pids(optarg); break; case 'm': selfn_monitor_cores(optarg); break; case 't': selfn_monitor_time(optarg); break; case 'T': selfn_monitor_top_like(NULL); break; case 'l': selfn_log_file(optarg); break; case 'o': selfn_monitor_file(optarg); break; case 'u': selfn_monitor_file_type(optarg); break; case 'e': selfn_allocation_class(optarg); break; case 'r': sel_free_in_use_rmid = 1; break; case 'R': selfn_reset_cat(NULL); break; case 'a': selfn_allocation_assoc(optarg); break; case 'c': selfn_allocation_select(optarg); break; case 's': selfn_show_allocation(NULL); break; case 'v': selfn_verbose_mode(NULL); break; case 'V': selfn_super_verbose_mode(NULL); break; default: printf("Unsupported option: -%c. " "See option -h for help.\n", optopt); return EXIT_FAILURE; break; case '?': print_help(0); return EXIT_SUCCESS; break; } } memset(&cfg, 0, sizeof(cfg)); cfg.verbose = sel_verbose_mode; cfg.free_in_use_rmid = sel_free_in_use_rmid; cfg.cdp_cfg = selfn_cdp_config; /** * Set up file descriptor for message log */ if (sel_log_file == NULL) { cfg.fd_log = STDOUT_FILENO; } else { cfg.fd_log = open(sel_log_file, O_WRONLY|O_CREAT, S_IRUSR|S_IWUSR); if (cfg.fd_log == -1) { printf("Error opening %s log file!\n", sel_log_file); exit_val = EXIT_FAILURE; goto error_exit_2; } } ret = pqos_init(&cfg); if (ret != PQOS_RETVAL_OK) { printf("Error initializing PQoS library!\n"); exit_val = EXIT_FAILURE; goto error_exit_1; } ret = pqos_cap_get(&p_cap, &p_cpu); if (ret != PQOS_RETVAL_OK) { printf("Error retrieving PQoS capabilities!\n"); exit_val = EXIT_FAILURE; goto error_exit_2; } ret = pqos_cpu_get_sockets(p_cpu, PQOS_MAX_SOCKETS, &sock_count, sockets); if (ret != PQOS_RETVAL_OK) { printf("Error retrieving CPU socket information!\n"); exit_val = EXIT_FAILURE; goto error_exit_2; } ret = pqos_cap_get_type(p_cap, PQOS_CAP_TYPE_MON, &cap_mon); if (ret == PQOS_RETVAL_PARAM) { printf("Error retrieving monitoring capabilities!\n"); exit_val = EXIT_FAILURE; goto error_exit_2; } ret = pqos_cap_get_type(p_cap, PQOS_CAP_TYPE_L3CA, &cap_l3ca); if (ret == PQOS_RETVAL_PARAM) { printf("Error retrieving allocation capabilities!\n"); exit_val = EXIT_FAILURE; goto error_exit_2; } if (sel_reset_CAT) { /** * Reset CAT configuration to after-reset state and exit */ if (pqos_l3ca_reset(p_cap, p_cpu) != PQOS_RETVAL_OK) { exit_val = EXIT_FAILURE; printf("CAT reset failed!\n"); } else printf("CAT reset successful\n"); goto allocation_exit; } if (sel_show_allocation_config) { /** * Show info about allocation config and exit */ alloc_print_config(cap_mon, cap_l3ca, sock_count, sockets, p_cpu); goto allocation_exit; } if (sel_allocation_profile != NULL) { if (profile_l3ca_apply(sel_allocation_profile, cap_l3ca) != 0) { exit_val = EXIT_FAILURE; goto error_exit_2; } } switch (alloc_apply(cap_l3ca, sock_count, sockets)) { case 0: /* nothing to apply */ break; case 1: /* new allocation config applied and all is good */ goto allocation_exit; break; case -1: /* something went wrong */ default: exit_val = EXIT_FAILURE; goto error_exit_2; break; } /** * Just monitoring option left on the table now */ if (cap_mon == NULL) { printf("Monitoring capability not detected!\n"); exit_val = EXIT_FAILURE; goto error_exit_2; } if (monitor_setup(p_cpu, cap_mon) != 0) { exit_val = EXIT_FAILURE; goto error_exit_2; } monitor_loop(p_cap); monitor_stop(); allocation_exit: error_exit_2: ret = pqos_fini(); ASSERT(ret == PQOS_RETVAL_OK); if (ret != PQOS_RETVAL_OK) printf("Error shutting down PQoS library!\n"); error_exit_1: monitor_cleanup(); /** * Close file descriptor for message log */ if (cfg.fd_log > 0 && cfg.fd_log != STDOUT_FILENO) close(cfg.fd_log); /** * Free allocated memory */ if (sel_allocation_profile != NULL) free(sel_allocation_profile); if (sel_log_file != NULL) free(sel_log_file); if (sel_config_file != NULL) free(sel_config_file); return exit_val; }
/** * @brief Selects allocation profile from internal DB * * @param arg string passed to -c command line option */ static void selfn_allocation_select(const char *arg) { selfn_strdup(&sel_allocation_profile, arg); }
/** * @brief Selects log file * * @param arg string passed to -l command line option */ static void selfn_log_file(const char *arg) { selfn_strdup(&sel_log_file, arg); }