spdk_top: add scheduler pop-up details window
Adds global scheduler pop-up details window displaying current scheduler name, scheduler period and governor name. Modify help window to include newly added scheduler pop-up. Mofdify parameter "string" of print_left() function to take const char* instead of char* - the string is not modified in that function. Signed-off-by: Krzysztof Karas <krzysztof.karas@intel.com> Change-Id: Icc0bdf55f716e5eed71a472f2c77c47ee2fc1b3d Reviewed-on: https://review.spdk.io/gerrit/c/spdk/spdk/+/6459 Tested-by: SPDK CI Jenkins <sys_sgci@intel.com> Community-CI: Mellanox Build Bot Reviewed-by: Tomasz Zawadzki <tomasz.zawadzki@intel.com> Reviewed-by: Jim Harris <james.r.harris@intel.com>
This commit is contained in:
parent
5ba9f929a6
commit
20a3f67524
@ -76,7 +76,10 @@
|
||||
#define POLLER_WIN_FIRST_COL 14
|
||||
#define FIRST_DATA_ROW 7
|
||||
#define HELP_WIN_WIDTH 88
|
||||
#define HELP_WIN_HEIGHT 22
|
||||
#define HELP_WIN_HEIGHT 24
|
||||
#define SCHEDULER_WIN_HEIGHT 7
|
||||
#define SCHEDULER_WIN_FIRST_COL 2
|
||||
#define MAX_SCHEDULER_PERIOD_STR_LEN 10
|
||||
|
||||
enum tabs {
|
||||
THREADS_TAB,
|
||||
@ -247,6 +250,7 @@ struct rpc_core_info {
|
||||
|
||||
struct rpc_scheduler {
|
||||
char *scheduler_name;
|
||||
char *governor_name;
|
||||
uint64_t scheduler_period;
|
||||
};
|
||||
|
||||
@ -540,10 +544,12 @@ static void
|
||||
free_rpc_scheduler(struct rpc_scheduler *req)
|
||||
{
|
||||
free(req->scheduler_name);
|
||||
free(req->governor_name);
|
||||
}
|
||||
|
||||
static const struct spdk_json_object_decoder rpc_scheduler_decoders[] = {
|
||||
{"scheduler_name", offsetof(struct rpc_scheduler, scheduler_name), spdk_json_decode_string, true},
|
||||
{"governor_name", offsetof(struct rpc_scheduler, governor_name), spdk_json_decode_string, true},
|
||||
{"scheduler_period", offsetof(struct rpc_scheduler, scheduler_period), spdk_json_decode_uint64},
|
||||
};
|
||||
|
||||
@ -1771,7 +1777,7 @@ print_in_middle(WINDOW *win, int starty, int startx, int width, char *string, ch
|
||||
}
|
||||
|
||||
static void
|
||||
print_left(WINDOW *win, int starty, int startx, int width, char *string, chtype color)
|
||||
print_left(WINDOW *win, int starty, int startx, int width, const char *string, chtype color)
|
||||
{
|
||||
wattron(win, color);
|
||||
mvwprintw(win, starty, startx, "%s", string);
|
||||
@ -2835,6 +2841,124 @@ show_poller(uint8_t current_page, uint8_t active_tab)
|
||||
delwin(poller_win);
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
get_max_scheduler_win_width(uint8_t sched_name_label_len, uint8_t sched_period_label_len,
|
||||
uint8_t gov_name_label_len)
|
||||
{
|
||||
uint8_t window_borders = 4;
|
||||
uint64_t s_name, s_period, g_name, max_name_len;
|
||||
char scheduler_period[MAX_SCHEDULER_PERIOD_STR_LEN];
|
||||
|
||||
snprintf(scheduler_period, MAX_SCHEDULER_PERIOD_STR_LEN, "%" PRIu64,
|
||||
g_scheduler_info.scheduler_period);
|
||||
|
||||
s_name = strlen(g_scheduler_info.scheduler_name) + sched_name_label_len;
|
||||
if (g_scheduler_info.governor_name != NULL) {
|
||||
g_name = strlen(g_scheduler_info.governor_name) + gov_name_label_len;
|
||||
} else {
|
||||
g_name = strlen("none") + gov_name_label_len;
|
||||
}
|
||||
s_period = strlen(scheduler_period) + sched_period_label_len;
|
||||
|
||||
max_name_len = spdk_max(s_name, g_name);
|
||||
/* This function relies on the fact that scheduler/governor
|
||||
* names will not change during runtime. Otherwise the scheduler
|
||||
* pop-up would need dynamic resizing. */
|
||||
|
||||
return spdk_max(max_name_len, s_period) + window_borders;
|
||||
}
|
||||
|
||||
static void
|
||||
draw_scheduler_popup(WINDOW *scheduler_win, uint64_t scheduler_win_width, uint8_t active_tab,
|
||||
uint8_t current_page, const char *scheduler_name_label,
|
||||
const char *scheduler_period_label, const char *governor_name_label)
|
||||
{
|
||||
char scheduler_period[MAX_SCHEDULER_PERIOD_STR_LEN];
|
||||
|
||||
box(scheduler_win, 0, 0);
|
||||
|
||||
print_left(scheduler_win, 1, SCHEDULER_WIN_FIRST_COL, scheduler_win_width, scheduler_name_label,
|
||||
COLOR_PAIR(5));
|
||||
print_left(scheduler_win, 1, SCHEDULER_WIN_FIRST_COL + strlen(scheduler_name_label),
|
||||
scheduler_win_width,
|
||||
g_scheduler_info.scheduler_name, COLOR_PAIR(3));
|
||||
|
||||
mvwhline(scheduler_win, 2, 1, ACS_HLINE, scheduler_win_width - 2);
|
||||
mvwaddch(scheduler_win, 2, scheduler_win_width, ACS_RTEE);
|
||||
|
||||
print_left(scheduler_win, 3, SCHEDULER_WIN_FIRST_COL, scheduler_win_width, scheduler_period_label,
|
||||
COLOR_PAIR(5));
|
||||
snprintf(scheduler_period, MAX_SCHEDULER_PERIOD_STR_LEN, "%" PRIu64,
|
||||
g_scheduler_info.scheduler_period);
|
||||
mvwprintw(scheduler_win, 3, SCHEDULER_WIN_FIRST_COL + strlen(scheduler_period_label), "%s",
|
||||
scheduler_period);
|
||||
|
||||
mvwhline(scheduler_win, 4, 1, ACS_HLINE, scheduler_win_width - 2);
|
||||
mvwaddch(scheduler_win, 4, scheduler_win_width, ACS_RTEE);
|
||||
|
||||
print_left(scheduler_win, 5, SCHEDULER_WIN_FIRST_COL, scheduler_win_width, governor_name_label,
|
||||
COLOR_PAIR(5));
|
||||
|
||||
if (g_scheduler_info.governor_name != NULL) {
|
||||
mvwprintw(scheduler_win, 5, SCHEDULER_WIN_FIRST_COL + strlen(governor_name_label), "%s",
|
||||
g_scheduler_info.governor_name);
|
||||
} else {
|
||||
mvwprintw(scheduler_win, 5, SCHEDULER_WIN_FIRST_COL + strlen(governor_name_label), "%s", "none");
|
||||
}
|
||||
|
||||
refresh_tab(active_tab, current_page);
|
||||
wnoutrefresh(scheduler_win);
|
||||
refresh();
|
||||
}
|
||||
|
||||
static void
|
||||
show_scheduler(uint8_t active_tab, uint8_t current_page)
|
||||
{
|
||||
PANEL *scheduler_panel;
|
||||
WINDOW *scheduler_win;
|
||||
uint64_t scheduler_win_width;
|
||||
bool stop_loop = false;
|
||||
int c;
|
||||
const char *scheduler_name_label = "Scheduler: ";
|
||||
const char *scheduler_period_label = "Period [us]: ";
|
||||
const char *governor_name_label = "Governor: ";
|
||||
|
||||
pthread_mutex_lock(&g_thread_lock);
|
||||
scheduler_win_width = get_max_scheduler_win_width(strlen(scheduler_name_label),
|
||||
strlen(scheduler_period_label),
|
||||
strlen(governor_name_label));
|
||||
|
||||
scheduler_win = newwin(SCHEDULER_WIN_HEIGHT, scheduler_win_width,
|
||||
get_position_for_window(SCHEDULER_WIN_HEIGHT, g_max_row),
|
||||
get_position_for_window(scheduler_win_width, g_max_col));
|
||||
|
||||
keypad(scheduler_win, TRUE);
|
||||
scheduler_panel = new_panel(scheduler_win);
|
||||
|
||||
top_panel(scheduler_panel);
|
||||
update_panels();
|
||||
doupdate();
|
||||
|
||||
draw_scheduler_popup(scheduler_win, scheduler_win_width, active_tab, current_page,
|
||||
scheduler_name_label, scheduler_period_label, governor_name_label);
|
||||
pthread_mutex_unlock(&g_thread_lock);
|
||||
|
||||
while (!stop_loop) {
|
||||
c = wgetch(scheduler_win);
|
||||
|
||||
switch (c) {
|
||||
case 27: /* ESC */
|
||||
stop_loop = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
del_panel(scheduler_panel);
|
||||
delwin(scheduler_win);
|
||||
}
|
||||
|
||||
static void *
|
||||
data_thread_routine(void *arg)
|
||||
{
|
||||
@ -2942,6 +3066,8 @@ help_window_display(void)
|
||||
"[t] Total/Interval - switch to display data measured from the start of SPDK", COLOR_PAIR(10));
|
||||
print_left(help_win, ++row, desc_second_row_col, HELP_WIN_WIDTH,
|
||||
"application or last refresh", COLOR_PAIR(10));
|
||||
print_left(help_win, ++row, col, HELP_WIN_WIDTH,
|
||||
"[g] Scheduler pop-up - display current scheduler information", COLOR_PAIR(10));
|
||||
print_left(help_win, ++row, col, HELP_WIN_WIDTH, "[h] Help - show this help window",
|
||||
COLOR_PAIR(10));
|
||||
|
||||
@ -3079,6 +3205,9 @@ show_stats(pthread_t *data_thread)
|
||||
case 't':
|
||||
g_interval_data = !g_interval_data;
|
||||
break;
|
||||
case 'g':
|
||||
show_scheduler(active_tab, current_page);
|
||||
break;
|
||||
case KEY_NPAGE: /* PgDown */
|
||||
if (current_page + 1 < max_pages) {
|
||||
current_page++;
|
||||
|
Loading…
Reference in New Issue
Block a user