diff --git a/Cargo.toml b/Cargo.toml index 142d87c..d2346ea 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -27,6 +27,7 @@ tokio = { version = "1.0", features = ["macros", "rt-multi-thread"] } chrono = "0.4.22" lazy_static = "1.4.0" daemonize="0.4.1" +once_cell = "1.17.1" [build-dependencies] # time = "0.1" diff --git a/src/core/mod.rs b/src/core.rs similarity index 91% rename from src/core/mod.rs rename to src/core.rs index 6ffec9f..e19e717 100644 --- a/src/core/mod.rs +++ b/src/core.rs @@ -17,4 +17,5 @@ pub mod scheduler; pub mod shared_obj; pub mod task; pub mod traffic_class; -pub mod worker; \ No newline at end of file +pub mod worker; +pub mod utils; \ No newline at end of file diff --git a/src/core/bessctl.rs b/src/core/bessctl.rs index 06cb2c5..812d931 100644 --- a/src/core/bessctl.rs +++ b/src/core/bessctl.rs @@ -32,7 +32,7 @@ use crate::shared_obj; use crate::traffic_class; // #include "utils/ether.h" // #include "utils/time.h" -use crate::worker::{self, WorkerStatus}; +use crate::worker::{self, WorkerStatus, Worker}; // #include // #include @@ -571,7 +571,7 @@ impl BessControl for BESSControlService { &self, req: Request, ) -> Result, Status> { - for wid in 0..worker::K_MAX_WORKERS { + for wid in 0..Worker::K_MAX_WORKERS { if !worker::is_worker_active(wid) { continue; } @@ -607,36 +607,31 @@ impl BessControl for BESSControlService { ) -> Result, Status> { // std::lock_guard lock(mutex_); - // uint64_t wid = request->wid(); - let wid = request.get_mut().wid; - // if (wid >= Worker::kMaxWorkers) { - // return return_with_error(response, EINVAL, "Invalid worker id"); - // } - if wid >= worker::K_MAX_WORKERS as i64 { + let wid = request.get_ref().wid; + if wid >= Worker::K_MAX_WORKERS as i64 { return Err(Status::aborted("Invalid worker id")); } - // uint64_t core = request->core(); - // if (!is_cpu_present(core)) { - // return return_with_error(response, EINVAL, "Invalid core %d", core); - // } + let core = request.get_ref().core; - // if (is_worker_active(wid)) { - // return return_with_error(response, EEXIST, "worker:%d is already active", - // wid); - // } - if worker::is_worker_active(wid) { - return Err(Status::aborted("active")); + if !worker::is_cpu_present(core) { + let response = format!("Invalid core {}", core); + return Err(Status::invalid_argument(response)); + } + + if worker::is_worker_active(wid as usize) { + let response = format!("worker: {} is already active", wid); + return Err(Status::already_exists(response)); } - // const std::string& scheduler = request->scheduler(); - // if (scheduler != "" && scheduler != "experimental") { - // return return_with_error(response, EINVAL, "Invalid scheduler %s", - // scheduler.c_str()); - // } + let scheduler = request.get_ref().scheduler.as_str(); + if scheduler != "" && scheduler != "experimental" { + let response = format!("Invalid scheduler {}", scheduler); + return Err(Status::invalid_argument(response)); + } - // launch_worker(wid, core, scheduler); - // return Status::OK; - // } + worker::launch_worker(wid, core, scheduler); + return Ok(Response::new(EmptyResponse { error: None })); + } // Status DestroyWorker(ServerContext*, const DestroyWorkerRequest* request, // EmptyResponse* response) override { diff --git a/src/core/bessd.rs b/src/core/bessd.rs index 2ea6654..e085288 100644 --- a/src/core/bessd.rs +++ b/src/core/bessd.rs @@ -33,9 +33,8 @@ use crate::core::opts::*; use chrono; use clap::Parser; use env_logger::fmt::Color; -use env_logger::{Builder, Target, WriteStyle}; +use env_logger::{Target, WriteStyle}; use exitcode; -use exitcode::OK; use log::*; use std::io::{self, BufRead,Write}; use std::process::exit; @@ -203,4 +202,4 @@ pub fn get_current_directory() -> String { fn read_file_lines

