Duration of Object Pinning
I am just being pedantic about the semantics of object pinning. The current "object pinning" is vague w.r.t. the duration of pinning.
Now that we define global cells as always pinned to support relocations for raw pointers, there are two different scopes of pinning. An object is pinned iff
- it is a global cell, or
- it is in the "pin set" of a thread.
The purpose of the so-called "pin set" is to make pinning operations locally scoped: It is like a per-thread reference-count rather than global referenece-count. If copying GC never happens, threads only need to modify local thread states rather than global states.
Consequently, the thread state of one thread may not be visible (or consistent w.r.t. concurrency) to other threads, hence the phrase "is in the pin set" is vague: whether a memory location is pinned depends on the observer.
But there is one guarantee the micro VM must make:
During the time when a memory location is pinned, its address must not change, at least as observed by the same Mu thread which executes C functions while pinned. So naturally we can define that the thread that pins the location must not observe the address changed between its own pinning and unpinning. So if two threads independently pin and then unpin the same Mu object concurrently without any synchronisation, they may observe different addresses, because their durations may not overlap, and GC may happen in between. If the two threads do not communicate and their C functions do not save the pointers, it should just work even if the object is moved while not pinned.
But more interesting questions may arise if we consider inter-thread communication: If
- one thread T1 pins an object O1, then
- sends the address of O1 to another thread O2, then
- O2 pins the same object O2, then sends a message to T1, then
- T1 unpins O1, and
- T2 independently unpins O1
Then should O1 have constant address since T1 pins O1 until both T1 and T2 unpins O1? If we interpret "sending a message" as "forming a happens-before relation", then the whole process looks pretty sequential.
We can use the "happens-before" relation to define the duration of pinning, so that the pinning/unpinning operations from different threads can chain up. Then some Mu objects may have a very long duration of pinning, during which it has constant address. This is not a problem, at least not more problematic than one single thread pinning an object for a really long time. We just need to precisely define the duration of pinning so that the client can depend on it.
I still don't know how to precisely express it. This is definitely trickier than the visibility rules for LOAD/STORE operations because this time it is about duration rather than just a value. The easiest model, of course, is to make pinning/unpinning sequentially consistent, but I wonder if it would require excessive fencing to prevent weird behaviours in something like:
- T1 pins O1 and sends a message to T2, then
- T2 pins O2 and sends a message to T3, then
- the programmer thinks T3 should see O1 being pinned, but observed otherwise.