From c2d63b96cbbd3be653fa0023fadae7df3babaf32 Mon Sep 17 00:00:00 2001 From: Lennard Kittner Date: Sun, 23 Mar 2025 17:12:25 +0100 Subject: Make Frequency Service available to rest of code --- src/energy.rs | 19 ++++++++++++++++++- src/scheduler.rs | 49 +++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 63 insertions(+), 5 deletions(-) (limited to 'src') diff --git a/src/energy.rs b/src/energy.rs index 9fe37b5..ed8b65e 100644 --- a/src/energy.rs +++ b/src/energy.rs @@ -3,10 +3,12 @@ mod rapl; mod trackers; use std::collections::{BTreeSet, HashMap}; -use std::sync::{mpsc, Arc}; +use std::ops::RangeInclusive; +use std::sync::{mpsc, Arc, RwLock}; use std::thread; use std::time::Duration; +use crate::freq::FrequencyKHZ; use crate::Pid; use dashmap::DashMap; @@ -32,6 +34,9 @@ pub struct EnergyService { shared_budgets: Arc>, request_receiver: mpsc::Receiver, update_interval: Duration, + shared_cpu_frequency_ranges: Arc>>>, + shared_policy_frequency_ranges: Arc>>>, + shared_cpu_current_frequencies: Arc>>, } impl EnergyService { @@ -41,6 +46,9 @@ impl EnergyService { shared_budgets: Arc>, request_receiver: mpsc::Receiver, update_interval: Duration, + shared_cpu_frequency_ranges: Arc>>>, + shared_policy_frequency_ranges: Arc>>>, + shared_cpu_current_frequencies: Arc>>, ) -> Self { Self { estimator, @@ -50,6 +58,9 @@ impl EnergyService { shared_budgets, request_receiver, update_interval, + shared_cpu_frequency_ranges, + shared_policy_frequency_ranges, + shared_cpu_current_frequencies, } } @@ -152,6 +163,9 @@ pub fn start_energy_service( use_mocking: bool, power_cap: u64, shared_budgets: Arc>, + shared_cpu_frequency_ranges: Arc>>>, + shared_policy_frequency_ranges: Arc>>>, + shared_cpu_current_frequencies: Arc>>, ) -> std::io::Result> { // Potentially convert back to bounded channel let (request_sender, request_receiver) = mpsc::sync_channel(10000); @@ -176,6 +190,9 @@ pub fn start_energy_service( shared_budgets, request_receiver, Duration::from_millis(50), // 50ms update interval + shared_cpu_frequency_ranges, + shared_policy_frequency_ranges, + shared_cpu_current_frequencies, ); service.run(); diff --git a/src/scheduler.rs b/src/scheduler.rs index 9e13656..39db5c6 100644 --- a/src/scheduler.rs +++ b/src/scheduler.rs @@ -1,5 +1,6 @@ use crate::bpf::*; use crate::energy::{self, Request as EnergyRequest}; +use crate::freq::{self, FrequencyKHZ, Request as FrequencyRequest}; use crate::e_core_selector::{ECoreSelector, RoundRobinSelector}; use anyhow::Result; @@ -9,9 +10,9 @@ use scx_utils::{Topology, UserExitInfo}; use std::collections::{HashMap, VecDeque}; use std::mem::MaybeUninit; -use std::ops::Range; +use std::ops::{Range, RangeInclusive}; use std::process; -use std::sync::{mpsc, Arc}; +use std::sync::{mpsc, Arc, RwLock}; use std::time::{Duration, Instant}; use crate::Pid; @@ -32,6 +33,10 @@ pub struct Scheduler<'a> { e_core_selector: Box, energy_sender: mpsc::SyncSender, shared_budgets: Arc>, + frequency_sender: mpsc::SyncSender, + shared_cpu_frequency_ranges: Arc>>>, + shared_policy_frequency_ranges: Arc>>>, + shared_cpu_current_frequencies: Arc>>, } impl<'a> Scheduler<'a> { @@ -49,12 +54,25 @@ impl<'a> Scheduler<'a> { println!("Initializing energy-aware scheduler"); + let shared_cpu_frequency_ranges: Arc>>> = + Arc::new(RwLock::new(Vec::new())); + let shared_policy_frequency_ranges: Arc>>> = + Arc::new(RwLock::new(Vec::new())); + let shared_cpu_current_frequencies: Arc>> = + Arc::new(RwLock::new(Vec::new())); + // Shared budget map between energy service and scheduler let shared_budgets: Arc> = Arc::new(DashMap::with_capacity(100000)); // Start energy tracking service - let energy_sender = - energy::start_energy_service(use_mocking, power_cap, shared_budgets.clone())?; + let energy_sender = energy::start_energy_service( + use_mocking, + power_cap, + shared_budgets.clone(), + shared_cpu_frequency_ranges.clone(), + shared_policy_frequency_ranges.clone(), + shared_cpu_current_frequencies.clone(), + )?; let topology = Topology::new().unwrap(); let mut e_core_ids = Vec::new(); @@ -70,10 +88,29 @@ impl<'a> Scheduler<'a> { p_core_ids.sort(); let e_cores = *e_core_ids.first().unwrap_or(&0)..*e_core_ids.last().unwrap_or(&0); let p_cores = *p_core_ids.first().unwrap_or(&0)..*p_core_ids.last().unwrap_or(&0); + let all_cores = 0..((e_cores.len() + p_cores.len()) as u32); let selector = Box::new(RoundRobinSelector::new(&e_cores)); let to_remove = Vec::with_capacity(1000); + let frequency_sender = freq::start_frequency_service( + all_cores, + shared_cpu_frequency_ranges.clone(), + shared_policy_frequency_ranges.clone(), + shared_cpu_current_frequencies.clone(), + Duration::from_millis(1), + )?; + + frequency_sender + .try_send(FrequencyRequest::GetPolicyCPUFrequency) + .unwrap(); + frequency_sender + .try_send(FrequencyRequest::GetPossibleCPUFrequencyRange) + .unwrap(); + frequency_sender + .try_send(FrequencyRequest::GetCurrentFrequencies) + .unwrap(); + Ok(Self { bpf, task_queue: VecDeque::new(), @@ -88,6 +125,10 @@ impl<'a> Scheduler<'a> { energy_sender, shared_budgets, to_remove, + frequency_sender, + shared_cpu_frequency_ranges, + shared_policy_frequency_ranges, + shared_cpu_current_frequencies, }) } -- cgit v1.3.1