Description
Parent: #850
Problem
There are periods in GC when we know some work packets have exclusive access to the Plan
instance. Examples include Prepare
, Release
and EndOfGC
. The problem is, we know this fact as humans, but the Rust programming language cannot check if that work packet has exclusive access to Plan
, using either compile-time checking or run-time checking. Therefore, we worked around this by casting &Plan
to &mut Plan
Possible solution
Because of the dynamic nature of MMTk-VM interaction and the work packet system, it is hard to check whether a thread is the only thread that can access a data structure.
But it is possible to do this dynamically using reference counting. If we can count how many threads have access to a given data structure (for example, MMTk, or Plan), we can let the users "yield" their right to access to that data structure. Once we are sure all read-only users yielded, we can grant another thread (the one running Prepare
or other work packets) read-write access. It is checked at run time. If a thread attempts to get read-write access while the read-only user count is greater than 0, it shall panic (which is not as good as compile-time checking in which case unsafe code doesn't compile).
p.s. The same idea can be applied to the parking of GC worker threads. If all workers parked, the last GC worker can gain read-write access and modify work buckets states.
AtomicRefCell
is the closest tool for this need. However, AtomicRefCell
requires the "handle" instances (Borrow
and BorrowMut
) to live within the lifetime of the AtomicRefCell
itself, with compile-time lifetime checking. Because of this limitation, we can't send the Borrow<T>
handle to another thread.
I once made a proof-of-concept project for "lending" some owned data to another thread, with run-time checking. The main difference is, the compiler will not prevent the handles from being sent to other threads. But if the owner of the object dies while it is still lent, it panics. (Sorry. In such a dynamic environment, there is not much the compiler can do.)