Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[enhancement] More control over the state of channel queues #1764

Open
koblonczek opened this issue Dec 4, 2024 · 0 comments
Open

[enhancement] More control over the state of channel queues #1764

koblonczek opened this issue Dec 4, 2024 · 0 comments
Labels
enhancement New feature or request

Comments

@koblonczek
Copy link

What's hard to do? (limit 100 words)

We'd like to be able to clear contents of the channel queue. This stems from a need to reset a hierarchy of procs sometimes, e.g. after encountering an error. Resetting such hierarchy was already proposed in #1680 [enhancement] Resetting a hierarchy of subprocs, but to guarantee correct execution of resetted procs all channel queues inside this hierarchy must be cleared as well. Otherwise any messages left in queues after the reset that were sent before the reset can cause incorrect results to be produced at best, or incorrect behavior or proc lockup at worst. Resetting proc's state can be currently expressed via non-blocking receive on a dedicated channel, so this enhancement proposal would be useful even without a mechanism for resetting procs baked into the language.

To illustrate these points, consider this example proc that sends a request for 4096 data packets and receives them over 4096 consecutive next() evaluations. with the possibility that external reset request clears the to_receive counter:

init { u32:0 }

next(to_receive: u32) {
    const REQUEST_N = u32:4096;
    
    let tok = join();

    let (_, (), reset_valid) = recv_non_blocking(tok, reset_req_r, ());

    send_if(tok, read_req_s, to_receive == u32:0, REQUEST_N);
    let (tok, data) = recv(tok, read_resp_r);

    let processed_data = data + u32:1;
    send(tok, data_out_s, processed_data);

    if (reset_valid) {
        u32:0
    } else if (to_receive == u32:0) {
        REQUEST_N - u32:1
    } else {
        to_receive - u32:1
    }
}

When a reset request is received on reset_req_r state is set to 0, but there may be some lingering packets left in the read_resp channel queue that we would like to clear as well.

Current best alternative workaround (limit 100 words)

One can write a proc in such a way that it will track the amount of messages it needs to receive in case a reset request comes in. Once it does, it needs to perform that amount of receives and discard the received data to empty the queue. This is:

  • inefficient in cases where the amount of data requested is very large - we don't want to spend time receiving a gigabyte of data that needs to be discarded anyway because there was some error during processing it halfway through.
  • cumbersome for large trees of procs - every proc would need to implement this behavior of receiving non-blocking reset request on dedicated channel and counting how many data it needs to receive to empty all queues during the reset

Your view of the "best case XLS enhancement" (limit 100 words)

Ability to reset channel queues from within DSLX. This could be as simple as sending a request on a dedicated 0-depth reset channel that is tied to a specific channel.

let (data_s, data_r, data_rst) = rchan<u32>("data");
@koblonczek koblonczek added the enhancement New feature or request label Dec 4, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant