Compare commits

..

No commits in common. "35b3c3c98cd07419c3c6c73027fa0cdefe2cb818" and "8834241417e67090c5185c37221118229b0b4c48" have entirely different histories.

5 changed files with 29 additions and 57 deletions

View File

@ -7,6 +7,7 @@
#include <kernel/Timer/Timer.h> #include <kernel/Timer/Timer.h>
#define SCHEDULER_ASSERT 1 #define SCHEDULER_ASSERT 1
#define SCHEDULER_LOAD_BALANCE 0
#if SCHEDULER_ASSERT == 0 #if SCHEDULER_ASSERT == 0
#undef ASSERT #undef ASSERT
@ -295,8 +296,9 @@ namespace Kernel
{ {
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled); ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
if (Processor::is_smp_enabled()) if constexpr(SCHEDULER_LOAD_BALANCE)
do_load_balancing(); if (Processor::is_smp_enabled())
do_load_balancing();
{ {
const uint64_t current_ns = SystemTimer::get().ns_since_boot(); const uint64_t current_ns = SystemTimer::get().ns_since_boot();
@ -337,7 +339,6 @@ namespace Kernel
node->blocked = false; node->blocked = false;
if (node != m_current) if (node != m_current)
m_run_queue.add_thread_to_back(node); m_run_queue.add_thread_to_back(node);
update_most_loaded_node_queue(node, &m_run_queue);
} }
else else
{ {
@ -387,6 +388,7 @@ namespace Kernel
return least_loaded_id; return least_loaded_id;
} }
#if SCHEDULER_LOAD_BALANCE
void Scheduler::do_load_balancing() void Scheduler::do_load_balancing()
{ {
ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled); ASSERT(Processor::get_interrupt_state() == InterruptState::Disabled);
@ -419,9 +421,9 @@ namespace Kernel
if (m_current) if (m_current)
{ {
const char* name = "<unknown>"; const char* name = "unknown";
if (m_current->thread->has_process() && *m_current->thread->process().name()) if (m_current->thread->has_process() && m_current->thread->process().is_userspace() && m_current->thread->process().userspace_info().argv)
name = m_current->thread->process().name(); name = m_current->thread->process().userspace_info().argv[0];
const uint64_t load_percent_x1000 = BAN::Math::div_round_up<uint64_t>(m_current->time_used_ns * 100'000, processing_ns); const uint64_t load_percent_x1000 = BAN::Math::div_round_up<uint64_t>(m_current->time_used_ns * 100'000, processing_ns);
dprintln(" tid { 2}: { 3}.{3}% <{}> current", m_current->thread->tid(), load_percent_x1000 / 1000, load_percent_x1000 % 1000, name); dprintln(" tid { 2}: { 3}.{3}% <{}> current", m_current->thread->tid(), load_percent_x1000 / 1000, load_percent_x1000 % 1000, name);
} }
@ -472,6 +474,9 @@ namespace Kernel
break; break;
if (thread_info.node == m_current || thread_info.queue == nullptr) if (thread_info.node == m_current || thread_info.queue == nullptr)
continue; continue;
// FIXME: allow load balancing with blocked threads, with this algorithm there is a race condition
if (thread_info.node->blocked)
continue;
auto least_loaded_id = find_least_loaded_processor(); auto least_loaded_id = find_least_loaded_processor();
if (least_loaded_id == Processor::current_id()) if (least_loaded_id == Processor::current_id())
@ -561,6 +566,7 @@ namespace Kernel
m_last_load_balance_ns += s_load_balance_interval_ns; m_last_load_balance_ns += s_load_balance_interval_ns;
} }
#endif
BAN::ErrorOr<void> Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id) BAN::ErrorOr<void> Scheduler::bind_thread_to_processor(Thread* thread, ProcessorID processor_id)
{ {
@ -604,14 +610,12 @@ namespace Kernel
auto state = Processor::get_interrupt_state(); auto state = Processor::get_interrupt_state();
Processor::set_interrupt_state(InterruptState::Disabled); Processor::set_interrupt_state(InterruptState::Disabled);
ASSERT(m_current->processor_id == Processor::current_id());
ASSERT(!m_current->blocked); ASSERT(!m_current->blocked);
m_current->blocked = true; m_current->blocked = true;
m_current->wake_time_ns = wake_time_ns; m_current->wake_time_ns = wake_time_ns;
if (blocker) if (blocker)
blocker->add_thread_to_block_queue(m_current); blocker->add_thread_to_block_queue(m_current);
update_most_loaded_node_queue(m_current, &m_block_queue);
Processor::yield(); Processor::yield();
Processor::set_interrupt_state(state); Processor::set_interrupt_state(state);

View File

@ -302,8 +302,6 @@ namespace Kernel
ASSERT(m_output.bytes > 0); ASSERT(m_output.bytes > 0);
m_output.bytes--; m_output.bytes--;
putchar('\b'); putchar('\b');
putchar(' ');
putchar('\b');
} }
// Caret notation // Caret notation
else if (last < 32 || last == 127) else if (last < 32 || last == 127)
@ -311,18 +309,12 @@ namespace Kernel
m_output.bytes--; m_output.bytes--;
putchar('\b'); putchar('\b');
putchar('\b'); putchar('\b');
putchar(' ');
putchar(' ');
putchar('\b');
putchar('\b');
} }
// Ascii // Ascii
else else
{ {
m_output.bytes--; m_output.bytes--;
putchar('\b'); putchar('\b');
putchar(' ');
putchar('\b');
} }
} }
} }

View File

@ -306,7 +306,8 @@ namespace Kernel
dprintln_if(DEBUG_VTTY, "Unsupported ANSI CSI character f"); dprintln_if(DEBUG_VTTY, "Unsupported ANSI CSI character f");
return; return;
case 'm': case 'm':
for (int i = 0; i <= m_ansi_state.index && i < static_cast<int>(max_ansi_args); i++) handle_ansi_csi_color(BAN::Math::max(m_ansi_state.nums[0], 0));
for (int i = 1; i < m_ansi_state.index; i++)
handle_ansi_csi_color(BAN::Math::max(m_ansi_state.nums[i], 0)); handle_ansi_csi_color(BAN::Math::max(m_ansi_state.nums[i], 0));
return reset_ansi(); return reset_ansi();
case 's': case 's':
@ -360,24 +361,11 @@ namespace Kernel
return reset_ansi(); return reset_ansi();
} }
reset_ansi(); reset_ansi();
dprintln_if(DEBUG_VTTY, "invalid ANSI CSI character {}", static_cast<char>(ch)); dprintln_if(DEBUG_VTTY, "invalid ANSI CSI ?{}{}", m_ansi_state.nums[0], (char)ch);
return;
case 'n':
if (m_ansi_state.nums[0] == 6)
{
char buffer[2 + 10 + 1 + 10 + 1];
size_t len = 0;
BAN::Formatter::print([&](char ch) { buffer[len++] = ch; }, "\e[{};{}R", m_row + 1, m_column + 1);
for (size_t i = 0; i < len; i++)
handle_input_byte(buffer[i]);
return reset_ansi();
};
reset_ansi();
dprintln_if(DEBUG_VTTY, "Unsupported ANSI CSI character n");
return; return;
default: default:
reset_ansi(); reset_ansi();
dprintln_if(DEBUG_VTTY, "Unsupported ANSI CSI character {}", static_cast<char>(ch)); dprintln_if(DEBUG_VTTY, "Unsupported ANSI CSI character {}", ch);
return; return;
} }
} }
@ -411,7 +399,7 @@ namespace Kernel
break; break;
case BS: case BS:
if (m_column > 0) if (m_column > 0)
m_column--; putchar_at(' ', --m_column, m_row);
break; break;
case HT: case HT:
m_column++; m_column++;

View File

@ -276,9 +276,9 @@ bool Terminal::read_shell()
return true; return true;
} }
void Terminal::handle_sgr(int32_t value) void Terminal::handle_sgr()
{ {
switch (value) switch (m_csi_info.fields[0])
{ {
case -1: case 0: case -1: case 0:
m_bg_color = s_default_bg_color; m_bg_color = s_default_bg_color;
@ -298,25 +298,25 @@ void Terminal::handle_sgr(int32_t value)
m_colors_inverted = false; m_colors_inverted = false;
break; break;
case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37: case 30: case 31: case 32: case 33: case 34: case 35: case 36: case 37:
m_fg_color = s_colors_dark[value - 30]; m_fg_color = s_colors_dark[m_csi_info.fields[0] - 30];
break; break;
case 39: case 39:
m_fg_color = s_default_fg_color; m_fg_color = s_default_fg_color;
break; break;
case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47: case 40: case 41: case 42: case 43: case 44: case 45: case 46: case 47:
m_bg_color = s_colors_dark[value - 40]; m_bg_color = s_colors_dark[m_csi_info.fields[0] - 40];
break; break;
case 49: case 49:
m_bg_color = s_default_bg_color; m_bg_color = s_default_bg_color;
break; break;
case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97: case 90: case 91: case 92: case 93: case 94: case 95: case 96: case 97:
m_fg_color = s_colors_bright[value - 90]; m_fg_color = s_colors_bright[m_csi_info.fields[0] - 90];
break; break;
case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107: case 100: case 101: case 102: case 103: case 104: case 105: case 106: case 107:
m_bg_color = s_colors_bright[value - 100]; m_bg_color = s_colors_bright[m_csi_info.fields[0] - 100];
break; break;
default: default:
dprintln("TODO: SGR {}", value); dprintln("TODO: SGR {}", m_csi_info.fields[0]);
break; break;
} }
} }
@ -337,7 +337,7 @@ Rectangle Terminal::handle_csi(char ch)
if (isdigit(ch)) if (isdigit(ch))
{ {
if (m_csi_info.index < m_csi_info.max_fields) if (m_csi_info.index <= 1)
{ {
auto& field = m_csi_info.fields[m_csi_info.index]; auto& field = m_csi_info.fields[m_csi_info.index];
field = (BAN::Math::max(field, 0) * 10) + (ch - '0'); field = (BAN::Math::max(field, 0) * 10) + (ch - '0');
@ -504,8 +504,7 @@ Rectangle Terminal::handle_csi(char ch)
m_cursor.y = BAN::Math::clamp<int32_t>(m_csi_info.fields[0], 1, rows()) - 1; m_cursor.y = BAN::Math::clamp<int32_t>(m_csi_info.fields[0], 1, rows()) - 1;
break; break;
case 'm': case 'm':
for (size_t i = 0; i <= m_csi_info.index && i < m_csi_info.max_fields; i++) handle_sgr();
handle_sgr(m_csi_info.fields[i]);
break; break;
case 's': case 's':
m_saved_cursor = m_cursor; m_saved_cursor = m_cursor;
@ -517,21 +516,11 @@ Rectangle Terminal::handle_csi(char ch)
case 'l': case 'l':
if (!m_csi_info.question || m_csi_info.fields[0] != 25) if (!m_csi_info.question || m_csi_info.fields[0] != 25)
{ {
dprintln("unsupported ANSI CSI {}", ch); dprintln("invalid ANSI CSI ?{}{}", m_csi_info.fields[0], (char)ch);
break; break;
} }
m_cursor_shown = (ch == 'h'); m_cursor_shown = (ch == 'h');
break; break;
case 'n':
if (m_csi_info.fields[0] != 6)
{
dprintln("unsupported ANSI CSI n");
break;
}
char buffer[2 + 10 + 1 + 10 + 2];
sprintf(buffer, "\e[%u;%uR", m_cursor.y + 1, m_cursor.x + 1);
write(m_shell_info.pts_master, buffer, strlen(buffer));
break;
default: default:
dprintln("TODO: CSI {}", ch); dprintln("TODO: CSI {}", ch);
break; break;

View File

@ -35,7 +35,7 @@ public:
uint32_t rows() const { return m_window->height() / m_font.height(); } uint32_t rows() const { return m_window->height() / m_font.height(); }
private: private:
void handle_sgr(int32_t value); void handle_sgr();
Rectangle handle_csi(char ch); Rectangle handle_csi(char ch);
Rectangle putcodepoint(uint32_t codepoint); Rectangle putcodepoint(uint32_t codepoint);
Rectangle putchar(uint8_t ch); Rectangle putchar(uint8_t ch);
@ -70,8 +70,7 @@ private:
struct CSIInfo struct CSIInfo
{ {
static constexpr size_t max_fields = 2; int32_t fields[2];
int32_t fields[max_fields];
size_t index; size_t index;
bool question; bool question;
}; };