Blame ui/ui.c

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