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

Synchronize mutable env in functions #1625

Closed
wants to merge 1 commit into from

Conversation

MarkMcCaskey
Copy link
Contributor

@MarkMcCaskey MarkMcCaskey commented Sep 15, 2020

Resolves #1612

This PR wraps all Envs in std::sync::Mutex ensuring that mutable access cannot happen concurrently. This PR also fixes some undefined behavior / broken code that was accidentally working with VMDynamicFunctionWithEnv.

As a next step, we should design new APIs to give users more control over Env, by for example having an env and env_mut variation where the env variation passes a &Env allowing users to synchronize themselves if they want. Additionally, it may be valuable to add unsafe versions of these functions for power users of the API. Finally, we should investigate if it's possible to allow direct &mut access in a single threaded context with a sound API (by using trait constraints).

Review

  • Add a short description of the the change to the CHANGELOG.md file

@MarkMcCaskey MarkMcCaskey force-pushed the fix/synchronize-mutable-env branch from 5e10ec6 to 514ccf8 Compare September 15, 2020 20:42
@MarkMcCaskey
Copy link
Contributor Author

bors try

bors bot added a commit that referenced this pull request Sep 15, 2020
@bors
Copy link
Contributor

bors bot commented Sep 15, 2020

try

Build succeeded:

@codecov-commenter
Copy link

Codecov Report

Merging #1625 into master will decrease coverage by 0.07%.
The diff coverage is 88.88%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master    #1625      +/-   ##
==========================================
- Coverage   31.75%   31.68%   -0.08%     
==========================================
  Files         185      185              
  Lines       27034    27118      +84     
==========================================
+ Hits         8584     8591       +7     
- Misses      18450    18527      +77     
Impacted Files Coverage Δ
lib/api/src/native.rs 52.94% <ø> (+1.42%) ⬆️
lib/api/src/externals/function.rs 37.61% <88.88%> (+1.69%) ⬆️
lib/compiler-cranelift/src/config.rs 60.00% <0.00%> (-2.50%) ⬇️
lib/compiler-singlepass/src/codegen_x64.rs 34.51% <0.00%> (-0.02%) ⬇️
lib/emscripten/src/lib.rs 0.00% <0.00%> (ø)
lib/wasi/src/lib.rs 36.20% <0.00%> (+4.72%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ccb3fbd...514ccf8. Read the comment docs.

// TODO: the `&mut *self.env.as_ptr()` is likely invoking some "mild"
// undefined behavior due to how it's used in the static fn call
unsafe { (*self.func)(&mut *self.env.as_ptr(), &args) }
let mut env_guard = self.env.lock().unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

I'm not really a fan of this. This is a clear performance penalty that we are now incurring for all function calls.

let func: &Func = unsafe { &*(&() as *const () as *const Func) };
let mut env_guard = env.lock().unwrap();
Copy link
Member

Choose a reason for hiding this comment

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

I'm not really a fan of this. This is a clear performance penalty that we are now incurring for all function calls.

Copy link
Contributor

Choose a reason for hiding this comment

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

We should measure this penalty, because I don't see a lot more options to solve this sync problem.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm completely in favor of measurement, but I'm also sympathetic to wanting a fast path for singlethreaded code which will likely be the majority of uses (at least in the short-term).

Also, I agree that yeah, this change is nice because it just works without much changes. I wrote up a design doc about solutions to this problem and I'll ping people about it next week: I think it's probable that we can make a more complex solution to this problem, but it will require breaking changes to our API or duplicating our API (singlethreaded version vs general version). I also talked about some more exotic options with Nick in regards to things like updating vtables at runtime to dynamically synchronize code when it becomes multithreaded but I don't think we're realistically going to be trying anything fancy any time soon and also I haven't thought of any fancy solutions that aren't a bad trade off in terms of complexity.

@MarkMcCaskey
Copy link
Contributor Author

This PR is not being actively developed, we've decided to pursue #1663 instead

@MarkMcCaskey MarkMcCaskey deleted the fix/synchronize-mutable-env branch November 20, 2020 20:44
bors bot added a commit that referenced this pull request Nov 20, 2020
1663: Make Function Env immutable r=MarkMcCaskey a=MarkMcCaskey


Alternative / related to #1625

Resolves #1612 

# Review

- [x] Add a short description of the the change to the CHANGELOG.md file


Co-authored-by: Mark McCaskey <[email protected]>
Co-authored-by: Mark McCaskey <[email protected]>
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.

Calling a host function with environment in parallel results in data race
4 participants