summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennard Kittner <lennard@kittner.dev>2025-03-23 17:12:25 +0100
committerLennard Kittner <lennard@kittner.dev>2025-03-23 17:12:25 +0100
commitc2d63b96cbbd3be653fa0023fadae7df3babaf32 (patch)
tree990c96aa93fd7aa92ac8ed55e70253fdb73c303c /src
parent572abfe10bb3ee74e8138f71e75bee8d8cad7214 (diff)
Make Frequency Service available to rest of code
Diffstat (limited to 'src')
-rw-r--r--src/energy.rs19
-rw-r--r--src/scheduler.rs49
2 files changed, 63 insertions, 5 deletions
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<DashMap<Pid, u64>>,
request_receiver: mpsc::Receiver<Request>,
update_interval: Duration,
+ shared_cpu_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_policy_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_cpu_current_frequencies: Arc<RwLock<Vec<FrequencyKHZ>>>,
}
impl EnergyService {
@@ -41,6 +46,9 @@ impl EnergyService {
shared_budgets: Arc<DashMap<Pid, u64>>,
request_receiver: mpsc::Receiver<Request>,
update_interval: Duration,
+ shared_cpu_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_policy_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_cpu_current_frequencies: Arc<RwLock<Vec<FrequencyKHZ>>>,
) -> 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<DashMap<Pid, u64>>,
+ shared_cpu_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_policy_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_cpu_current_frequencies: Arc<RwLock<Vec<FrequencyKHZ>>>,
) -> std::io::Result<mpsc::SyncSender<Request>> {
// 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<dyn ECoreSelector>,
energy_sender: mpsc::SyncSender<EnergyRequest>,
shared_budgets: Arc<DashMap<Pid, u64>>,
+ frequency_sender: mpsc::SyncSender<FrequencyRequest>,
+ shared_cpu_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_policy_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>>,
+ shared_cpu_current_frequencies: Arc<RwLock<Vec<FrequencyKHZ>>>,
}
impl<'a> Scheduler<'a> {
@@ -49,12 +54,25 @@ impl<'a> Scheduler<'a> {
println!("Initializing energy-aware scheduler");
+ let shared_cpu_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>> =
+ Arc::new(RwLock::new(Vec::new()));
+ let shared_policy_frequency_ranges: Arc<RwLock<Vec<RangeInclusive<FrequencyKHZ>>>> =
+ Arc::new(RwLock::new(Vec::new()));
+ let shared_cpu_current_frequencies: Arc<RwLock<Vec<FrequencyKHZ>>> =
+ Arc::new(RwLock::new(Vec::new()));
+
// Shared budget map between energy service and scheduler
let shared_budgets: Arc<DashMap<Pid, u64>> = 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,
})
}