-
Notifications
You must be signed in to change notification settings - Fork 14
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
Spawn behaviours with a dynamic cown set #23
Conversation
be94f60
to
071a4c4
Compare
bc886c2
to
42cd608
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM. Could you improve the test coverage?
auto log3 = make_cown<Body2>(1); | ||
|
||
cown_ptr_span<Body2> t2{&log3, 1}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this dead code?
auto log3 = make_cown<Body2>(1); | ||
|
||
cown_ptr_span<Body2> t2{&log3, 1}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this dead code?
|
||
cown_ptr_span<Body2> t2{&log3, 1}; | ||
|
||
when(t1, log1) << [=](acquired_cown_span<Body1> ca, acquired_cown<Body1> a) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add a few more complex sequences here to ensure coverage of first and last being different things:
- span, cown
- cown, span
- span, span
- span, cown, span
- cown, span, cown
@@ -0,0 +1,102 @@ | |||
// Copyright Microsoft and Project Verona Contributors. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add test coverage for move versus copy of cown span
when (span) { ... }
versus
when (std::move(span)) { ... }
src/rt/cpp/when.h
Outdated
size_t actual_size = | ||
ptr_span.length * sizeof(ActualCown<std::remove_const_t<T>>*); | ||
size_t acq_size = | ||
ptr_span.length * sizeof(acquired_cown<std::remove_const_t<T>>); | ||
span.array = reinterpret_cast<ActualCown<std::remove_const_t<T>>**>( | ||
snmalloc::ThreadAlloc::get().alloc(actual_size + acq_size)); | ||
|
||
for (size_t i = 0; i < ptr_span.length; i++) | ||
{ | ||
span.array[i] = ptr_span.array[i].allocated_cown; | ||
} | ||
span.length = ptr_span.length; | ||
|
||
acq_array = | ||
reinterpret_cast<acquired_cown<T>*>((char*)(span.array) + actual_size); | ||
|
||
for (size_t i = 0; i < ptr_span.length; i++) | ||
{ | ||
new (&acq_array[i]) acquired_cown<T>(*ptr_span.array[i].allocated_cown); | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you factor out the code duplication here from the above constructor. Thanks
64c9b98
to
23259c5
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mostly minute stuff now. Would be nice if there were a few more comments. But it's looking great.
src/rt/cpp/when.h
Outdated
cown_ptr_span(cown_ptr_span&& old) = delete; | ||
cown_ptr_span& operator=(cown_ptr_span&&) = delete; | ||
cown_ptr_span& operator=(const cown_ptr_span&) = delete; | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why are these operators deleted? Could you add a comment to explain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to be deleted. They are not used in the current codebase. So, I marked them as deleted to avoid bugs in auto generated. I'll add a comment to clarify.
src/rt/cpp/when.h
Outdated
{ | ||
array = reinterpret_cast<cown_ptr<T>*>( | ||
snmalloc::ThreadAlloc::get().alloc(length * sizeof(cown_ptr<T>*))); | ||
memset(array, 0, length * sizeof(cown_ptr<T>*)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why memset? The next loop overwrites everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because the cown_ptr
copy assignment operator does a clear()
first. I'll remove the memset and call the copy constructor with new (&array[i]) cown_ptr<T>(arr[i])
instead.
src/rt/cpp/when.h
Outdated
template<typename T> | ||
struct cown_ptr_span | ||
{ | ||
cown_ptr<T>* array; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you add comments about ownership here? Is this class opening the underlying cownptrs or borrowing them. Explaining that, and then adding comments elsewhere.
Does std::move make sense if they are borrowed? Hadn't thought about this for my earlier review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's clearer if cown_ptr_span
always owns the included cowns. This can happen either by allocating a new cown_ptr array and incrementing the reference count, or by using the template parameter and passing an array of cown_ptr that already holds the ownership.
I added a comment that explains that.
43ffdef
to
4c66aea
Compare
src/rt/cpp/cown_span.h
Outdated
* allocated array. | ||
*/ | ||
template<typename T> | ||
struct cown_ptr_span |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I have one minor thing given this is an owning array. I think we should perhaps call it: cown_array
. I think of span
as borrowed, and not owning the underlying memory. But this does, so I think the current name will given the wrong idea.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure I can do that. I thought that owning made more sense and made things simpler. Alternatively, we can keep the span
semantics and prevent from passing it with move
. What do you think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think owning is the right choice. Let's rename.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ack
src/rt/cpp/when.h
Outdated
ActualCownSpan& operator=(ActualCownSpan&& old) | ||
{ | ||
if (array) | ||
snmalloc::ThreadAlloc::get().dealloc(array); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is performing deallocation, so doesn't this require ownership?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This array holds ActualCown<T>
, though, not cown_ptr<T>
. If I understand correctly, when this array is constructed there is no reference count increase.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, yeah, so ActualCown is kind of borrowing from the underlying cown_ptr. Makes sense, do you think you could add a comment, so we don't get confused again. Possibly add a comment to ActualCown too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should there be a destructor to deallocate the array too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right. ActualCown borrows from the underlying cown_array. I'll add the comment.
You are also correct about the confusion with the dealloc. This is wrong and it shouldn't be there. The lifetime of the ActualCownSpan is always the same as the AccessBatch. The memory the span uses is managed by the AccessBatch constructors and destructors. There is no need for a move assignment operator. I'll remove that.
The lifetime of the Access and AccessBatch goes all the way till after the execution of the behaviour.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Given that this the case, should the ActualCownSpan be defined inside the AccessBatch?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah. So ActualCownSpan
is different to ActualCown
. ActualCown
is the Verona runtimes view of a cown, where as ActualCownSpan
is part of the behaviour structure. I think moving it into AccessBatch makes sense, I also wonder if it should be Actual...
, but differently named?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, it should be ActualCownPtrSpan
since it's an array of pointers to ActualCown
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ignore it. It's not necessary and it's only confusing. I'm removing it completely.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM, could you remove the dead code.
src/rt/cpp/when.h
Outdated
#if 0 | ||
/** | ||
* This is a non-owning span of ActualCown pointers | ||
* Its lifetime is always the same as the AccessBatch. | ||
*/ | ||
struct ActualCownPtrSpan | ||
{ | ||
ActualCown<std::remove_const_t<T>>** array; | ||
size_t length; | ||
|
||
void clear() | ||
{ | ||
length = 0; | ||
array = nullptr; | ||
} | ||
|
||
ActualCownPtrSpan() | ||
{ | ||
clear(); | ||
} | ||
|
||
ActualCownPtrSpan(ActualCownPtrSpan&& old) | ||
{ | ||
length = old.length; | ||
array = old.array; | ||
old.clear(); | ||
} | ||
}; | ||
#endif | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#if 0 | |
/** | |
* This is a non-owning span of ActualCown pointers | |
* Its lifetime is always the same as the AccessBatch. | |
*/ | |
struct ActualCownPtrSpan | |
{ | |
ActualCown<std::remove_const_t<T>>** array; | |
size_t length; | |
void clear() | |
{ | |
length = 0; | |
array = nullptr; | |
} | |
ActualCownPtrSpan() | |
{ | |
clear(); | |
} | |
ActualCownPtrSpan(ActualCownPtrSpan&& old) | |
{ | |
length = old.length; | |
array = old.array; | |
old.clear(); | |
} | |
}; | |
#endif | |
10debf8
to
2bf3458
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
No description provided.