Skip to content

feat(DAG): Add estimated WCET per node; add relative EDF scheduler - #738

Open
romancardenas wants to merge 4 commits into
tier4:mainfrom
romancardenas:dag_estimated_wcet
Open

romancardenas wants to merge 4 commits into
tier4:mainfrom
romancardenas:dag_estimated_wcet

Conversation

@romancardenas

Copy link
Copy Markdown
Contributor

Description

This PR include a wcet field for DAG nodes. By default, it is set to Duration::ZERO, which is equivalent to the previous behavior. However, if users provide an expected WCET per node, when building the DAG, now the earliest start and latest end relative times per node are computed.

Earliest Start Time

For source nodes, ES = 0
For other nodes, ES = max over predecessors p (ES(p) + WCET(p)

Latest Finish Time

For sink nodes, LF = Deadline
For other nodes, LF = min over successors p (LF(p) - WCET(p))

LF is now the node relative deadline.

Also, we can now check if, a priori, the DAG scheduling is feasible

ES + WCET <= LF

Generic Dag EDF scheduler

I splitted the GEDF logic into a generic EDF scheduler and a specific GEDF scheduler. The GEDF only considers the global deadline to compute each node's deadline.

Relative EDF

A new scheduler takes into consideration the new per-node relative deadlines to schedule the tasks properly.

Related links

How was this PR tested?

  • scripts/ci.sh passes on my machine.

Notes for reviewers

I plan to do more tests and examples during this week. However, an early review is more than welcome to help me speed up the debug process :)

@romancardenas

romancardenas commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor Author

After @atsushi421 's feedback, I pushed a new commit with the following upgrades:

The Timing structure

Now, dag.rs defines the following per-node timing analysis structure:

/// The timing parameters of a node. All are offsets from the release of the job.
#[derive(Clone, Copy, Debug, Default)]
pub struct NodeTiming {
    /// Estimated worst-case execution time of the node. It is zero unless set with `set_node_wcet()`.
    pub estimated_wcet: Duration,
    /// Estimated earliest start of the node, computed from the predecessors.
    pub estimated_earliest_start: Duration,
    /// Estimated latest finish of the node, computed from the successors.
    pub estimated_latest_finish: Duration,
    /// True if the node is on a critical path, that is, a longest path of the DAG by WCET.
    /// Such a node has the least slack, which is `D` minus the length of that path.
    pub is_critical: bool,
}

impl NodeTiming {
    pub fn estimated_earliest_finish(&self) -> Duration {
        self.estimated_earliest_start + self.estimated_wcet
    }

    pub fn estimated_latest_start(&self) -> Duration {
        self.estimated_latest_finish - self.estimated_wcet
    }

    pub fn slack(&self) -> Duration {
        self.estimated_latest_finish - self.estimated_earliest_finish()
    }
}

This structure also allows us to know if a given node is part of the critical path, in case it is necessary for future algorithms.

When building the DAG, each node will have its own Timing structure, which is pre-populated before running the DAG (no runtime cost).

The get_or_release_job method

DAG schedulers will then use the following method to get release and timing info from nodes:

pub(crate) fn get_or_release_job<R>(
        &self,
        node_idx: NodeIndex,
        release: bool,
        release_time: impl FnOnce() -> u64,
        read_timing: impl FnOnce(&NodeTiming) -> R, // <- NEW THING!!!
    ) -> (u64, R) {
...
}

Instead of copying all the timing structure each time the node is released, now the get_or_release_job allows users to pass a closure that, from the original timing structure, computes whatever metric is needed for getting the priority.

As GEDF doesn't use these new metrics, the closure is empty. However, for REDF, the closure gets the estimated_latest_finish field. Future algorithms can, for instance, check if the node is in the critical path, or the slack.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant