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

Introduce ThreadContext instead of execution depth #726

Closed
wants to merge 8 commits into from

Conversation

chfast
Copy link
Collaborator

@chfast chfast commented Feb 4, 2021

Replace depth param in execute() functions with ThreadContext&.
The ThreadContext encapsulates the depth control from now on and is
extensible. In future it can support metering and better stack space
allocation.

Call depth control semantic is preserved, except the depth is now passed by reference (aka int& depth) so additional context guard is needed in places where depth is being bumped.

In C the ThreadContext is opaque what is good for API, but it is impossible to dump the depth inside a C host function.

This is baseline for PoC thread context extensions proposed in #529 and #572. Rebasing these is impossible, but the rest of the changes from there should be re-applied later.

@codecov
Copy link

codecov bot commented Feb 4, 2021

Codecov Report

Merging #726 (62cfb87) into master (5028558) will decrease coverage by 0.01%.
The diff coverage is 97.51%.

@@            Coverage Diff             @@
##           master     #726      +/-   ##
==========================================
- Coverage   99.34%   99.32%   -0.02%     
==========================================
  Files          73       72       -1     
  Lines       11142    10696     -446     
==========================================
- Hits        11069    10624     -445     
+ Misses         73       72       -1     
Flag Coverage Δ
rust ?
spectests 90.88% <100.00%> (+0.03%) ⬆️
unittests 99.32% <97.51%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Impacted Files Coverage Δ
lib/fizzy/instantiate.hpp 100.00% <ø> (ø)
tools/wasi/wasi.cpp 57.30% <20.00%> (ø)
lib/fizzy/capi.cpp 98.93% <100.00%> (+0.01%) ⬆️
lib/fizzy/execute.cpp 100.00% <100.00%> (ø)
lib/fizzy/execute.hpp 100.00% <100.00%> (ø)
lib/fizzy/instantiate.cpp 100.00% <100.00%> (ø)
test/unittests/api_test.cpp 100.00% <100.00%> (ø)
test/unittests/capi_test.cpp 99.87% <100.00%> (-0.01%) ⬇️
test/unittests/execute_call_test.cpp 100.00% <100.00%> (ø)
test/unittests/execute_test.cpp 100.00% <100.00%> (ø)
... and 4 more

@chfast chfast force-pushed the thread_context branch 3 times, most recently from 4aa51c4 to 7d287f0 Compare February 4, 2021 20:06
@chfast chfast requested review from gumb0 and axic and removed request for gumb0 February 4, 2021 20:15
class ThreadContext
{
public:
int depth = 0;
Copy link
Member

Choose a reason for hiding this comment

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

So there's no way to set a different starting depth?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

You can ctx.depth = 1, as in tests.

Copy link
Member

Choose a reason for hiding this comment

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

Should we expose it? In any case if we it should be just a separate PR for the C API (and then Rust). It is fine to hide it in this PR.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

In C the ThreadContext is opaque what is good for API, but it is impossible to dump the depth inside a C host function.

Copy link
Member

Choose a reason for hiding this comment

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

Well we would need C++ helpers for it first, right? :)

@@ -21,8 +21,31 @@ namespace fizzy
struct ExecutionResult;
struct Instance;

class ThreadContext
Copy link
Member

Choose a reason for hiding this comment

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

Why do we go with the term thread? Is this future proofing for multithreaded wasm? Is some kind of locking planned, given the memory (to begin with) is still part of the instance and not the thread.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

It has nothing to do with multithreading. I is just execution thread context (in principle, you can create multiple thread context and start multiple call stacks in parallel). I understand the name may be confusing although WABT uses the same name for this concept. We can consider alternative names.

Copy link
Member

Choose a reason for hiding this comment

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

I think it would be a good name, but given wasm multithreading this may be confusing. Would this be applicable during that? Would something like ExecutionContext be less confusing, or equally confusing as it is partial too?

@chfast chfast requested a review from gumb0 February 5, 2021 09:05
lib/fizzy/instantiate.hpp Outdated Show resolved Hide resolved
bindings/rust/src/lib.rs Outdated Show resolved Hide resolved
@@ -20,6 +20,8 @@ typedef struct FizzyModule FizzyModule;
/// The opaque data type representing an instance (instantiated module).
typedef struct FizzyInstance FizzyInstance;

typedef struct FizzyThreadContext FizzyThreadContext;
Copy link
Member

Choose a reason for hiding this comment

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

Should have a comment, see FizzyInstance above.

public:
int depth = 0;

void acquire() noexcept { ++depth; }
Copy link
Member

Choose a reason for hiding this comment

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

Do these need to be public? Are these supposed to be used directly or only via the Guard?

@@ -21,8 +21,31 @@ namespace fizzy
struct ExecutionResult;
struct Instance;

class ThreadContext
Copy link
Member

Choose a reason for hiding this comment

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

Should have some level of documentaiton.

Instance& instance, FuncIdx func_idx, const Value* args, ThreadContext& ctx);

/// Execute a function from an instance starting at default depth of 0.
inline ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args)
Copy link
Member

Choose a reason for hiding this comment

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

Is this version used heavily in the tests?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes.

@@ -318,7 +318,9 @@ TEST(capi, find_exported_function)
EXPECT_EQ(function.type.output, FizzyValueTypeI32);
EXPECT_NE(function.context, nullptr);
ASSERT_NE(function.function, nullptr);
EXPECT_THAT(function.function(function.context, instance, nullptr, 0), CResult(42_u32));

// FIXME: thread context missing.
Copy link
Member

Choose a reason for hiding this comment

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

This should be fixed before merging I guess?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This is not fixable if ThreadContext to stay opaque in C.

@axic
Copy link
Member

axic commented Feb 5, 2021

Looks great in general!

@axic
Copy link
Member

axic commented Feb 5, 2021

I think there should be a benchmark run after the comments are addressed and before this is merged, to see what is the effect, if any.

Replace depth param in execute() functions with ThreadContext&.
The ThreadContext encapsulates the depth control from now on and is
extensible. In future it can support metering and better stack space
allocation.

Call depth control semantic is preserved, except the depth is now passed
by reference (aka `int& depth`) so additional context guard is needed in
places where depth is being bumped.
public:
int depth = 0;

Guard bump_call_depth() noexcept
Copy link
Collaborator

Choose a reason for hiding this comment

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

Hm, this returns private class, I wouldn't think it's possible...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Maybe call it increment_call_depth, bump sounds a bit informal it seems.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Just an idea: it could be execute member function of ThreadContext bumping depth and redirecting to normal execute

    ExecutionResult execute(Instance& instance, FuncIdx func_idx, const Value* args) noexcept;

then Guard can be completely hidden from user.

But maybe confusingly too many execute variants then.

auto sub = [&instance1, func_idx](Instance&, const Value* args, int depth) -> ExecutionResult {
return fizzy::execute(*instance1, *func_idx, args, depth);
auto sub = [&instance1, func_idx](Instance&, const Value* args, ThreadContext& ctx) {
// ThreadContext is bumped here.
Copy link
Collaborator

Choose a reason for hiding this comment

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

I was a bit confused by this comment. I think you mean at this point it was already bumped by the caller?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Probably should be "is not bumped". And it should be according to the current semantic.

@chfast
Copy link
Collaborator Author

chfast commented Feb 10, 2021

I will rename it to ExecutionContext.

@gumb0
Copy link
Collaborator

gumb0 commented Feb 10, 2021

I will rename it to ExecutionContext.

What I don't like about ExecutionContext is that void* context in C API also can be thought of as "execution context". But I don't have a better name.

@chfast
Copy link
Collaborator Author

chfast commented Mar 23, 2021

Replaced by #766.

@chfast chfast closed this Mar 23, 2021
@chfast chfast deleted the thread_context branch March 23, 2021 13:09
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.

3 participants