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
I ran into an error while experimenting with round-robin thread scheduling, and it raised the question for me of whether protectors should only be considered active from the context of the same thread that they were created on, or whether protectors should be considered active regardless of the thread that is performing the access. This came up with an atomically reference counted data structure, and I don't see any way of fundamentally avoiding the issue by making changes to the data structure's code. If we use std atomics, then each thread that decrements a refcount will hold a shared reference inside the allocation, and that reference could be on the stack arbitrarily long after decrementing, if the thread is preempted. Then, other threads would be able to see the decrement and free the allocation, while that first thread's reference still exists. I wrote a minimized test case that can reproduce the error I encountered, regardless of thread scheduling policy.
I'm not sure which way this should go. On the one hand, I could read references to "the call stack" as referring to the current call stack, in which case we could make the active protector set per-thread in Miri and this would go away. On the other hand, this would open the possibility of a dangling reference in a local, and I'm not sure whether that's allowed, even if it's not accessed once it's dangling. Perhaps the deallocation check could be made more permissive while leaving access checks as they are? Alternately, what if Arc and similar data structures require new APIs that take *const AtomicUsize, for cases where the pointer could become dangling right after the synchronization operation? I'd appreciate your thoughts; let me know if this should go in the UCG repo.
The text was updated successfully, but these errors were encountered:
I do think that the interaction of protectors and concurrency in terms of what happens in Miri right now is exactly as intended... but protectors do indeed cause problems for some kinds of code that arises more typically for fine-grained concurrent data structures. This looks to me like another instance of rust-lang/rust#55005, also tracked at rust-lang/unsafe-code-guidelines#88. Crossbeam also runs into this I think (crossbeam-rs/crossbeam#545).
If that analysis is accurate, I'd close this issue as it is not a Miri implementation problem, but a Stacked Borrows specification or language design problem.
I ran into an error while experimenting with round-robin thread scheduling, and it raised the question for me of whether protectors should only be considered active from the context of the same thread that they were created on, or whether protectors should be considered active regardless of the thread that is performing the access. This came up with an atomically reference counted data structure, and I don't see any way of fundamentally avoiding the issue by making changes to the data structure's code. If we use std atomics, then each thread that decrements a refcount will hold a shared reference inside the allocation, and that reference could be on the stack arbitrarily long after decrementing, if the thread is preempted. Then, other threads would be able to see the decrement and free the allocation, while that first thread's reference still exists. I wrote a minimized test case that can reproduce the error I encountered, regardless of thread scheduling policy.
I'm not sure which way this should go. On the one hand, I could read references to "the call stack" as referring to the current call stack, in which case we could make the active protector set per-thread in Miri and this would go away. On the other hand, this would open the possibility of a dangling reference in a local, and I'm not sure whether that's allowed, even if it's not accessed once it's dangling. Perhaps the deallocation check could be made more permissive while leaving access checks as they are? Alternately, what if
Arc
and similar data structures require new APIs that take*const AtomicUsize
, for cases where the pointer could become dangling right after the synchronization operation? I'd appreciate your thoughts; let me know if this should go in the UCG repo.The text was updated successfully, but these errors were encountered: