Duplicate :
|
|
Relates :
|
|
Relates :
|
We add / remove entries to / from the region stack in the ConcurrentMark class using the region_stack_push() / region_stack_pop() methods. The assumption for those methods is that region_stack_push() will only be called during evacuation pauses and the region_stack_pop() will only be called during concurrent marking. So, their implementation which is based on CAS is safe as long as we only call one of those methods concurrently by multiple threads but not both. Unfortunately, there's a case where both can be called concurrently: during marking we mostly call region_stack_pop() to process entries from the region stack. But if we get a safepoint while we're processing one of the entries we will use region_stack_push() to push the remainder of the region we're processing so that we can carry on processing it in the future. And if we call region_stack_push() / region_stack_pop() concurrently, the results are undefined (i.e., the pop method can decrement the index and read the contents from the array before the push method has actaully installed them).
|