|
Packit |
bcb633 |
/*
|
|
Packit |
bcb633 |
* BSD LICENSE
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* Copyright(c) 2014-2018 Intel Corporation. All rights reserved.
|
|
Packit |
bcb633 |
* All rights reserved.
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* Redistribution and use in source and binary forms, with or without
|
|
Packit |
bcb633 |
* modification, are permitted provided that the following conditions
|
|
Packit |
bcb633 |
* are met:
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* * Redistributions of source code must retain the above copyright
|
|
Packit |
bcb633 |
* notice, this list of conditions and the following disclaimer.
|
|
Packit |
bcb633 |
* * Redistributions in binary form must reproduce the above copyright
|
|
Packit |
bcb633 |
* notice, this list of conditions and the following disclaimer in
|
|
Packit |
bcb633 |
* the documentation and/or other materials provided with the
|
|
Packit |
bcb633 |
* distribution.
|
|
Packit |
bcb633 |
* * Neither the name of Intel Corporation nor the names of its
|
|
Packit |
bcb633 |
* contributors may be used to endorse or promote products derived
|
|
Packit |
bcb633 |
* from this software without specific prior written permission.
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
|
Packit |
bcb633 |
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
|
Packit |
bcb633 |
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
|
Packit |
bcb633 |
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
Packit |
bcb633 |
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
|
Packit |
bcb633 |
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
|
Packit |
bcb633 |
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
|
Packit |
bcb633 |
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
Packit |
bcb633 |
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
|
Packit |
bcb633 |
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
Packit |
bcb633 |
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Platform QoS sample LLC occupancy monitoring application
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
#include <stdio.h>
|
|
Packit |
bcb633 |
#include <stdlib.h>
|
|
Packit |
bcb633 |
#include <string.h>
|
|
Packit |
bcb633 |
#include <unistd.h>
|
|
Packit |
bcb633 |
#include <sys/types.h>
|
|
Packit |
bcb633 |
#include <sys/stat.h>
|
|
Packit |
bcb633 |
#include <signal.h>
|
|
Packit |
bcb633 |
#include "pqos.h"
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* Defines
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
#define PQOS_MAX_CORES 1024
|
|
Packit |
bcb633 |
#define PQOS_MAX_PIDS 16
|
|
Packit |
bcb633 |
#define PQOS_MAX_MON_EVENTS 1
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* Number of cores that are selected in config string
|
|
Packit |
bcb633 |
* for monitoring LLC occupancy
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static int sel_monitor_num = 0;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* The mask to tell which events to display
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static enum pqos_mon_event sel_events_max = (enum pqos_mon_event)0;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* Maintains a table of core, event, number of events that are
|
|
Packit |
bcb633 |
* selected in config string for monitoring
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static struct {
|
|
Packit |
bcb633 |
unsigned core;
|
|
Packit |
bcb633 |
struct pqos_mon_data *pgrp;
|
|
Packit |
bcb633 |
enum pqos_mon_event events;
|
|
Packit |
bcb633 |
} sel_monitor_core_tab[PQOS_MAX_CORES];
|
|
Packit |
bcb633 |
static struct pqos_mon_data *m_mon_grps[PQOS_MAX_CORES];
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* Maintains a table of process id, event, number of events that are selected
|
|
Packit |
bcb633 |
* in config string for monitoring LLC occupancy
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static struct {
|
|
Packit |
bcb633 |
pid_t pid;
|
|
Packit |
bcb633 |
struct pqos_mon_data *pgrp;
|
|
Packit |
bcb633 |
enum pqos_mon_event events;
|
|
Packit |
bcb633 |
} sel_monitor_pid_tab[PQOS_MAX_PIDS];
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* Maintains the number of process id's you want to track
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static int sel_process_num = 0;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* Flag to determine which library interface to use
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static enum pqos_interface interface = PQOS_INTER_MSR;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
static void stop_monitoring(void);
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief CTRL-C handler for infinite monitoring loop
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* @param [in] signo signal number
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static void __attribute__((noreturn)) monitoring_ctrlc(int signo)
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
printf("\nExiting[%d]...\n", signo);
|
|
Packit |
bcb633 |
stop_monitoring();
|
|
Packit |
bcb633 |
if (pqos_fini() != PQOS_RETVAL_OK) {
|
|
Packit |
bcb633 |
printf("Error shutting down PQoS library!\n");
|
|
Packit |
bcb633 |
exit(EXIT_FAILURE);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
exit(EXIT_SUCCESS);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Scale byte value up to KB
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* @param [in] bytes value to be scaled up
|
|
Packit |
bcb633 |
* @return scaled up value in KB's
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static inline double bytes_to_kb(const double bytes)
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
return bytes / 1024.0;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Scale byte value up to MB
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* @param [in] bytes value to be scaled up
|
|
Packit |
bcb633 |
* @return scaled up value in MB's
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static inline double bytes_to_mb(const double bytes)
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
return bytes / (1024.0 * 1024.0);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Check to determine if processes or cores are monitored
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* @return Process monitoring mode status
|
|
Packit |
bcb633 |
* @retval 0 monitoring cores
|
|
Packit |
bcb633 |
* @retval 1 monitoring processes
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static inline int process_mode(void)
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
return (sel_process_num <= 0) ? 0 : 1;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Verifies and translates monitoring config string into
|
|
Packit |
bcb633 |
* internal monitoring configuration.
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* @param [in] argc Number of arguments in input command
|
|
Packit |
bcb633 |
* @param [in] argv Input arguments for LLC occupancy monitoring
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static void
|
|
Packit |
bcb633 |
monitoring_get_input(int argc, char *argv[])
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
int num_args, num_opts = 1, i = 0, sel_pid = 0, help = 0;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
for (i = 0; i < argc; i++) {
|
|
Packit |
bcb633 |
if (!strcmp(argv[i], "-p")) {
|
|
Packit |
bcb633 |
sel_pid = 1;
|
|
Packit |
bcb633 |
num_opts++;
|
|
Packit |
bcb633 |
} else if (!strcmp(argv[i], "-I")) {
|
|
Packit |
bcb633 |
interface = PQOS_INTER_OS;
|
|
Packit |
bcb633 |
num_opts++;
|
|
Packit |
bcb633 |
} else if (!strcmp(argv[i], "-H") || !strcmp(argv[i], "-h")) {
|
|
Packit |
bcb633 |
help = 1;
|
|
Packit |
bcb633 |
num_opts++;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
/* Ensure OS interface selected if monitoring tasks */
|
|
Packit |
bcb633 |
if (sel_pid && interface == PQOS_INTER_MSR) {
|
|
Packit |
bcb633 |
printf("Error: PID monitoring requires OS interface "
|
|
Packit |
bcb633 |
"selection!\nPlease use the -I option.\n");
|
|
Packit |
bcb633 |
help = 1;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
num_args = (argc - num_opts);
|
|
Packit |
bcb633 |
if (help) {
|
|
Packit |
bcb633 |
printf("Usage: %s [<core1> <core2> <core3> ...]\n"
|
|
Packit |
bcb633 |
" %s -I -p [<pid1> <pid2> <pid3> ...]\n",
|
|
Packit |
bcb633 |
argv[0], argv[0]);
|
|
Packit |
bcb633 |
printf("Eg : %s 1 2 6\n "
|
|
Packit |
bcb633 |
"%s -I -p 3564 7638 356\n"
|
|
Packit |
bcb633 |
"Notes:\n "
|
|
Packit |
bcb633 |
"-h help\n "
|
|
Packit |
bcb633 |
"-I select library OS interface\n "
|
|
Packit |
bcb633 |
"-p select process ID's to monitor LLC occupancy"
|
|
Packit |
bcb633 |
"\n\n", argv[0], argv[0]);
|
|
Packit |
bcb633 |
exit(EXIT_SUCCESS);
|
|
Packit |
bcb633 |
} else if (num_args == 0) {
|
|
Packit |
bcb633 |
sel_monitor_num = 0;
|
|
Packit |
bcb633 |
} else {
|
|
Packit |
bcb633 |
if (sel_pid) {
|
|
Packit |
bcb633 |
if (num_args > PQOS_MAX_PIDS)
|
|
Packit |
bcb633 |
num_args = PQOS_MAX_PIDS;
|
|
Packit |
bcb633 |
for (i = 0; i < num_args; i++) {
|
|
Packit |
bcb633 |
m_mon_grps[i] = malloc(sizeof(**m_mon_grps));
|
|
Packit |
bcb633 |
sel_monitor_pid_tab[i].pgrp = m_mon_grps[i];
|
|
Packit |
bcb633 |
sel_monitor_pid_tab[i].pid =
|
|
Packit |
bcb633 |
(unsigned) atoi(argv[num_opts + i]);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
sel_process_num = (int) num_args;
|
|
Packit |
bcb633 |
} else {
|
|
Packit |
bcb633 |
if (num_args > PQOS_MAX_CORES)
|
|
Packit |
bcb633 |
num_args = PQOS_MAX_CORES;
|
|
Packit |
bcb633 |
for (i = 0; i < num_args; i++) {
|
|
Packit |
bcb633 |
m_mon_grps[i] = malloc(sizeof(**m_mon_grps));
|
|
Packit |
bcb633 |
sel_monitor_core_tab[i].pgrp = m_mon_grps[i];
|
|
Packit |
bcb633 |
sel_monitor_core_tab[i].core =
|
|
Packit |
bcb633 |
(unsigned) atoi(argv[num_opts + i]);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
sel_monitor_num = (int) num_args;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Starts monitoring on selected cores/PIDs
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* @param [in] cpu_info cpu information structure
|
|
Packit |
bcb633 |
* @param [in] cap_mon monitoring capabilities structure
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
* @return Operation status
|
|
Packit |
bcb633 |
* @retval 0 OK
|
|
Packit |
bcb633 |
* @retval -1 error
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static int
|
|
Packit |
bcb633 |
setup_monitoring(const struct pqos_cpuinfo *cpu_info,
|
|
Packit |
bcb633 |
const struct pqos_capability * const cap_mon)
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
unsigned i;
|
|
Packit |
bcb633 |
const enum pqos_mon_event perf_events = (enum pqos_mon_event)
|
|
Packit |
bcb633 |
(PQOS_PERF_EVENT_IPC | PQOS_PERF_EVENT_LLC_MISS);
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
for (i = 0; (unsigned)i < cap_mon->u.mon->num_events; i++)
|
|
Packit |
bcb633 |
sel_events_max |= (cap_mon->u.mon->events[i].type);
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/* Remove perf events IPC and LLC MISSES */
|
|
Packit |
bcb633 |
sel_events_max &= ~perf_events;
|
|
Packit |
bcb633 |
if (sel_monitor_num == 0 && sel_process_num == 0) {
|
|
Packit |
bcb633 |
for (i = 0; i < cpu_info->num_cores; i++) {
|
|
Packit |
bcb633 |
unsigned lcore = cpu_info->cores[i].lcore;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
sel_monitor_core_tab[sel_monitor_num].core = lcore;
|
|
Packit |
bcb633 |
sel_monitor_core_tab[sel_monitor_num].events =
|
|
Packit |
bcb633 |
sel_events_max;
|
|
Packit |
bcb633 |
m_mon_grps[sel_monitor_num] =
|
|
Packit |
bcb633 |
malloc(sizeof(**m_mon_grps));
|
|
Packit |
bcb633 |
sel_monitor_core_tab[sel_monitor_num].pgrp =
|
|
Packit |
bcb633 |
m_mon_grps[sel_monitor_num];
|
|
Packit |
bcb633 |
sel_monitor_num++;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
if (!process_mode()) {
|
|
Packit |
bcb633 |
for (i = 0; i < (unsigned) sel_monitor_num; i++) {
|
|
Packit |
bcb633 |
unsigned lcore = sel_monitor_core_tab[i].core;
|
|
Packit |
bcb633 |
int ret;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
ret = pqos_mon_start(1, &lcore,
|
|
Packit |
bcb633 |
sel_events_max,
|
|
Packit |
bcb633 |
NULL,
|
|
Packit |
bcb633 |
sel_monitor_core_tab[i].pgrp);
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK) {
|
|
Packit |
bcb633 |
printf("Monitoring start error on core %u,"
|
|
Packit |
bcb633 |
"status %d\n", lcore, ret);
|
|
Packit |
bcb633 |
return ret;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
} else {
|
|
Packit |
bcb633 |
for (i = 0; i < (unsigned) sel_process_num; i++) {
|
|
Packit |
bcb633 |
pid_t pid = sel_monitor_pid_tab[i].pid;
|
|
Packit |
bcb633 |
int ret;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
ret = pqos_mon_start_pids(1, &pid,
|
|
Packit |
bcb633 |
PQOS_MON_EVENT_L3_OCCUP,
|
|
Packit |
bcb633 |
NULL,
|
|
Packit |
bcb633 |
sel_monitor_pid_tab[i].pgrp);
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK) {
|
|
Packit |
bcb633 |
printf("Monitoring start error on pid %u,"
|
|
Packit |
bcb633 |
"status %d\n", pid, ret);
|
|
Packit |
bcb633 |
return ret;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
return PQOS_RETVAL_OK;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Stops monitoring on selected cores
|
|
Packit |
bcb633 |
*
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static void stop_monitoring(void)
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
unsigned i, mon_number = 0;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
if (!process_mode())
|
|
Packit |
bcb633 |
mon_number = (unsigned) sel_monitor_num;
|
|
Packit |
bcb633 |
else
|
|
Packit |
bcb633 |
mon_number = (unsigned) sel_process_num;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
for (i = 0; i < mon_number; i++) {
|
|
Packit |
bcb633 |
int ret;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
ret = pqos_mon_stop(m_mon_grps[i]);
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK)
|
|
Packit |
bcb633 |
printf("Monitoring stop error!\n");
|
|
Packit |
bcb633 |
free(m_mon_grps[i]);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/**
|
|
Packit |
bcb633 |
* @brief Reads monitoring event data
|
|
Packit |
bcb633 |
*/
|
|
Packit |
bcb633 |
static void monitoring_loop(void)
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
unsigned mon_number = 0;
|
|
Packit |
bcb633 |
int ret = PQOS_RETVAL_OK;
|
|
Packit |
bcb633 |
int i = 0;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
if (signal(SIGINT, monitoring_ctrlc) == SIG_ERR)
|
|
Packit |
bcb633 |
printf("Failed to catch SIGINT!\n");
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
if (!process_mode())
|
|
Packit |
bcb633 |
mon_number = (unsigned) sel_monitor_num;
|
|
Packit |
bcb633 |
else
|
|
Packit |
bcb633 |
mon_number = (unsigned) sel_process_num;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
while (1) {
|
|
Packit |
bcb633 |
ret = pqos_mon_poll(m_mon_grps, (unsigned)mon_number);
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK) {
|
|
Packit |
bcb633 |
printf("Failed to poll monitoring data!\n");
|
|
Packit |
bcb633 |
return;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
if (!process_mode()) {
|
|
Packit |
bcb633 |
printf(" CORE RMID LLC[KB]"
|
|
Packit |
bcb633 |
" MBL[MB] MBR[MB]\n");
|
|
Packit |
bcb633 |
for (i = 0; i < sel_monitor_num; i++) {
|
|
Packit |
bcb633 |
const struct pqos_event_values *pv =
|
|
Packit |
bcb633 |
&m_mon_grps[i]->values;
|
|
Packit |
bcb633 |
double llc = bytes_to_kb(pv->llc);
|
|
Packit |
bcb633 |
double mbr = bytes_to_mb(pv->mbm_remote_delta);
|
|
Packit |
bcb633 |
double mbl = bytes_to_mb(pv->mbm_local_delta);
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
if (interface == PQOS_INTER_OS)
|
|
Packit |
bcb633 |
printf("%8u %s %10.1f %10.1f %10.1f\n",
|
|
Packit |
bcb633 |
m_mon_grps[i]->cores[0],
|
|
Packit |
bcb633 |
" N/A", llc, mbl, mbr);
|
|
Packit |
bcb633 |
else
|
|
Packit |
bcb633 |
printf("%8u %8u %10.1f %10.1f %10.1f\n",
|
|
Packit |
bcb633 |
m_mon_grps[i]->cores[0],
|
|
Packit |
bcb633 |
m_mon_grps[i]->poll_ctx[0].rmid,
|
|
Packit |
bcb633 |
llc, mbl, mbr);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
} else {
|
|
Packit |
bcb633 |
printf("PID LLC[KB]\n");
|
|
Packit |
bcb633 |
for (i = 0; i < sel_process_num; i++) {
|
|
Packit |
bcb633 |
const struct pqos_event_values *pv =
|
|
Packit |
bcb633 |
&m_mon_grps[i]->values;
|
|
Packit |
bcb633 |
double llc = bytes_to_kb(pv->llc);
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
printf("%6d %10.1f\n",
|
|
Packit |
bcb633 |
m_mon_grps[i]->pids[0], llc);
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
printf("\nPress Enter to continue or Ctrl+c to exit");
|
|
Packit |
bcb633 |
if (getchar() != '\n')
|
|
Packit |
bcb633 |
break;
|
|
Packit |
bcb633 |
printf("\e[1;1H\e[2J");
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
int main(int argc, char *argv[])
|
|
Packit |
bcb633 |
{
|
|
Packit |
bcb633 |
struct pqos_config config;
|
|
Packit |
bcb633 |
const struct pqos_cpuinfo *p_cpu = NULL;
|
|
Packit |
bcb633 |
const struct pqos_cap *p_cap = NULL;
|
|
Packit |
bcb633 |
int ret, exit_val = EXIT_SUCCESS;
|
|
Packit |
bcb633 |
const struct pqos_capability *cap_mon = NULL;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/* Get input from user */
|
|
Packit |
bcb633 |
monitoring_get_input(argc, argv);
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
memset(&config, 0, sizeof(config));
|
|
Packit |
bcb633 |
config.fd_log = STDOUT_FILENO;
|
|
Packit |
bcb633 |
config.verbose = 0;
|
|
Packit |
bcb633 |
config.interface = interface;
|
|
Packit |
bcb633 |
|
|
Packit |
bcb633 |
/* PQoS Initialization - Check and initialize CAT and CMT capability */
|
|
Packit |
bcb633 |
ret = pqos_init(&config);
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK) {
|
|
Packit |
bcb633 |
printf("Error initializing PQoS library!\n");
|
|
Packit |
bcb633 |
exit_val = EXIT_FAILURE;
|
|
Packit |
bcb633 |
goto error_exit;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
/* Get CMT capability and CPU info pointer */
|
|
Packit |
bcb633 |
ret = pqos_cap_get(&p_cap, &p_cpu);
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK) {
|
|
Packit |
bcb633 |
printf("Error retrieving PQoS capabilities!\n");
|
|
Packit |
bcb633 |
exit_val = EXIT_FAILURE;
|
|
Packit |
bcb633 |
goto error_exit;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
(void) pqos_cap_get_type(p_cap, PQOS_CAP_TYPE_MON, &cap_mon);
|
|
Packit |
bcb633 |
/* Setup the monitoring resources */
|
|
Packit |
bcb633 |
ret = setup_monitoring(p_cpu, cap_mon);
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK) {
|
|
Packit |
bcb633 |
printf("Error Setting up monitoring!\n");
|
|
Packit |
bcb633 |
exit_val = EXIT_FAILURE;
|
|
Packit |
bcb633 |
goto error_exit;
|
|
Packit |
bcb633 |
}
|
|
Packit |
bcb633 |
/* Start Monitoring */
|
|
Packit |
bcb633 |
monitoring_loop();
|
|
Packit |
bcb633 |
/* Stop Monitoring */
|
|
Packit |
bcb633 |
stop_monitoring();
|
|
Packit |
bcb633 |
error_exit:
|
|
Packit |
bcb633 |
ret = pqos_fini();
|
|
Packit |
bcb633 |
if (ret != PQOS_RETVAL_OK)
|
|
Packit |
bcb633 |
printf("Error shutting down PQoS library!\n");
|
|
Packit |
bcb633 |
return exit_val;
|
|
Packit |
bcb633 |
}
|