52 const uint32_t seqnum_initializing = (uint32_t)-1; |
52 const uint32_t seqnum_initializing = (uint32_t)-1; |
53 bool contention = false; |
53 bool contention = false; |
54 |
54 |
55 // Multiple threads can enter here, make sure only one of them |
55 // Multiple threads can enter here, make sure only one of them |
56 // resets the marking information while the others busy wait. |
56 // resets the marking information while the others busy wait. |
57 for (uint32_t seqnum = _seqnum; seqnum != ZGlobalSeqNum; seqnum = _seqnum) { |
57 for (uint32_t seqnum = OrderAccess::load_acquire(&_seqnum); |
|
58 seqnum != ZGlobalSeqNum; |
|
59 seqnum = OrderAccess::load_acquire(&_seqnum)) { |
58 if ((seqnum != seqnum_initializing) && |
60 if ((seqnum != seqnum_initializing) && |
59 (Atomic::cmpxchg(seqnum_initializing, &_seqnum, seqnum) == seqnum)) { |
61 (Atomic::cmpxchg(seqnum_initializing, &_seqnum, seqnum) == seqnum)) { |
60 // Reset marking information |
62 // Reset marking information |
61 _live_bytes = 0; |
63 _live_bytes = 0; |
62 _live_objects = 0; |
64 _live_objects = 0; |
63 |
65 |
64 // Clear segment claimed/live bits |
66 // Clear segment claimed/live bits |
65 segment_live_bits().clear(); |
67 segment_live_bits().clear(); |
66 segment_claim_bits().clear(); |
68 segment_claim_bits().clear(); |
67 |
69 |
68 // Make sure the newly reset marking information is |
70 assert(_seqnum == seqnum_initializing, "Invalid"); |
69 // globally visible before updating the page seqnum. |
|
70 OrderAccess::storestore(); |
|
71 |
71 |
72 // Update seqnum |
72 // Make sure the newly reset marking information is ordered |
73 assert(_seqnum == seqnum_initializing, "Invalid"); |
73 // before the update of the page seqnum, such that when the |
74 _seqnum = ZGlobalSeqNum; |
74 // up-to-date seqnum is load acquired, the bit maps will not |
|
75 // contain stale information. |
|
76 OrderAccess::release_store(&_seqnum, ZGlobalSeqNum); |
75 break; |
77 break; |
76 } |
78 } |
77 |
79 |
78 // Mark reset contention |
80 // Mark reset contention |
79 if (!contention) { |
81 if (!contention) { |
91 bool contention = false; |
93 bool contention = false; |
92 |
94 |
93 if (!claim_segment(segment)) { |
95 if (!claim_segment(segment)) { |
94 // Already claimed, wait for live bit to be set |
96 // Already claimed, wait for live bit to be set |
95 while (!is_segment_live(segment)) { |
97 while (!is_segment_live(segment)) { |
96 // Busy wait. The loadload barrier is needed to make |
|
97 // sure we re-read the live bit every time we loop. |
|
98 OrderAccess::loadload(); |
|
99 |
|
100 // Mark reset contention |
98 // Mark reset contention |
101 if (!contention) { |
99 if (!contention) { |
102 // Count contention once |
100 // Count contention once |
103 ZStatInc(ZCounterMarkSegmentResetContention); |
101 ZStatInc(ZCounterMarkSegmentResetContention); |
104 contention = true; |
102 contention = true; |