(filename: P) -> io::Result>> where P: AsRef, { let file = File::open(filename)?; Ok(io::BufReader::new(file).lines()) -} \ No newline at end of file +} diff --git a/src/core/scheduler.rs b/src/core/scheduler.rs index be22412..6ba4225 100644 --- a/src/core/scheduler.rs +++ b/src/core/scheduler.rs @@ -1,10 +1,6 @@ -// #include -// #include -// #include -// #include // #include "module.h" -use crate::core::traffic_class; +// use crate::core::traffic_class; // #include "utils/extended_priority_queue.h" // #include "worker.h" @@ -48,6 +44,7 @@ struct SchedWakeupQueue; // The non-instantiable base class for schedulers. Implements common routines // needed for scheduling. + pub struct Scheduler { // root: *TrafficClass, // default_rr_class: *RoundRobinTrafficClass, diff --git a/src/core/traffic_class.rs b/src/core/traffic_class.rs index 9f381b8..69fce01 100644 --- a/src/core/traffic_class.rs +++ b/src/core/traffic_class.rs @@ -19,10 +19,10 @@ const QUANTUM: u32 = 1 << 10; // Resource types that can be accounted for. pub enum Resource { - ResourceCount = 0, // Count of how many times scheduled - ResourceCycle, // CPU cycles - ResourcePacket, // Packets set - ResourceBit, // Bits sent + Count = 0, // Count of how many times scheduled + Cycle, // CPU cycles + Packet, // Packets set + Bit, // Bits sent NumResources, // Sentinel. Also used to indicate "no resource". } @@ -30,10 +30,10 @@ pub enum Resource { // pub type resource_arr_t = [u64; Resource::NUM_RESOURCES as usize]; // The priority of a traffic class. -// typedef uint32_t priority_t; +type priority_t = u32; // The amount of a resource allocated to a class. -// typedef int32_t resource_share_t; +type resource_share_t = u32; struct TcStats { usage: [u64; 4], @@ -61,24 +61,26 @@ enum TrafficPolicy { mod traffic_class_initializer_types { enum PriorityFakeType { - PRIORITY = 0, + Priority, } enum WeightedFairFakeType { - WEIGHTED_FAIR = 0, + WeightedFair, } enum RoundRobinFakeType { - ROUND_ROBIN = 0, + RoundRobin, } enum RateLimitFakeType { - RATE_LIMIT = 0, + RateLimit, } enum LeafFakeType { - LEAF = 0, + Leaf, } } use traffic_class_initializer_types::*; +use std::collections::HashMap; +use once_cell::sync::Lazy; const TRAFFIC_POLICY_NAME: [&str; TrafficPolicy::NumPolicies as usize] = [ "priority", @@ -88,17 +90,23 @@ const TRAFFIC_POLICY_NAME: [&str; TrafficPolicy::NumPolicies as usize] = [ "leaf", ]; -// const std::unordered_map ResourceMap = { -// {"count", RESOURCE_COUNT}, -// {"cycle", RESOURCE_CYCLE}, -// {"packet", RESOURCE_PACKET}, -// {"bit", RESOURCE_BIT}}; - -// const std::unordered_map ResourceName = { -// {RESOURCE_COUNT, "count"}, -// {RESOURCE_CYCLE, "cycle"}, -// {RESOURCE_PACKET, "packet"}, -// {RESOURCE_BIT, "bit"}}; +static RESOURCE_MAP: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + m.insert("count",Resource::Count); + m.insert("cycle",Resource::Cycle); + m.insert("packet", Resource::Packet); + m.insert("bit",Resource::Bit); + m +}); + +static RESOURCE_NAME: Lazy> = Lazy::new(|| { + let mut m = HashMap::new(); + m.insert(Resource::Count, "count"); + m.insert(Resource::Cycle, "cycle"); + m.insert(Resource::Packet, "packet"); + m.insert(Resource::Bit, "bit"); + m +}); /* acc += x */ // #define ACCUMULATE(acc, x) \ diff --git a/src/core/utils.rs b/src/core/utils.rs new file mode 100644 index 0000000..b9f20e6 --- /dev/null +++ b/src/core/utils.rs @@ -0,0 +1 @@ +pub mod random; \ No newline at end of file diff --git a/src/core/utils/random.h b/src/core/utils/random.h deleted file mode 100644 index 152e20a..0000000 --- a/src/core/utils/random.h +++ /dev/null @@ -1,103 +0,0 @@ -// Copyright (c) 2014-2016, The Regents of the University of California. -// Copyright (c) 2016-2017, Nefeli Networks, Inc. -// All rights reserved. -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions are met: -// -// * Redistributions of source code must retain the above copyright notice, this -// list of conditions and the following disclaimer. -// -// * Redistributions in binary form must reproduce the above copyright notice, -// this list of conditions and the following disclaimer in the documentation -// and/or other materials provided with the distribution. -// -// * Neither the names of the copyright holders nor the names of their -// contributors may be used to endorse or promote products derived from this -// software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE -// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR -// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF -// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS -// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN -// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) -// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE -// POSSIBILITY OF SUCH DAMAGE. - -#ifndef BESS_UTILS_RANDOM_H_ -#define BESS_UTILS_RANDOM_H_ - -#include - -#include "time.h" - -class Random { - public: - Random() : seed_(rdtsc()) {} - explicit Random(uint64_t seed) : seed_(seed) {} - - void SetSeed(uint64_t seed) { this->seed_ = seed; }; - - uint32_t Get(); - uint32_t GetRange(uint32_t range); - double GetReal(); - double GetRealNonzero(); - - private: - uint64_t seed_; -}; - -inline uint32_t Random::Get() { - seed_ = seed_ * 1103515245 + 12345; - return seed_ >> 32; -} - -/* returns [0, range) with no integer modulo operation */ -inline uint32_t Random::GetRange(uint32_t range) { - union { - uint64_t i; - double d; - } tmp; - - /* - * From the MSB, - * 0: sign - * 1-11: exponent (0x3ff == 0, 0x400 == 1) - * 12-63: mantissa - * The resulting double number is 1.(b0)(b1)...(b47), - * where seed_ is (b0)(b1)...(b63). - */ - seed_ = seed_ * 1103515245 + 12345; - tmp.i = (seed_ >> 12) | 0x3ff0000000000000ul; - return (tmp.d - 1.0) * range; -} - -/* returns [0.0, 1.0) */ -inline double Random::GetReal() { - union { - uint64_t i; - double d; - } tmp; - - seed_ = seed_ * 1103515245 + 12345; - tmp.i = (seed_ >> 12) | 0x3ff0000000000000ul; - return tmp.d - 1.0; -} - -/* returns (0.0, 1.0] (note it includes 1.0) */ -inline double Random::GetRealNonzero() { - union { - uint64_t i; - double d; - } tmp; - - seed_ = seed_ * 1103515245 + 12345; - tmp.i = (seed_ >> 12) | 0x3ff0000000000000ul; - return 2.0 - tmp.d; -} - -#endif // BESS_UTILS_RANDOM_H_ diff --git a/src/core/utils/random.rs b/src/core/utils/random.rs new file mode 100644 index 0000000..f1f3eca --- /dev/null +++ b/src/core/utils/random.rs @@ -0,0 +1,92 @@ +// Copyright (c) 2014-2016, The Regents of the University of California. +// Copyright (c) 2016-2017, Nefeli Networks, Inc. +// Copyright (c) 2024, Austin Aigbe +// All rights reserved. +// +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are met: +// +// * Redistributions of source code must retain the above copyright notice, this +// list of conditions and the following disclaimer. +// +// * Redistributions in binary form must reproduce the above copyright notice, +// this list of conditions and the following disclaimer in the documentation +// and/or other materials provided with the distribution. +// +// * Neither the names of the copyright holders nor the names of their +// contributors may be used to endorse or promote products derived from this +// software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE +// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +// POSSIBILITY OF SUCH DAMAGE. + + +use std::time::{SystemTime, UNIX_EPOCH}; + +pub struct Random { + seed: u64, +} + +impl Random { + // Constructor with no arguments, uses rdtsc equivalent + pub fn new() -> Self { + Self { + seed: Random::rdtsc(), + } + } + + // Constructor with seed argument + pub fn with_seed(seed: u64) -> Self { + Self { seed } + } + + // Method to set seed + pub fn set_seed(&mut self, seed: u64) { + self.seed = seed; + } + + // Equivalent to `rdtsc` in C++ + fn rdtsc() -> u64 { + let start = SystemTime::now().duration_since(UNIX_EPOCH).unwrap(); + start.as_nanos() as u64 + } + + // `Get` method: generate a random number + pub fn get(&mut self) -> u32 { + self.seed = self.seed.wrapping_mul(1103515245).wrapping_add(12345); + (self.seed >> 32) as u32 + } + + // Get a random number in range [0, range) + pub fn get_range(&mut self, range: u32) -> u32 { + self.seed = self.seed.wrapping_mul(1103515245).wrapping_add(12345); + let tmp: u64 = (self.seed >> 12) | 0x3ff0000000000000; + let dbl = f64::from_bits(tmp); + ((dbl - 1.0) * range as f64) as u32 + } + + // Get a real number in the range [0.0, 1.0) + pub fn get_real(&mut self) -> f64 { + self.seed = self.seed.wrapping_mul(1103515245).wrapping_add(12345); + let tmp: u64 = (self.seed >> 12) | 0x3ff0000000000000; + let dbl = f64::from_bits(tmp); + dbl - 1.0 + } + + // Get a real number in the range (0.0, 1.0] + pub fn get_real_nonzero(&mut self) -> f64 { + self.seed = self.seed.wrapping_mul(1103515245).wrapping_add(12345); + let tmp: u64 = (self.seed >> 12) | 0x3ff0000000000000; + let dbl = f64::from_bits(tmp); + 2.0 - dbl + } +} diff --git a/src/core/worker.rs b/src/core/worker.rs index 6e8ea00..574d870 100644 --- a/src/core/worker.rs +++ b/src/core/worker.rs @@ -1,96 +1,151 @@ -use std::thread; +// use std::thread; +use std::path::Path; +use lazy_static::lazy_static; +use std::sync::{Arc, Mutex}; // use gate; -// #include "traffic_class.h" +use crate::core::traffic_class::TrafficClass; // #include "utils/common.h" -// #include "utils/random.h" +use crate::utils::random::Random; +use crate::core::scheduler::Scheduler; + const MAX_GATES: u32 = 8192; -// /* TODO: worker threads doesn't necessarily be pinned to 1 core -// * -// * n: kMaxWorkers -// * -// * Role DPDK lcore ID Hardware core(s) -// * -------------------------------------------------------- -// * worker 0 0 1 specified core -// * worker 1 1 1 specified core -// * ... -// * worker n-1 n-1 1 specified core -// * master RTE_MAX_LCORE-1 all other cores that are allowed -// */ +const SYS_CPU_DIR: &str = "/sys/devices/system/cpu/cpu"; +const CORE_ID_FILE: &str = "topology/core_id"; + + +// TODO: worker threads doesn't necessarily be pinned to 1 core +// +// n: kMaxWorkers +// +// Role DPDK lcore ID Hardware core(s) +// -------------------------------------------------------- +// worker 0 0 1 specified core +// worker 1 1 1 specified core +// ... +// worker n-1 n-1 1 specified core +// master RTE_MAX_LCORE-1 all other cores that are allowed +// +#[derive(PartialEq)] pub enum WorkerStatus { - WorkerPausing, // transient state for blocking or quitting - WorkerPaused, - WorkerRunning, - WorkerFinished, + Pausing, // transient state for blocking or quitting + Paused, + Running, + Finished, } -use crate::core::scheduler::Scheduler; -// use crate::packet_pool::PacketPool; -// class Task; -pub const K_MAX_WORKERS: u32 = 64; -pub const K_ANY_WORKER: i32 = -1; // unspecified worker ID +struct PacketPool; +struct Task; + pub struct Worker { status: WorkerStatus, - wid: u32, // always [0, K_MAX_WORKERS - 1] - core: u32, // TODO: should be cpuset_t + wid: usize, // always [0, K_MAX_WORKERS - 1] + core: i32, // TODO: should be cpuset_t socket: u32, fd_event: u32, - - // bess::PacketPool *packet_pool_; - // packet_pool: *PacketPool, - // scheduler: *Scheduler, - - // bess::Scheduler *scheduler_; + packet_pool: PacketPool, + scheduler: Scheduler, silent_drops: u64, // packets that have been sent to a deadend current_tsc: u64, current_ns: u64, - // rand: &Random, + rand: Random, } impl Worker { - // /* ---------------------------------------------------------------------- - // * functions below are invoked by non-worker threads (the master) - // * ---------------------------------------------------------------------- */ - // void SetNonWorker(); - - // /* ---------------------------------------------------------------------- - // * functions below are invoked by worker threads - // * ---------------------------------------------------------------------- */ - // inline int is_pause_requested() { return status_ == WORKER_PAUSING; } - - // /* Block myself. Return nonzero if the worker needs to die */ - // int BlockWorker(); + pub const K_MAX_WORKERS: usize = 64; + pub const K_ANY_WORKER: isize = -1; // unspecified worker ID + + // ---------------------------------------------------------------------- + // functions below are invoked by non-worker threads (the master) + // ---------------------------------------------------------------------- + pub fn set_non_worker(&self) { + todo!(); + } + + // ---------------------------------------------------------------------- + // functions below are invoked by worker threads + // ---------------------------------------------------------------------- + + pub fn is_pause_requested(&self) -> bool { + self.status == WorkerStatus::Paused + } + // Block myself. Return nonzero if the worker needs to die + pub fn block_worker(&self) -> i32 { + todo!(); + } + + // The entry point of worker threads + pub fn run(&self, _arg: &mut T) -> &mut T { + todo!() + } + + pub fn status(&self) -> &WorkerStatus { + &self.status + } + + pub fn set_status(&mut self, status: WorkerStatus) { + self.status = status; + } - // /* The entry point of worker threads */ - // void *Run(void *_arg); + pub fn wid(&self) -> usize { + self.wid + } - // worker_status_t status() { return status_; } - // void set_status(worker_status_t status) { status_ = status; } + pub fn core(&self) -> i32 { + self.core + } + + pub fn socket(&self) -> u32 { + self.socket + } - // int wid() { return wid_; } - // int core() { return core_; } - // int socket() { return socket_; } - // int fd_event() { return fd_event_; } + pub fn fd_event(&self) -> u32 { + self.fd_event + } + + pub fn packet_pool(&self) -> &PacketPool { + &self.packet_pool + } + + pub fn scheduler(&self) -> &Scheduler { + &self.scheduler + } - // bess::PacketPool *packet_pool() { return packet_pool_; } + pub fn silent_drops(&self) -> u64 { + self.silent_drops + } + + pub fn set_silent_drops(&mut self, drops: u64) { + self.silent_drops = drops; + } - // bess::Scheduler *scheduler() { return scheduler_; } + pub fn incr_silent_drops(&mut self, drops: u64) { + self.silent_drops += drops; + } - // uint64_t silent_drops() { return silent_drops_; } - // void set_silent_drops(uint64_t drops) { silent_drops_ = drops; } - // void incr_silent_drops(uint64_t drops) { silent_drops_ += drops; } + pub fn current_tsc(&self) -> u64 { + self.current_tsc + } - // uint64_t current_tsc() const { return current_tsc_; } - // void set_current_tsc(uint64_t tsc) { current_tsc_ = tsc; } + pub fn set_current_tsc(&mut self, tsc: u64) { + self.current_tsc = tsc; + } - // uint64_t current_ns() const { return current_ns_; } - // void set_current_ns(uint64_t ns) { current_ns_ = ns; } + pub fn current_ns(&self) -> u64 { + self.current_ns + } + + pub fn set_current_ns(&mut self, ns: u64) { + self.current_ns = ns; + } - // Random *rand() const { return rand_; } + pub fn rand(&self) -> &Random { + &self.rand + } } // NOTE: Do not use "thread_local" here. It requires a function call every time // it is accessed. Use __thread instead, which incurs minimal runtime overhead. @@ -105,20 +160,40 @@ impl Worker { // "not trivially destructible"); // #endif -// // TODO: C++-ify - // extern int num_workers; +pub static mut NUM_WORKERS: usize = 0; + // extern std::thread worker_threads[Worker::kMaxWorkers]; + // extern Worker *volatile workers[Worker::kMaxWorkers]; +lazy_static!{ + static ref WORKERS: Arc>> = Arc::new(Mutex::new( { + let v: Vec = Vec::with_capacity(Worker::K_MAX_WORKERS); + v + })); +} + // ------------------------------------------------------------------------ // functions below are invoked by non-worker threads (the master) // ------------------------------------------------------------------------ -pub fn is_worker_core(cpu: u32) { - todo!(); +pub fn is_worker_core(cpu: i32) -> bool { + // Loop over all worker IDs + for wid in 0..Worker::K_MAX_WORKERS { + // Check if the worker is active and if the worker's core matches the CPU + if is_worker_active(wid) { + if let Some(worker) = WORKERS.lock().unwrap().get(wid) { + if worker.core() == cpu { + return true; + } + } + } + } + // Return false if no match is found + false } -pub fn pause_worker(wid: u32) { +pub fn pause_worker(_wid: usize) { todo!(); } @@ -132,7 +207,7 @@ fn attach_orphans() { } // void resume_worker(int wid); -fn resume_worker(wid: i32) { +fn resume_worker(_wid: usize) { todo!(); } @@ -140,27 +215,39 @@ fn resume_worker(wid: i32) { // void destroy_worker(int wid); // void destroy_all_workers(); -// bool is_any_worker_running(); +pub fn is_any_worker_running() -> bool { + todo!() +} -// int is_cpu_present(unsigned int core_id); +// Check if a cpu is present by the presence of the cpu information for it +pub fn is_cpu_present(core_id: i64) -> bool { + let path: String = format!("{}/{}/{}", SYS_CPU_DIR, core_id, CORE_ID_FILE); + + // Check if the file exists + Path::new(&path).exists() +} -//TODO -// static inline int is_worker_active(int wid) { -// return workers[wid] != nullptr; -// } -pub fn is_worker_active(wid: u32) -> bool { - true +#[inline(always)] +pub fn is_worker_active(wid: usize) -> bool { + // return workers[wid] != nullptr; + if wid >= Worker::K_MAX_WORKERS { + return false; // Ensure the worker ID is within bounds + } + + // Safely check if there's a worker present at the given index + WORKERS.lock().unwrap().get(wid).is_some() } -pub fn is_worker_running(wid: u32) -> bool { +pub fn is_worker_running(_wid: usize) -> bool { + //return workers[wid] && workers[wid]->status() == WORKER_RUNNING; false -//TODO - //return workers[wid] && workers[wid]->status() == WORKER_RUNNING; } -// // arg (int) is the core id the worker should run on, and optionally the -// // scheduler to use. -// void launch_worker(int wid, int core, const std::string &scheduler = ""); +// arg (int) is the core id the worker should run on, and optionally the +// scheduler to use. +pub fn launch_worker(wid: i64, core: i64, scheduler: &str) { + todo!(); +} // Worker *get_next_active_worker(); @@ -174,31 +261,46 @@ pub fn is_worker_running(wid: u32) -> bool { // // Otherwise, return false // bool remove_tc_from_orphan(bess::TrafficClass *c); -// // Returns a list of all the orphan traffic classes. -// const std::list> &list_orphan_tcs(); +// Returns a list of all the orphan traffic classes. +pub fn list_orphan_tcs<'a>() -> &'a Vec<(i32, &'a mut TrafficClass)> { + todo!() +} -// // Try to detach 'c' from a scheduler, or from the list of orhpan traffic -// // classes. -// // -// // Return true if successful. 'c' is now owned by the caller, and it must be -// // attached to a tree or destroyed. -// // -// // Otherwise, return false -// bool detach_tc(bess::TrafficClass *c); +// Try to detach 'c' from a scheduler, or from the list of orhpan traffic +// classes. +// +// Return true if successful. 'c' is now owned by the caller, and it must be +// attached to a tree or destroyed. +// +// Otherwise, return false +pub fn detach_tc(_c: &mut TrafficClass) -> bool { + todo!() +} -// // This class is used as a resource manager to automatically pause workers if -// // running and then restarts workers if they were previously paused. -// class WorkerPauser { -// public: -// explicit WorkerPauser(); -// ~WorkerPauser(); -// private: -// std::list workers_paused_; -// }; +// This struct is used as a resource manager to automatically pause workers if +// running and then restarts workers if they were previously paused. +pub struct WorkerPauser { + workers_paused: Vec, +} + +impl WorkerPauser { + pub fn new() -> Self { + WorkerPauser { + workers_paused: Vec::new(), + } + } +} + +// ~WorkerPauser() +impl Drop for WorkerPauser { + fn drop(&mut self) { + // Run when WorkerPauser is dropped + } +} // #endif // BESS_WORKER_H_ -// =========================================================================================== + // #include // #include @@ -247,22 +349,6 @@ pub fn is_worker_running(wid: u32) -> bool { // Scheduler *scheduler; // }; -// #define SYS_CPU_DIR "/sys/devices/system/cpu/cpu%u" -// #define CORE_ID_FILE "topology/core_id" - -// Check if a cpu is present by the presence of the cpu information for it -// pub fn is_cpu_present(core_id: u32) -> bool { -// char path[PATH_MAX]; -// int len = snprintf(path, sizeof(path), SYS_CPU_DIR "/" CORE_ID_FILE, core_id); -// if (len <= 0 || (unsigned)len >= sizeof(path)) { -// return false; -// } -// if (access(path, F_OK) != 0) { -// return false; -// } - -// return true; -// } // int is_worker_core(int cpu) { // int wid;