You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
// requests: Vec<Request>for req in&behaviour.requests{unsafe{// correct// req is &Request, still reference to the instance on heap
req.release();}}
Solution
Regarding that, I think request should be marked as immovable.
One solution to this issue would be to modify Vec<Request> to Pin<Box<[Request]>>, which would prevent the unintentional move.
// requests: Pin<Box<[Request]>>for req in behaviour.requests{unsafe{// complier error: `Pin<Box<[Request]>>` is not an iterator
req.release();}}// requests: Pin<Box<[Request]>>for req in behaviour.requests.into_iter(){unsafe{// ok: req is &Request
req.release();}}
Drawback
Now, if we want to iterate through requests, we need to call iter() or dereference it first.
for req in behaviour.requests// complier error: `Pin<Box<[Request]>>` is not an iterator
for req in&behaviour.requests// complier error: `&Pin<Box<[Request]>>` is not an iterator
for req in&*behaviour.requests// ok
for req in behaviour.requests.iter()// okfor req in behaviour.requests.into_iter()// ok
Unresolved questions
There is still a way to invalidate the last pointer.
Fortunately, these two examples could both be considered logical errors.
It breaks requests must be sorted assumption.
Behavior should only access its own requests.
And these errors are easy to avoid, just: Don't let behaviour mutable.
In fact, I think it's a logical error to declare a mutable behavior variable.
The optimal solution to this problem may be to utilize either Vec<Pin<Box<Request>>>> or Vec<Arc<Request>>, I haven't tested it yet.
But both approaches incur some overhead costs, so I think Pin<Box<[Request]>> is sufficient.
The text was updated successfully, but these errors were encountered:
Hmm... I think you are correct. IIRC efficiently implementing boc while making sure move between heap/stack was ok was really annoying, and we had many problems similar to the one you have now.
I'm busy right now, so won't be able to look at it for a couple of weeks. But I will make sure to fix it.
However, this change may greatly reduce the difficulty of the BoC homework.
Interestingly, it's safe to move behavior onto the stack in resolve_one() because there is no longer a next pointer to this behavior. (I set next to null in the last line of release())
unsafefnresolve_one(this:*constSelf){/* ... */let behavior:Box<Behavior> = unsafe{Box::from_raw(this)};let behavior = *behavior;// It is safe but useless
rayon::spawn(move || {/* ... */});}
First of all, thanks to all CS431 course instructors for providing such good learning materials about Concurrent Programming.
Pitfall
When I implement BoC runtime, I wrote this code snip.
It turns out that this simple code contains a nasty bug.
The correct way to iterate through
requests
is:Solution
Regarding that, I think
request
should be marked as immovable.One solution to this issue would be to modify
Vec<Request>
toPin<Box<[Request]>>
, which would prevent the unintentional move.Drawback
Now, if we want to iterate through
requests
, we need to calliter()
or dereference it first.Unresolved questions
There is still a way to invalidate the
last
pointer.Fortunately, these two examples could both be considered logical errors.
And these errors are easy to avoid, just: Don't let behaviour mutable.
In fact, I think it's a logical error to declare a mutable
behavior
variable.The optimal solution to this problem may be to utilize either
Vec<Pin<Box<Request>>>>
orVec<Arc<Request>>
, I haven't tested it yet.But both approaches incur some overhead costs, so I think
Pin<Box<[Request]>>
is sufficient.The text was updated successfully, but these errors were encountered: