8276047: G1: refactor G1CardSetArrayLocker
Reviewed-by: tschatzl, sjohanss
This commit is contained in:
parent
e922023ec9
commit
24cf48000a
@ -196,19 +196,19 @@ private:
|
|||||||
static const EntryCountType EntryMask = LockBitMask - 1;
|
static const EntryCountType EntryMask = LockBitMask - 1;
|
||||||
|
|
||||||
class G1CardSetArrayLocker : public StackObj {
|
class G1CardSetArrayLocker : public StackObj {
|
||||||
EntryCountType volatile* _value;
|
EntryCountType volatile* _num_entries_addr;
|
||||||
EntryCountType volatile _original_value;
|
EntryCountType _local_num_entries;
|
||||||
bool _success;
|
|
||||||
public:
|
public:
|
||||||
G1CardSetArrayLocker(EntryCountType volatile* value);
|
G1CardSetArrayLocker(EntryCountType volatile* value);
|
||||||
|
|
||||||
EntryCountType num_entries() const { return _original_value; }
|
EntryCountType num_entries() const { return _local_num_entries; }
|
||||||
void inc_num_entries() { _success = true; }
|
void inc_num_entries() {
|
||||||
|
assert(((_local_num_entries + 1) & EntryMask) == (EntryCountType)(_local_num_entries + 1), "no overflow" );
|
||||||
|
_local_num_entries++;
|
||||||
|
}
|
||||||
|
|
||||||
~G1CardSetArrayLocker() {
|
~G1CardSetArrayLocker() {
|
||||||
assert(((_original_value + _success) & EntryMask) == (EntryCountType)(_original_value + _success), "precondition!" );
|
Atomic::release_store(_num_entries_addr, _local_num_entries);
|
||||||
|
|
||||||
Atomic::release_store(_value, (EntryCountType)(_original_value + _success));
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -145,22 +145,21 @@ inline G1CardSetArray::G1CardSetArray(uint card_in_region, EntryCountType num_el
|
|||||||
_data[0] = card_in_region;
|
_data[0] = card_in_region;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline G1CardSetArray::G1CardSetArrayLocker::G1CardSetArrayLocker(EntryCountType volatile* value) :
|
inline G1CardSetArray::G1CardSetArrayLocker::G1CardSetArrayLocker(EntryCountType volatile* num_entries_addr) :
|
||||||
_value(value),
|
_num_entries_addr(num_entries_addr) {
|
||||||
_success(false) {
|
|
||||||
SpinYield s;
|
SpinYield s;
|
||||||
EntryCountType original_value = (*_value) & EntryMask;
|
EntryCountType num_entries = Atomic::load(_num_entries_addr) & EntryMask;
|
||||||
while (true) {
|
while (true) {
|
||||||
EntryCountType old_value = Atomic::cmpxchg(_value,
|
EntryCountType old_value = Atomic::cmpxchg(_num_entries_addr,
|
||||||
original_value,
|
num_entries,
|
||||||
(EntryCountType)(original_value | LockBitMask));
|
(EntryCountType)(num_entries | LockBitMask));
|
||||||
if (old_value == original_value) {
|
if (old_value == num_entries) {
|
||||||
// Succeeded locking the array.
|
// Succeeded locking the array.
|
||||||
_original_value = original_value;
|
_local_num_entries = num_entries;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
// Failed. Retry (with the lock bit stripped again).
|
// Failed. Retry (with the lock bit stripped again).
|
||||||
original_value = old_value & EntryMask;
|
num_entries = old_value & EntryMask;
|
||||||
s.wait();
|
s.wait();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user