37 Proposal for eviction
- Eviction:
- Uses a CSpace lock
- Respects IsEvictable()
- Synchronously calls OnEvict() and that allows for cache map elements to be erased
- Forced eviction:
- is optional
- It runs in a CSpace lock
- It respects IsEvictable()
- It cannot be assumed to evict everything synchronously
- Cache maps:
- use std::map which is not threadsafe, so all access to the map is protected by a CSpace lock
- Eviction occurs with a CSpaceLock and this synchronously erases map entries.
- If a task has been posted but not yet completed then IsEvictable() returns false to prevent a
map entry being erased while there's an associated task.
It is recommended that IObject instances having $indep / $dep or $cache functions are $new'd and GC'd by the CSpace. All DGS examples should be changed to reflect this.
It's not just a recommendation for IObject instances having async $cache functions. In that case the IObjects MUST be heap allocated, so that they are destroyed when it's allowable to do so.
The CSpace has a task executer. This is used by async $cache functions to post async tasks. The task executer is only closed when the CSpace is destroyed.
DGS nodes have an IsEvictable() method which must be respected by the evictor. An async DGS node implements IsEvictable() in such a way that the node cannot be evicted while there is an async task in progress.
While a DGS node is in the eviction queue its containing object is visited by the GC and therefore cannot be destroyed.
task still running --> IsEvictable() returns false
--> DGS node is in the eviction queue
--> DGS node can't be evicted
and containing object can't be deleted.
"Forced eviction" is achieved by calling AlwaysEvict() on a DGS node with a CSpace lock. This tries to evict it synchronously, but if IsEvictable() returns false the node is moved to a different eviction queue which is evicted aggressively by the CSpace GC.
IObjects implement EvictDgsNodes() to perform forced eviction on all their DGS nodes with a CSpace lock. This is called when it is known that an IObject is no longer required (e.g. a view being unlinked) and this helps ensure it evicts all its nodes. Otherwise the object might not be GC'd for a long time (that's only possible when all its DGS nodes have been evicted). EvictDgsNodes() is not required for correctness, it is only required for efficient memory reclamation.