hoitaja: First version of static core allocator.

This commit is contained in:
Michael Mueller
2023-08-07 18:03:45 +02:00
parent d603ea90c0
commit 01cf697875

View File

@@ -12,13 +12,18 @@
* under the terms of the GNU Affero General Public License version 3.
*/
#pragma once
/* Genode includes */
#include <sandbox/child.h>
#include <sandbox/library.h>
#include <sandbox/utils.h>
#include <sandbox/types.h>
#include <util/string.h>
/** Hoitaja includes **/
#include "load_controller.h"
#include "cell_controller.h"
#include <cell.h>
namespace Hoitaja
{
@@ -28,13 +33,77 @@ namespace Hoitaja
class Hoitaja::Core_allocator
{
private:
Sandbox::Child *_cells_to_grow;
Sandbox::Child *_cells_to_shrink;
Genode::Affinity::Space &_affinity_space;
::Sandbox::Prio_levels &_prio_levels;
double _resource_coeff; // Coefficient used for calculating resource shares
void _shrink(Cell &cell, unsigned int cores)
{
char yield_args_str[10];
Genode::snprintf(yield_args_str, 7, "cores=%d", cores);
Genode::Parent::Resource_args yield_args(yield_args_str);
cell.yield(yield_args);
}
public:
inline unsigned int _calculate_resource_share(long priority) {
double ref_share = static_cast<double>(_affinity_space.total()) / _resource_coeff;
return static_cast<unsigned int>((1.0 / static_cast<double>(priority)) * ref_share);
}
Core_allocator(Genode::Affinity::Space &affinity_space, ::Sandbox::Prio_levels prio_levels) : _affinity_space(affinity_space), _prio_levels(prio_levels), _resource_coeff(0.0)
{
Genode::log("Created core allocator for ", affinity_space.total(), " cores and ", prio_levels.value, " priorities.");
}
Genode::Affinity::Location allocate_cores_for_cell(Genode::Xml_node const &start_node)
{
// Calculate affinity from global affinity space and priority
long priority = ::Sandbox::priority_from_xml(start_node, _prio_levels);
priority = (priority == 0) ? 1 : priority;
_resource_coeff += (1.0/static_cast<double>(priority)); // treat priority 0 same as 1, to avoid division by zero here
unsigned int cores_share = _calculate_resource_share(priority);
Genode::log("Child ", start_node.attribute_value("name", Genode::String<8>("unknown")), "'s share is ", cores_share, " of ", _affinity_space.total(), " cores, coeff=", _resource_coeff, " priority=", priority);
return Genode::Affinity::Location( _affinity_space.total()-cores_share, 0, cores_share, 1 ); /* always use the core_share last cores, for now */
}
void free_cores_from_cell(Cell &cell)
{
/* Remove cell's coefficient from the global resource coefficient.
* This is necessary in order to be able to redistribute the freed resources correctly. We do not trigger the redistribution itself here, because the child has not been fully destroyed yet, thus its resources might still be occupied at this point. */
_resource_coeff -= 1.0 / static_cast<double>(cell.resources().priority);
}
/**
* @brief Update core allocations for cells reported by Cell controller
*
*/
void update();
void update(Hoitaja::Cell &cell, int *xpos) {
Cell::Resources resources = cell.resources();
long priority = (resources.priority == 0)? 1 : resources.priority;
unsigned int cores_share = _calculate_resource_share(priority);
unsigned int cores_to_reclaim = resources.affinity.location().width() * resources.affinity.location().height() - cores_share;
cores_to_reclaim = (static_cast<int>(cores_to_reclaim) < 0) ? 0 : cores_to_reclaim;
Genode::Affinity::Location location(*xpos - cores_share, resources.affinity.location().ypos(), cores_share, resources.affinity.location().height());
cell.update_affinity(Genode::Affinity(resources.affinity.space(), location));
*xpos = location.xpos();
// TODO: Update affinity of existing sessions for cell
// TODO: Send yield request to cell
log("Need to reclaim ", cores_to_reclaim, " cores from ", cell.name());
if (cores_to_reclaim > 0) {
_shrink(cell, cores_to_reclaim);
}
}
};