Blame ui/ui.c

Packit 9eaa09
Packit 9eaa09
#include <string.h>
Packit 9eaa09
#include "ui.h"
Packit 9eaa09
Packit 9eaa09
Packit 9eaa09
GList *all_cpus = NULL;
Packit 9eaa09
GList *all_irqs = NULL;
Packit 9eaa09
Packit 9eaa09
char *IRQ_CLASS_TO_STR[] = {
Packit 9eaa09
			"Other",
Packit 9eaa09
			"Legacy",
Packit 9eaa09
			"SCSI",
Packit 9eaa09
			"Video",
Packit 9eaa09
			"Ethernet",
Packit 9eaa09
			"Gigabit Ethernet",
Packit 9eaa09
			"10-Gigabit Ethernet,"
Packit 9eaa09
			"Virt Event"};
Packit 9eaa09
Packit 9eaa09
void show_frame()
Packit 9eaa09
{
Packit 9eaa09
	int i;
Packit 9eaa09
	attrset(COLOR_PAIR(4));
Packit 9eaa09
	char top[COLS];
Packit 9eaa09
	top[0] = '\0';
Packit 9eaa09
	while(strlen(top) != (size_t)COLS - 1) {
Packit 9eaa09
		snprintf(top + strlen(top), COLS - strlen(top), " ");
Packit 9eaa09
	}
Packit 9eaa09
	mvprintw(0, 0, top);
Packit 9eaa09
	for(i = 0; i < LINES; i++) {
Packit 9eaa09
		mvprintw(i, 0, " ");
Packit 9eaa09
		mvprintw(i, COLS - 1, " ");
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void show_footer()
Packit 9eaa09
{
Packit 9eaa09
	char footer[COLS];
Packit 9eaa09
	snprintf(footer, COLS - 1,
Packit 9eaa09
		" q (QUIT)   F3 (TREE)   F4 (SETTINGS)   F5 (SETUP IRQS)");
Packit 9eaa09
	while(strlen(footer) != (size_t)COLS - 1) {
Packit 9eaa09
		snprintf(footer + strlen(footer), COLS - strlen(footer), " ");
Packit 9eaa09
	}
Packit 9eaa09
	attrset(COLOR_PAIR(4));
Packit 9eaa09
	mvprintw(LINES - 1, 0, footer);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
char * check_control_in_sleep_input(int max_len, int column_offest, int line_offset)
Packit 9eaa09
{
Packit 9eaa09
	char *input_to = malloc(max_len * sizeof(char));
Packit 9eaa09
	int iteration = 0;
Packit 9eaa09
	while(iteration < max_len) {
Packit 9eaa09
		int new = getch();
Packit 9eaa09
		switch(new) {
Packit 9eaa09
		case ERR:
Packit 9eaa09
			/* No input is ready for nonblocking getch() call */
Packit 9eaa09
			break;
Packit 9eaa09
		case '\r':
Packit 9eaa09
		case '\n':
Packit 9eaa09
			input_to[iteration] = '\0';
Packit 9eaa09
			return input_to;
Packit 9eaa09
		case 'q':
Packit 9eaa09
			close_window(0);
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_BACKSPACE:
Packit 9eaa09
			if(iteration > 0) {
Packit 9eaa09
				attrset(COLOR_PAIR(5));
Packit 9eaa09
				iteration--;
Packit 9eaa09
				mvaddch(line_offset, column_offest + iteration, ' ');
Packit 9eaa09
			}
Packit 9eaa09
			move(line_offset, column_offest + iteration);
Packit 9eaa09
			attrset(COLOR_PAIR(6));
Packit 9eaa09
			break;
Packit 9eaa09
		case 27:
Packit 9eaa09
			return NULL;
Packit 9eaa09
		default:
Packit 9eaa09
			input_to[iteration] = new;
Packit 9eaa09
			iteration++;
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
	}
Packit 9eaa09
	return input_to;
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
int get_valid_sleep_input(int column_offest)
Packit 9eaa09
{
Packit 9eaa09
	uint64_t new_sleep = setup.sleep;
Packit 9eaa09
	while(1) {
Packit 9eaa09
		attrset(COLOR_PAIR(5));
Packit 9eaa09
		mvprintw(2, column_offest, "			");
Packit 9eaa09
		attrset(COLOR_PAIR(6));
Packit 9eaa09
		refresh();
Packit 9eaa09
		move(2, column_offest);
Packit 9eaa09
		curs_set(1);
Packit 9eaa09
		char *input = check_control_in_sleep_input(20, column_offest, 3);
Packit 9eaa09
		if(input == NULL) {
Packit 9eaa09
			curs_set(0);
Packit 9eaa09
			attrset(COLOR_PAIR(1));
Packit 9eaa09
			mvprintw(2, column_offest, "%lu			", new_sleep);
Packit 9eaa09
			move(LINES, COLS);
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
		attrset(COLOR_PAIR(1));
Packit 9eaa09
		mvprintw(LINES - 2, 1, "							");
Packit 9eaa09
		curs_set(0);
Packit 9eaa09
		refresh();
Packit 9eaa09
		char *error;
Packit 9eaa09
		new_sleep = strtol(input, &error, 10);
Packit 9eaa09
		if((*error == '\0') && (new_sleep >= 1)) {
Packit 9eaa09
			break;
Packit 9eaa09
		} else {
Packit 9eaa09
			new_sleep = setup.sleep;
Packit 9eaa09
			attrset(COLOR_PAIR(4));
Packit 9eaa09
			mvprintw(LINES - 2, 1,
Packit 9eaa09
				"Invalid input: %s								",
Packit 9eaa09
				input);
Packit 9eaa09
			refresh();
Packit 9eaa09
		}
Packit 9eaa09
	}
Packit 9eaa09
Packit 9eaa09
	attrset(COLOR_PAIR(1));
Packit 9eaa09
	mvprintw(2, column_offest, "%lu				", new_sleep);
Packit 9eaa09
Packit 9eaa09
	return new_sleep;
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void get_banned_cpu(int *cpu, void *data __attribute__((unused)))
Packit 9eaa09
{
Packit 9eaa09
	cpu_ban_t *new = malloc(sizeof(cpu_ban_t));
Packit 9eaa09
	new->number = *cpu;
Packit 9eaa09
	new->is_banned = 1;
Packit 9eaa09
	all_cpus = g_list_append(all_cpus, new);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void print_cpu_line(cpu_ban_t *cpu, void *data)
Packit 9eaa09
{
Packit 9eaa09
	int *line_offset = data;
Packit 9eaa09
	if(cpu->is_banned) {
Packit 9eaa09
		attrset(COLOR_PAIR(10));
Packit 9eaa09
	} else {
Packit 9eaa09
		attrset(COLOR_PAIR(9));
Packit 9eaa09
	}
Packit 9eaa09
	mvprintw(*line_offset, 3, "CPU %d", cpu->number);
Packit 9eaa09
	mvprintw(*line_offset, 19, "%s", cpu->is_banned ?
Packit 9eaa09
			"YES	" :
Packit 9eaa09
			"NO	 ");
Packit 9eaa09
	(*line_offset)++;
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void print_all_cpus()
Packit 9eaa09
{
Packit 9eaa09
	if(all_cpus == NULL) {
Packit 9eaa09
		for_each_node(tree, get_cpu, NULL);
Packit 9eaa09
		for_each_int(setup.banned_cpus, get_banned_cpu, NULL);
Packit 9eaa09
		all_cpus = g_list_sort(all_cpus, sort_all_cpus);
Packit 9eaa09
	}
Packit 9eaa09
	int *line = malloc(sizeof(int));
Packit 9eaa09
	*line = 6;
Packit 9eaa09
	attrset(COLOR_PAIR(2));
Packit 9eaa09
	mvprintw(4, 3, "NUMBER          IS BANNED");
Packit 9eaa09
	for_each_cpu(all_cpus, print_cpu_line, line);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void add_banned_cpu(int *banned_cpu, void *data)
Packit 9eaa09
{
Packit 9eaa09
	snprintf(data + strlen(data), 1024 - strlen(data), "%d, ", *banned_cpu);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void display_banned_cpus()
Packit 9eaa09
{
Packit 9eaa09
	char banned_cpus[1024] = "Banned CPU numbers: \0";
Packit 9eaa09
	if(g_list_length(setup.banned_cpus) > 0) {
Packit 9eaa09
		for_each_int(setup.banned_cpus, add_banned_cpu, banned_cpus);
Packit 9eaa09
		snprintf(banned_cpus + strlen(banned_cpus) - 2,
Packit 9eaa09
				1024 - strlen(banned_cpus), "\n");
Packit 9eaa09
	} else {
Packit 9eaa09
		snprintf(banned_cpus + strlen(banned_cpus),
Packit 9eaa09
				1024 - strlen(banned_cpus), "None\n");
Packit 9eaa09
	}
Packit 9eaa09
	attrset(COLOR_PAIR(0));
Packit 9eaa09
	mvprintw(2, 5, "%s\n", banned_cpus);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
int toggle_cpu(GList *cpu_list, int cpu_number)
Packit 9eaa09
{
Packit 9eaa09
	GList *entry = g_list_first(cpu_list);
Packit 9eaa09
	cpu_ban_t *entry_data = (cpu_ban_t *)(entry->data);
Packit 9eaa09
	while(entry_data->number != cpu_number) {
Packit 9eaa09
		entry = g_list_next(entry);
Packit 9eaa09
		entry_data = (cpu_ban_t *)(entry->data);
Packit 9eaa09
	}
Packit 9eaa09
	if(((cpu_ban_t *)(entry->data))->is_banned) {
Packit 9eaa09
		((cpu_ban_t *)(entry->data))->is_banned = 0;
Packit 9eaa09
	} else {
Packit 9eaa09
		((cpu_ban_t *)(entry->data))->is_banned = 1;
Packit 9eaa09
	}
Packit 9eaa09
	return ((cpu_ban_t *)(entry->data))->is_banned;
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void get_new_cpu_ban_values(cpu_ban_t *cpu, void *data)
Packit 9eaa09
{
Packit 9eaa09
	char *mask_data = (char *)data;
Packit 9eaa09
	if(cpu->is_banned) {
Packit 9eaa09
		snprintf(mask_data + strlen(mask_data), 1024 - strlen(mask_data),
Packit 9eaa09
				"%d,", cpu->number);
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void get_cpu(cpu_node_t *node, void *data __attribute__((unused)))
Packit 9eaa09
{
Packit 9eaa09
	if(node->type == OBJ_TYPE_CPU) {
Packit 9eaa09
		cpu_ban_t *new = malloc(sizeof(cpu_ban_t));
Packit 9eaa09
		new->number = node->number;
Packit 9eaa09
		new->is_banned = 0;
Packit 9eaa09
		all_cpus = g_list_append(all_cpus, new);
Packit 9eaa09
	}
Packit 9eaa09
	if(g_list_length(node->children) > 0) {
Packit 9eaa09
		for_each_node(node->children, get_cpu, NULL);
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void handle_cpu_banning()
Packit 9eaa09
{
Packit 9eaa09
	GList *tmp = g_list_copy_deep(all_cpus, copy_cpu_ban, NULL);
Packit 9eaa09
	attrset(COLOR_PAIR(5));
Packit 9eaa09
	mvprintw(LINES - 3, 1, "Move up and down the list, toggle ban with Enter.");
Packit 9eaa09
	mvprintw(LINES - 2, 1,
Packit 9eaa09
			"Press ESC for discarding and <S> for saving the values.");
Packit 9eaa09
	move(6, 19);
Packit 9eaa09
	curs_set(1);
Packit 9eaa09
	refresh();
Packit 9eaa09
	size_t position = 5;
Packit 9eaa09
	char processing = 1;
Packit 9eaa09
	while(processing) {
Packit 9eaa09
		int direction = getch();
Packit 9eaa09
		switch(direction) {
Packit 9eaa09
		case KEY_UP:
Packit 9eaa09
			if(position > 6) {
Packit 9eaa09
				position--;
Packit 9eaa09
				move(position, 19);
Packit 9eaa09
			}
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_DOWN:
Packit 9eaa09
			if(position <= g_list_length(all_cpus) + 4) {
Packit 9eaa09
				position++;
Packit 9eaa09
				move(position, 19);
Packit 9eaa09
			}
Packit 9eaa09
			break;
Packit 9eaa09
		case '\n':
Packit 9eaa09
		case '\r': {
Packit 9eaa09
			attrset(COLOR_PAIR(3));
Packit 9eaa09
			int banned = toggle_cpu(tmp, position - 6);
Packit 9eaa09
			if(banned) {
Packit 9eaa09
				mvprintw(position, 19, "YES");
Packit 9eaa09
			} else {
Packit 9eaa09
				mvprintw(position, 19, "NO ");
Packit 9eaa09
			}
Packit 9eaa09
			move(position, 19);
Packit 9eaa09
			refresh();
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
		case 27:
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			curs_set(0);
Packit 9eaa09
			/* Forget the changes */
Packit 9eaa09
			tmp = g_list_copy_deep(all_cpus, copy_cpu_ban, NULL);
Packit 9eaa09
			print_all_cpus();
Packit 9eaa09
			attrset(COLOR_PAIR(0));
Packit 9eaa09
			mvprintw(LINES - 3, 1, "			\
Packit 9eaa09
														");
Packit 9eaa09
			attrset(COLOR_PAIR(5));
Packit 9eaa09
			mvprintw(LINES - 2, 1,
Packit 9eaa09
				"Press <S> for changing sleep setup, <C> for CPU ban setup.  ");
Packit 9eaa09
			move(LINES - 1, COLS - 1);
Packit 9eaa09
			refresh();
Packit 9eaa09
			break;
Packit 9eaa09
		case 's':
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			all_cpus = tmp;
Packit 9eaa09
			curs_set(0);
Packit 9eaa09
			print_all_cpus();
Packit 9eaa09
			attrset(COLOR_PAIR(0));
Packit 9eaa09
			mvprintw(LINES - 3, 1, "			\
Packit 9eaa09
														");
Packit 9eaa09
			attrset(COLOR_PAIR(5));
Packit 9eaa09
			mvprintw(LINES - 2, 1,
Packit 9eaa09
				"Press <S> for changing sleep setup, <C> for CPU ban setup.  ");
Packit 9eaa09
			attrset(COLOR_PAIR(3));
Packit 9eaa09
			move(LINES - 1, COLS - 1);
Packit 9eaa09
			refresh();
Packit 9eaa09
			char settings_string[1024] = "settings cpus \0";
Packit 9eaa09
			for_each_cpu(all_cpus, get_new_cpu_ban_values, settings_string);
Packit 9eaa09
			if(!strcmp("settings cpus \0", settings_string)) {
Packit 9eaa09
				strncpy(settings_string + strlen(settings_string),
Packit 9eaa09
						"NULL", 1024 - strlen(settings_string));
Packit 9eaa09
			}
Packit 9eaa09
			send_settings(settings_string);
Packit 9eaa09
			break;
Packit 9eaa09
		case 'q':
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			close_window(0);
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(3):
Packit 9eaa09
			is_tree = 1;
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			display_tree();
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(5):
Packit 9eaa09
			is_tree = 0;
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			setup_irqs();
Packit 9eaa09
			break;
Packit 9eaa09
		default:
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void copy_assigned_obj(int *number, void *data)
Packit 9eaa09
{
Packit 9eaa09
	snprintf(data + strlen(data), 128 - strlen(data), "%d, ", *number);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void print_assigned_objects_string(irq_t *irq, int *line_offset)
Packit 9eaa09
{
Packit 9eaa09
	if(irq->is_banned) {
Packit 9eaa09
		return;
Packit 9eaa09
	}
Packit 9eaa09
	char assigned_to[128] = "\0";
Packit 9eaa09
	for_each_int(irq->assigned_to, copy_assigned_obj, assigned_to);
Packit 9eaa09
	assigned_to[strlen(assigned_to) - 2] = '\0';
Packit 9eaa09
	mvprintw(*line_offset, 36, assigned_to);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void print_irq_line(irq_t *irq, void *data)
Packit 9eaa09
{
Packit 9eaa09
	int *line_offset = data;
Packit 9eaa09
	switch(irq->class) {
Packit 9eaa09
	case(IRQ_OTHER):
Packit 9eaa09
		attrset(COLOR_PAIR(1));
Packit 9eaa09
		break;
Packit 9eaa09
	case(IRQ_LEGACY):
Packit 9eaa09
		attrset(COLOR_PAIR(2));
Packit 9eaa09
		break;
Packit 9eaa09
	case(IRQ_SCSI):
Packit 9eaa09
		attrset(COLOR_PAIR(3));
Packit 9eaa09
		break;
Packit 9eaa09
	case(IRQ_VIDEO):
Packit 9eaa09
		attrset(COLOR_PAIR(8));
Packit 9eaa09
		break;
Packit 9eaa09
	case(IRQ_ETH):
Packit 9eaa09
	case(IRQ_GBETH):
Packit 9eaa09
	case(IRQ_10GBETH):
Packit 9eaa09
		attrset(COLOR_PAIR(9));
Packit 9eaa09
		break;
Packit 9eaa09
	case(IRQ_VIRT_EVENT):
Packit 9eaa09
		attrset(COLOR_PAIR(10));
Packit 9eaa09
		break;
Packit 9eaa09
	default:
Packit 9eaa09
		attrset(COLOR_PAIR(0));
Packit 9eaa09
		break;
Packit 9eaa09
	}
Packit 9eaa09
	mvprintw(*line_offset, 3, "IRQ %d", irq->vector);
Packit 9eaa09
	mvprintw(*line_offset, 19, "%s", irq->is_banned ? "YES" : "NO ");
Packit 9eaa09
	print_assigned_objects_string(irq, line_offset);
Packit 9eaa09
	mvprintw(*line_offset, 84, "%s",
Packit 9eaa09
			 irq->class < 0 ? "Unknown" : IRQ_CLASS_TO_STR[irq->class]);
Packit 9eaa09
	(*line_offset)++;
Packit 9eaa09
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void print_all_irqs()
Packit 9eaa09
{
Packit 9eaa09
	int *line = malloc(sizeof(int));
Packit 9eaa09
	*line = 4;
Packit 9eaa09
	attrset(COLOR_PAIR(0));
Packit 9eaa09
	mvprintw(2, 3,
Packit 9eaa09
			"NUMBER          IS BANNED        ASSIGNED TO CPUS      \
Packit 9eaa09
			    CLASS");
Packit 9eaa09
	for_each_irq(all_irqs, print_irq_line, line);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
int toggle_irq(GList *irq_list, int position)
Packit 9eaa09
{
Packit 9eaa09
	GList *entry = g_list_first(irq_list);
Packit 9eaa09
	int irq_node = 0;
Packit 9eaa09
	while(irq_node != position) {
Packit 9eaa09
		entry = g_list_next(entry);
Packit 9eaa09
		irq_node++;
Packit 9eaa09
	}
Packit 9eaa09
	if(((irq_t *)(entry->data))->is_banned) {
Packit 9eaa09
		((irq_t *)(entry->data))->is_banned = 0;
Packit 9eaa09
	} else {
Packit 9eaa09
		((irq_t *)(entry->data))->is_banned = 1;
Packit 9eaa09
	}
Packit 9eaa09
	return ((irq_t *)(entry->data))->is_banned;
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void get_new_irq_ban_values(irq_t *irq, void *data)
Packit 9eaa09
{
Packit 9eaa09
	char *ban_list = (char *)data;
Packit 9eaa09
	if(irq->is_banned) {
Packit 9eaa09
		snprintf(ban_list + strlen(ban_list), 1024 - strlen(ban_list),
Packit 9eaa09
				" %d", irq->vector);
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void copy_irqs_from_nodes(cpu_node_t *node, void *data __attribute__((unused)))
Packit 9eaa09
{
Packit 9eaa09
	if(g_list_length(node->irqs) > 0) {
Packit 9eaa09
		GList *new = g_list_copy_deep(node->irqs, copy_irq, NULL);
Packit 9eaa09
		all_irqs = g_list_concat(all_irqs, new);
Packit 9eaa09
	}
Packit 9eaa09
	if(g_list_length(node->children) > 0) {
Packit 9eaa09
		for_each_node(node->children, copy_irqs_from_nodes, all_irqs);
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void get_all_irqs()
Packit 9eaa09
{
Packit 9eaa09
	all_irqs = g_list_copy_deep(setup.banned_irqs, copy_irq, NULL);
Packit 9eaa09
	for_each_node(tree, copy_irqs_from_nodes, NULL);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void handle_irq_banning()
Packit 9eaa09
{
Packit 9eaa09
	GList *tmp = g_list_copy_deep(all_irqs, copy_irq, NULL);
Packit 9eaa09
	attrset(COLOR_PAIR(5));
Packit 9eaa09
	mvprintw(LINES - 3, 1, "Move up and down the list, toggle ban with Enter.");
Packit 9eaa09
	mvprintw(LINES - 2, 1, "Press ESC for discarding and <S> for saving the values.");
Packit 9eaa09
	move(4, 19);
Packit 9eaa09
	curs_set(1);
Packit 9eaa09
	refresh();
Packit 9eaa09
	size_t position = 3;
Packit 9eaa09
	char processing = 1;
Packit 9eaa09
	while(processing) {
Packit 9eaa09
		int direction = getch();
Packit 9eaa09
		switch(direction) {
Packit 9eaa09
		case KEY_UP:
Packit 9eaa09
			if(position > 4) {
Packit 9eaa09
				position--;
Packit 9eaa09
				move(position, 19);
Packit 9eaa09
			}
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_DOWN:
Packit 9eaa09
			if(position < g_list_length(all_irqs) + 3) {
Packit 9eaa09
				position++;
Packit 9eaa09
				move(position, 19);
Packit 9eaa09
			}
Packit 9eaa09
			break;
Packit 9eaa09
		case '\n':
Packit 9eaa09
		case '\r': {
Packit 9eaa09
			attrset(COLOR_PAIR(3));
Packit 9eaa09
			int banned = toggle_irq(tmp, position - 4);
Packit 9eaa09
			if(banned) {
Packit 9eaa09
				mvprintw(position, 19, "YES");
Packit 9eaa09
			} else {
Packit 9eaa09
				mvprintw(position, 19, "NO ");
Packit 9eaa09
			}
Packit 9eaa09
			move(position, 19);
Packit 9eaa09
			refresh();
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
		case 27:
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			curs_set(0);
Packit 9eaa09
			/* Forget the changes */
Packit 9eaa09
			tmp = g_list_copy_deep(all_irqs, copy_irq, NULL);
Packit 9eaa09
			print_all_irqs();
Packit 9eaa09
			attrset(COLOR_PAIR(0));
Packit 9eaa09
			mvprintw(LINES - 3, 1, "			\
Packit 9eaa09
					");
Packit 9eaa09
			attrset(COLOR_PAIR(5));
Packit 9eaa09
			mvprintw(LINES - 2, 1, "Press  for setting up IRQ banning.\
Packit 9eaa09
				");
Packit 9eaa09
			move(LINES - 1, COLS - 1);
Packit 9eaa09
			refresh();
Packit 9eaa09
			break;
Packit 9eaa09
		case 's':
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			all_irqs = tmp;
Packit 9eaa09
			curs_set(0);
Packit 9eaa09
			print_all_irqs();
Packit 9eaa09
			attrset(COLOR_PAIR(0));
Packit 9eaa09
			mvprintw(LINES - 3, 1, "			\
Packit 9eaa09
					");
Packit 9eaa09
			attrset(COLOR_PAIR(5));
Packit 9eaa09
			mvprintw(LINES - 2, 1, "Press  for setting up IRQ banning.\
Packit 9eaa09
				");
Packit 9eaa09
			attrset(COLOR_PAIR(3));
Packit 9eaa09
			move(LINES - 1, COLS - 1);
Packit 9eaa09
			refresh();
Packit 9eaa09
			char settings_string[1024] = BAN_IRQS;
Packit 9eaa09
			for_each_irq(all_irqs, get_new_irq_ban_values, settings_string);
Packit 9eaa09
			if(!strcmp(BAN_IRQS, settings_string)) {
Packit 9eaa09
				strncpy(settings_string + strlen(settings_string),
Packit 9eaa09
						" NONE", 1024 - strlen(settings_string));
Packit 9eaa09
			}
Packit 9eaa09
			send_settings(settings_string);
Packit 9eaa09
			break;
Packit 9eaa09
		case 'q':
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			close_window(0);
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(3):
Packit 9eaa09
			is_tree = 1;
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			display_tree();
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(4):
Packit 9eaa09
			is_tree = 0;
Packit 9eaa09
			processing = 0;
Packit 9eaa09
			settings();
Packit 9eaa09
			break;
Packit 9eaa09
		default:
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void init()
Packit 9eaa09
{
Packit 9eaa09
	signal(SIGINT, close_window);
Packit 9eaa09
	initscr();
Packit 9eaa09
	keypad(stdscr, TRUE);
Packit 9eaa09
	curs_set(0);
Packit 9eaa09
	nonl();
Packit 9eaa09
	cbreak();
Packit 9eaa09
	nodelay(stdscr, TRUE);
Packit 9eaa09
	echo();
Packit 9eaa09
	if(has_colors()) {
Packit 9eaa09
		start_color();
Packit 9eaa09
		init_pair(1, COLOR_RED, COLOR_BLACK);
Packit 9eaa09
		init_pair(2, COLOR_YELLOW, COLOR_BLACK);
Packit 9eaa09
		init_pair(3, COLOR_GREEN, COLOR_BLACK);
Packit 9eaa09
		init_pair(4, COLOR_WHITE, COLOR_BLUE);
Packit 9eaa09
		init_pair(5, COLOR_WHITE, COLOR_RED);
Packit 9eaa09
		init_pair(6, COLOR_RED, COLOR_WHITE);
Packit 9eaa09
		init_pair(7, COLOR_BLACK, COLOR_CYAN);
Packit 9eaa09
		init_pair(8, COLOR_BLUE, COLOR_BLACK);
Packit 9eaa09
		init_pair(9, COLOR_CYAN, COLOR_BLACK);
Packit 9eaa09
		init_pair(10, COLOR_MAGENTA, COLOR_BLACK);
Packit 9eaa09
	}
Packit 9eaa09
Packit 9eaa09
	display_tree();
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void close_window(int sig __attribute__((unused)))
Packit 9eaa09
{
Packit 9eaa09
	g_list_free(setup.banned_irqs);
Packit 9eaa09
	g_list_free(setup.banned_cpus);
Packit 9eaa09
	g_list_free_full(tree, free);
Packit 9eaa09
	endwin();
Packit 9eaa09
	exit(EXIT_SUCCESS);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void settings()
Packit 9eaa09
{
Packit 9eaa09
	clear();
Packit 9eaa09
	char *setup_data = get_data(SETUP);
Packit 9eaa09
	parse_setup(setup_data);
Packit 9eaa09
Packit 9eaa09
	char info[128] = "Current sleep interval between rebalancing: \0";
Packit 9eaa09
	uint8_t sleep_input_offset = strlen(info) + 3;
Packit 9eaa09
	snprintf(info + strlen(info), 128 - strlen(info), "%lu\n", setup.sleep);
Packit 9eaa09
	attrset(COLOR_PAIR(1));
Packit 9eaa09
	mvprintw(2, 3, info);
Packit 9eaa09
	print_all_cpus();
Packit 9eaa09
Packit 9eaa09
	int user_input = 1;
Packit 9eaa09
	while(user_input) {
Packit 9eaa09
		attrset(COLOR_PAIR(5));
Packit 9eaa09
		mvprintw(LINES - 2, 1,
Packit 9eaa09
				 "Press <S> for changing sleep setup, <C> for CPU ban setup. ");
Packit 9eaa09
		show_frame();
Packit 9eaa09
		show_footer();
Packit 9eaa09
		refresh();
Packit 9eaa09
		int c = getch();
Packit 9eaa09
		switch(c) {
Packit 9eaa09
		case 's': {
Packit 9eaa09
			mvprintw(LINES - 1, 1, "Press ESC for discarding your input.\
Packit 9eaa09
												");
Packit 9eaa09
			attrset(COLOR_PAIR(0));
Packit 9eaa09
			mvprintw(LINES - 2, 1, "			\
Packit 9eaa09
												");
Packit 9eaa09
			uint64_t new_sleep = get_valid_sleep_input(sleep_input_offset);
Packit 9eaa09
			if(new_sleep != setup.sleep) {
Packit 9eaa09
				setup.sleep = new_sleep;
Packit 9eaa09
				char settings_data[128];
Packit 9eaa09
				snprintf(settings_data, 128, "%s %lu", SET_SLEEP, new_sleep);
Packit 9eaa09
				send_settings(settings_data);
Packit 9eaa09
			}
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
		case 'c':
Packit 9eaa09
			handle_cpu_banning();
Packit 9eaa09
			break;
Packit 9eaa09
		/* We need to include window changing options as well because the
Packit 9eaa09
		 * related char was eaten up by getch() already */
Packit 9eaa09
		case 'q':
Packit 9eaa09
			user_input = 0;
Packit 9eaa09
			close_window(0);
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(3):
Packit 9eaa09
			is_tree = 1;
Packit 9eaa09
			user_input = 0;
Packit 9eaa09
			display_tree();
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(5):
Packit 9eaa09
			is_tree = 0;
Packit 9eaa09
			user_input = 0;
Packit 9eaa09
			setup_irqs();
Packit 9eaa09
			break;
Packit 9eaa09
		default:
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
	}
Packit 9eaa09
	free(setup_data);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void setup_irqs()
Packit 9eaa09
{
Packit 9eaa09
	clear();
Packit 9eaa09
	get_all_irqs();
Packit 9eaa09
	all_irqs = g_list_sort(all_irqs, sort_all_irqs);
Packit 9eaa09
	print_all_irqs();
Packit 9eaa09
	attrset(COLOR_PAIR(5));
Packit 9eaa09
	mvprintw(LINES - 2, 1, "Press  for setting up IRQ banning.");
Packit 9eaa09
	show_frame();
Packit 9eaa09
	show_footer();
Packit 9eaa09
	refresh();
Packit 9eaa09
Packit 9eaa09
	int user_input = 1;
Packit 9eaa09
	while(user_input) {
Packit 9eaa09
		int c = getch();
Packit 9eaa09
		switch(c) {
Packit 9eaa09
		case 'i':
Packit 9eaa09
			handle_irq_banning();
Packit 9eaa09
			break;
Packit 9eaa09
		case 'q':
Packit 9eaa09
			user_input = 0;
Packit 9eaa09
			close_window(0);
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(3):
Packit 9eaa09
			is_tree = 1;
Packit 9eaa09
			user_input = 0;
Packit 9eaa09
			display_tree();
Packit 9eaa09
			break;
Packit 9eaa09
		case KEY_F(4):
Packit 9eaa09
			is_tree = 0;
Packit 9eaa09
			user_input = 0;
Packit 9eaa09
			settings();
Packit 9eaa09
			break;
Packit 9eaa09
		default:
Packit 9eaa09
			break;
Packit 9eaa09
		}
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void display_tree_node_irqs(irq_t *irq, void *data)
Packit 9eaa09
{
Packit 9eaa09
	char indent[32] = "	   \0";
Packit 9eaa09
	snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", (char *)data);
Packit 9eaa09
	attrset(COLOR_PAIR(3));
Packit 9eaa09
	printw("%sIRQ %lu, IRQs since last rebalance %lu\n",
Packit 9eaa09
			indent, irq->vector, irq->diff);
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void display_tree_node(cpu_node_t *node, void *data)
Packit 9eaa09
{
Packit 9eaa09
	int i;
Packit 9eaa09
	const char *node_type_to_str[] = {
Packit 9eaa09
			"CPU\0",
Packit 9eaa09
			"CACHE DOMAIN\0",
Packit 9eaa09
			"CPU PACKAGE\0",
Packit 9eaa09
			"NUMA NODE\0"};
Packit 9eaa09
Packit 9eaa09
	char *spaces = "    \0";
Packit 9eaa09
	char indent[32] = "\0";
Packit 9eaa09
	char *asciitree = " `--\0";
Packit 9eaa09
	for(i = node->type; i <= OBJ_TYPE_NODE; i++) {
Packit 9eaa09
		snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", spaces);
Packit 9eaa09
		if(i != OBJ_TYPE_NODE) {
Packit 9eaa09
			snprintf(indent + strlen(indent), 32 - strlen(indent), "   ");
Packit 9eaa09
		}
Packit 9eaa09
	}
Packit 9eaa09
	snprintf(indent + strlen(indent), 32 - strlen(indent), "%s", asciitree);
Packit 9eaa09
	char copy_to[1024];
Packit 9eaa09
	char *numa_available = "\0";
Packit 9eaa09
	if((node->type == OBJ_TYPE_NODE) && (node->number == -1)) {
Packit 9eaa09
		numa_available = " (This machine is not NUMA-capable)";
Packit 9eaa09
	}
Packit 9eaa09
	snprintf(copy_to, 1024, "%s%s, number %d%s, CPU mask %s\n",
Packit 9eaa09
			indent, node_type_to_str[node->type], node->number, numa_available,
Packit 9eaa09
			node->cpu_mask);
Packit 9eaa09
	switch(node->type) {
Packit 9eaa09
	case(OBJ_TYPE_CPU):
Packit 9eaa09
		attrset(COLOR_PAIR(1));
Packit 9eaa09
		break;
Packit 9eaa09
	case(OBJ_TYPE_CACHE):
Packit 9eaa09
		attrset(COLOR_PAIR(2));
Packit 9eaa09
		break;
Packit 9eaa09
	case(OBJ_TYPE_PACKAGE):
Packit 9eaa09
		attrset(COLOR_PAIR(8));
Packit 9eaa09
		break;
Packit 9eaa09
	case(OBJ_TYPE_NODE):
Packit 9eaa09
		attrset(COLOR_PAIR(9));
Packit 9eaa09
		break;
Packit 9eaa09
	default:
Packit 9eaa09
		break;
Packit 9eaa09
	}
Packit 9eaa09
	printw(copy_to);
Packit 9eaa09
	if(g_list_length(node->irqs) > 0) {
Packit 9eaa09
		for_each_irq(node->irqs, display_tree_node_irqs, indent);
Packit 9eaa09
	}
Packit 9eaa09
	if(g_list_length(node->children)) {
Packit 9eaa09
		for_each_node(node->children, display_tree_node, data);
Packit 9eaa09
	}
Packit 9eaa09
}
Packit 9eaa09
Packit 9eaa09
void display_tree()
Packit 9eaa09
{
Packit 9eaa09
	clear();
Packit 9eaa09
	char *setup_data = get_data(SETUP);
Packit 9eaa09
	parse_setup(setup_data);
Packit 9eaa09
	char *irqbalance_data = get_data(STATS);
Packit 9eaa09
	parse_into_tree(irqbalance_data);
Packit 9eaa09
	display_banned_cpus();
Packit 9eaa09
	for_each_node(tree, display_tree_node, NULL);
Packit 9eaa09
	show_frame();
Packit 9eaa09
	show_footer();
Packit 9eaa09
	refresh();
Packit 9eaa09
	free(setup_data);
Packit 9eaa09
	free(irqbalance_data);
Packit 9eaa09
}