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

Fix Unintended Action Override #491

Merged
merged 8 commits into from
Oct 19, 2024
Merged

Fix Unintended Action Override #491

merged 8 commits into from
Oct 19, 2024

Conversation

Depetrol
Copy link
Collaborator

@Depetrol Depetrol commented Oct 17, 2024

This PR is a subsequent PR for #490 to address the unintended action override concurrency bug. The companion PR in lingua-franca is lf-lang/lingua-franca#2429.

Reproduce the Bug with Tests

When actions are triggered in different threads concurrently, there is a chance that the value of a later action could override the value of a previous action. This is unintended and can be reproduced in ConcurrentAction.lf. #490 attempted to solve this bug, but in some CI workflows the bug was triggered at a lower probability. In 20 runs of ConcurrentAction.lf, most likely one will fail and the action value would be overwritten.

A more aggressive test, ConcurrentActionRepeat.lf has been created to reproduce this bug. It is similar to ConcurrentAction.lf but runs the concurrent test 100 times. Increasing the threads that trigger the concurrent action in ConcurrentAction.lf would not increase the chance of triggering this bug, because the action.schedule are all lumped together before the actions are popped out of the event queue.

The Concurrency Bug

The concurrency bug originates from the templating of action tokens. Each action has a template that contains a token that is used both to reuse the token and pass the value of the action. During the lifecycle of each action, there are two phases: it is first scheduled and then popped out of the event queue and executed. The first phase uses the template to reuse the token in _lf_initialize_token_with_value which calls _lf_get_token, and the second phase uses the template to pass the value of the token with _lf_replace_template_token.

The unintended action override happens when _lf_initialize_token_with_value changes the template token when another thread is passing action value with the template token. Then the other thread's action value would read the value of the action value just scheduled, which is wrong.

Fix Concurrency Bug

To fix the concurrency bug, we cannot have the to phases both changing the template token. Since phase 2 is heavily used in various different places to pass the token value, it is simpler to change the behavior of _lf_initialize_token_with_value to not modify the template token.

The fix is to not modify the template token in _lf_get_token (which is called in _lf_initialize_token_with_value). Note that token reuse does not cause concurrency bugs since the reference count of 1 means that there is no more use of token value, hence it can be reused safely.

The current implementation has no duplicated actions in 300 runs of ConcurrentActionRepeat.lf.

Derived Fix

Several other bugs were derived when the template token is not replaced during scheduling(which took quite some time to track down). Turns out that some code assumes that the template token has been replaced during _lf_initialize_token_with_value and uses the value and length of the template token. This can be fixed by setting the token to the port and using the value and length of the port token.

@Depetrol Depetrol marked this pull request as ready for review October 18, 2024 19:31
@Depetrol Depetrol requested a review from edwardalee October 18, 2024 21:01
Copy link
Contributor

@edwardalee edwardalee left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. It's surprising that the macro fixes didn't create problems before, but this looks right to me. Maybe point lingua-franca-ref.txt back to master before merging.

@Depetrol
Copy link
Collaborator Author

I'll modify lingua-franca-ref.txt before merging! We might also have to merge lf-lang/lingua-franca#2429 first(I don't have merge access), otherwise some tests will fail.

@lhstrh lhstrh added this pull request to the merge queue Oct 19, 2024
@lhstrh
Copy link
Member

lhstrh commented Oct 19, 2024

Don't worry, I'll update the lingua-franca.txt after merging lf-lang/lingua-franca#2429.

@Depetrol
Copy link
Collaborator Author

Thanks!

Merged via the queue into main with commit 3d7715c Oct 19, 2024
30 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants