mirror of
https://github.com/genodelabs/genode.git
synced 2025-01-31 00:24:51 +00:00
seoul: reduce CPU load in graphic mode
- Stop refreshing if all CPUs go to sleep, also in text mode. - Any input resets update rate to 100Hz in graphic mode, which gets decreased step by step down to 25Hz if no input is available (looking video without input by user). Fixes #3576
This commit is contained in:
parent
d385749ead
commit
9812799b24
@ -71,7 +71,7 @@ foreach binary $guest_os_binaries {
|
||||
|
||||
source ${genode_dir}/repos/ports/run/seoul.inc
|
||||
|
||||
append qemu_args " -cpu phenom "
|
||||
append qemu_args " -cpu phenom -smp 2 "
|
||||
append qemu_args " -net nic,model=e1000 "
|
||||
append qemu_args " -nographic "
|
||||
|
||||
|
@ -74,7 +74,7 @@ build $build_components
|
||||
# write Seoul config file
|
||||
set vm_cfg_fd [open "bin/vm_seoul.cfg" w]
|
||||
puts $vm_cfg_fd "<config map_small=\"$map_small\" vmm_vcpu_same_cpu=\"$vmm_vcpu_same_cpu\">"
|
||||
puts $vm_cfg_fd { <machine>
|
||||
puts $vm_cfg_fd { <machine verbose="no">
|
||||
<mem start="0x0" end="0x9a000"/>
|
||||
<mem start="0x100000" end="0xfffff000"/>
|
||||
<!--<ioio/>-->
|
||||
|
@ -785,7 +785,9 @@ class Machine : public StaticReceiver<Machine>
|
||||
Seoul::Network *_nic { nullptr };
|
||||
Rtc::Session *_rtc { nullptr };
|
||||
|
||||
Vcpu * _vcpus[32] { nullptr };
|
||||
enum { MAX_CPUS = 8 };
|
||||
Vcpu * _vcpus[MAX_CPUS] { nullptr };
|
||||
Genode::Bit_array<64> _vcpus_active { };
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
@ -907,6 +909,8 @@ class Machine : public StaticReceiver<Machine>
|
||||
ep_name->string(),
|
||||
location);
|
||||
|
||||
_vcpus_active.set(_vcpus_up, 1);
|
||||
|
||||
Vcpu * vcpu = new Vcpu(*ep, _vm_con, _heap, _env,
|
||||
_motherboard_lock, msg.vcpu,
|
||||
_guest_memory, _motherboard,
|
||||
@ -956,12 +960,26 @@ class Machine : public StaticReceiver<Machine>
|
||||
if (!_vcpus[vcpu_id])
|
||||
return false;
|
||||
|
||||
_vcpus_active.clear(vcpu_id, 1);
|
||||
|
||||
if (!_vcpus_active.get(0, 64)) {
|
||||
MessageConsole msgcon(MessageConsole::Type::TYPE_KILL);
|
||||
_unsynchronized_motherboard.bus_console.send(msgcon);
|
||||
}
|
||||
|
||||
_motherboard_lock.unlock();
|
||||
|
||||
_vcpus[vcpu_id]->block();
|
||||
|
||||
_motherboard_lock.lock();
|
||||
|
||||
if (!_vcpus_active.get(0, 64)) {
|
||||
MessageConsole msgcon(MessageConsole::Type::TYPE_RESET);
|
||||
_unsynchronized_motherboard.bus_console.send(msgcon);
|
||||
}
|
||||
|
||||
_vcpus_active.set(vcpu_id, 1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -1218,6 +1236,8 @@ class Machine : public StaticReceiver<Machine>
|
||||
{
|
||||
using namespace Genode;
|
||||
|
||||
bool const verbose = machine_node.attribute_value("verbose", false);
|
||||
|
||||
Xml_node node = machine_node.sub_node();
|
||||
for (;; node = node.next()) {
|
||||
|
||||
@ -1225,7 +1245,9 @@ class Machine : public StaticReceiver<Machine>
|
||||
char name[MODEL_NAME_MAX_LEN];
|
||||
node.type_name(name, sizeof(name));
|
||||
|
||||
Genode::log("device: ", (char const *)name);
|
||||
if (verbose)
|
||||
Genode::log("device: ", (char const *)name);
|
||||
|
||||
Device_model_info *dmi = device_model_registry()->lookup(name);
|
||||
|
||||
if (!dmi) {
|
||||
@ -1249,7 +1271,8 @@ class Machine : public StaticReceiver<Machine>
|
||||
Xml_node::Attribute arg = node.attribute(dmi->arg_names[i]);
|
||||
arg.value(&argv[i]);
|
||||
|
||||
Genode::log(" arg[", i, "]: ", Genode::Hex(argv[i]));
|
||||
if (verbose)
|
||||
Genode::log(" arg[", i, "]: ", Genode::Hex(argv[i]));
|
||||
}
|
||||
catch (Xml_node::Nonexistent_attribute) { }
|
||||
}
|
||||
|
@ -38,13 +38,13 @@ static Tff_font::Static_glyph_buffer<4096> glyph_buffer { };
|
||||
static Tff_font default_font(_binary_mono_tff_start, glyph_buffer);
|
||||
|
||||
static struct {
|
||||
Genode::uint64_t checksum1 = 0;
|
||||
Genode::uint64_t checksum2 = 0;
|
||||
unsigned unchanged = 0;
|
||||
bool cmp_even = 1;
|
||||
bool active = false;
|
||||
bool revoked = false;
|
||||
bool vga_update= false; /* update indirectly by vbios */
|
||||
Genode::uint64_t checksum1 = 0;
|
||||
Genode::uint64_t checksum2 = 0;
|
||||
unsigned unchanged = 0;
|
||||
bool cmp_even = 1;
|
||||
bool active = false;
|
||||
bool vga_revoked = false;
|
||||
bool vga_update = false; /* update indirectly by vbios */
|
||||
} fb_state;
|
||||
|
||||
|
||||
@ -153,15 +153,17 @@ unsigned Seoul::Console::_input_to_ps2wheel(Input::Event const &ev)
|
||||
|
||||
bool Seoul::Console::receive(MessageConsole &msg)
|
||||
{
|
||||
if (msg.type == MessageConsole::TYPE_ALLOC_VIEW) {
|
||||
switch (msg.type) {
|
||||
case MessageConsole::TYPE_ALLOC_VIEW :
|
||||
_guest_fb = msg.ptr;
|
||||
_regs = msg.regs;
|
||||
|
||||
msg.view = 0;
|
||||
} else if (msg.type == MessageConsole::TYPE_SWITCH_VIEW) {
|
||||
return true;
|
||||
case MessageConsole::TYPE_SWITCH_VIEW:
|
||||
/* XXX: For now, we only have one view. */
|
||||
} else if (msg.type == MessageConsole::TYPE_GET_MODEINFO) {
|
||||
|
||||
return true;
|
||||
case MessageConsole::TYPE_GET_MODEINFO:
|
||||
enum {
|
||||
MEMORY_MODEL_TEXT = 0,
|
||||
MEMORY_MODEL_DIRECT_COLOR = 6,
|
||||
@ -210,9 +212,18 @@ bool Seoul::Console::receive(MessageConsole &msg)
|
||||
msg.info->phys_base = 0xe0000000;
|
||||
msg.info->_phys_size = _fb_mode.width()*_fb_mode.height()*2;
|
||||
return true;
|
||||
} else return false;
|
||||
}
|
||||
return false;
|
||||
case MessageConsole::TYPE_KILL: /* all CPUs go idle */
|
||||
_handle_fb(); /* refresh before going to sleep */
|
||||
fb_state.active = false;
|
||||
return true;
|
||||
case MessageConsole::TYPE_RESET: /* first of all sleeping CPUs woke up */
|
||||
_reactivate();
|
||||
return true;
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void Screen::vga_updated()
|
||||
@ -220,6 +231,14 @@ void Screen::vga_updated()
|
||||
fb_state.vga_update = true;
|
||||
}
|
||||
|
||||
void Seoul::Console::_reactivate()
|
||||
{
|
||||
fb_state.active = true;
|
||||
|
||||
MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000));
|
||||
_unsynchronized_motherboard.bus_timer.send(msg);
|
||||
}
|
||||
|
||||
bool Seoul::Console::receive(MessageMemRegion &msg)
|
||||
{
|
||||
/* we had a fault in the text framebuffer */
|
||||
@ -234,11 +253,11 @@ bool Seoul::Console::receive(MessageMemRegion &msg)
|
||||
}
|
||||
|
||||
if (reactivate) {
|
||||
if (!fb_state.active) fb_state.active = true;
|
||||
fb_state.vga_revoked = false;
|
||||
|
||||
Logging::printf("Reactivating text buffer loop.\n");
|
||||
|
||||
MessageTimer msg(_timer, _unsynchronized_motherboard.clock()->abstime(1, 1000));
|
||||
_unsynchronized_motherboard.bus_timer.send(msg);
|
||||
_reactivate();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -254,8 +273,7 @@ unsigned Seoul::Console::_handle_fb()
|
||||
/* transfer text buffer content into chunky canvas */
|
||||
if (_regs->mode == TEXT_MODE) {
|
||||
|
||||
if (fb_state.revoked || !fb_state.active)
|
||||
return 0;
|
||||
if (fb_state.vga_revoked || !fb_state.active) return 0;
|
||||
|
||||
memset(_pixels, 0, _fb_size);
|
||||
|
||||
@ -299,24 +317,32 @@ unsigned Seoul::Console::_handle_fb()
|
||||
_memory.detach(PHYS_FRAME_VGA_COLOR << 12,
|
||||
FRAME_COUNT_COLOR << 12);
|
||||
|
||||
fb_state.vga_revoked = true;
|
||||
fb_state.unchanged = 0;
|
||||
fb_state.active = false;
|
||||
|
||||
_framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height());
|
||||
Logging::printf("Deactivated text buffer loop.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!fb_state.revoked) {
|
||||
|
||||
if (!fb_state.vga_revoked) {
|
||||
_memory.detach(PHYS_FRAME_VGA_COLOR << 12,
|
||||
FRAME_COUNT_COLOR << 12);
|
||||
|
||||
fb_state.revoked = true;
|
||||
fb_state.vga_revoked = true;
|
||||
}
|
||||
|
||||
if (!fb_state.active) {
|
||||
fb_state.unchanged = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_framebuffer.refresh(0, 0, _fb_mode.width(), _fb_mode.height());
|
||||
return 10;
|
||||
|
||||
fb_state.unchanged++;
|
||||
|
||||
return (fb_state.unchanged > 4) ? 4 * 10 : fb_state.unchanged * 10;
|
||||
}
|
||||
|
||||
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include <base/env.h>
|
||||
#include <dataspace/client.h>
|
||||
#include <util/string.h>
|
||||
#include <util/bit_array.h>
|
||||
|
||||
/* os includes */
|
||||
#include <framebuffer_session/connection.h>
|
||||
@ -64,13 +65,13 @@ class Seoul::Console : public StaticReceiver<Seoul::Console>
|
||||
Genode::addr_t const _vm_phys_fb;
|
||||
short *_pixels;
|
||||
Genode::Surface<Pixel_rgb565> _surface;
|
||||
unsigned _timer { 0 };
|
||||
Keyboard _vkeyb { _motherboard };
|
||||
char *_guest_fb { nullptr };
|
||||
VgaRegs *_regs { nullptr };
|
||||
bool _left { false };
|
||||
bool _middle { false };
|
||||
bool _right { false };
|
||||
unsigned _timer { 0 };
|
||||
|
||||
unsigned _input_to_ps2mouse(Input::Event const &);
|
||||
unsigned _input_to_ps2wheel(Input::Event const &);
|
||||
@ -81,6 +82,8 @@ class Seoul::Console : public StaticReceiver<Seoul::Console>
|
||||
void _handle_input();
|
||||
unsigned _handle_fb();
|
||||
|
||||
void _reactivate();
|
||||
|
||||
/*
|
||||
* Noncopyable
|
||||
*/
|
||||
|
Loading…
x
Reference in New Issue
Block a user