mirror of
https://github.com/openjdk/jdk.git
synced 2026-01-28 03:58:21 +00:00
8372565: Convert SATBMarkQueue to use Atomic<T>
Reviewed-by: tschatzl, shade, iwalulya
This commit is contained in:
parent
70b4eb249e
commit
0021dc0410
@ -27,6 +27,7 @@
|
||||
|
||||
#include "cppstdlib/limits.hpp"
|
||||
#include "gc/shared/freeListAllocator.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
#include "utilities/debug.hpp"
|
||||
#include "utilities/globalDefinitions.hpp"
|
||||
#include "utilities/lockFreeStack.hpp"
|
||||
@ -38,7 +39,7 @@ class BufferNode {
|
||||
|
||||
InternalSizeType _index;
|
||||
InternalSizeType _capacity;
|
||||
BufferNode* volatile _next;
|
||||
Atomic<BufferNode*> _next;
|
||||
void* _buffer[1]; // Pseudo flexible array member.
|
||||
|
||||
BufferNode(InternalSizeType capacity)
|
||||
@ -58,11 +59,11 @@ public:
|
||||
return std::numeric_limits<InternalSizeType>::max();
|
||||
}
|
||||
|
||||
static BufferNode* volatile* next_ptr(BufferNode& bn) { return &bn._next; }
|
||||
static Atomic<BufferNode*>* next_ptr(BufferNode& bn) { return &bn._next; }
|
||||
typedef LockFreeStack<BufferNode, &next_ptr> Stack;
|
||||
|
||||
BufferNode* next() const { return _next; }
|
||||
void set_next(BufferNode* n) { _next = n; }
|
||||
BufferNode* next() const { return _next.load_relaxed(); }
|
||||
void set_next(BufferNode* n) { _next.store_relaxed(n); }
|
||||
size_t index() const { return _index; }
|
||||
|
||||
void set_index(size_t i) {
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#include "logging/log.hpp"
|
||||
#include "memory/allocation.inline.hpp"
|
||||
#include "oops/oop.inline.hpp"
|
||||
#include "runtime/atomicAccess.hpp"
|
||||
#include "runtime/mutexLocker.hpp"
|
||||
#include "runtime/os.hpp"
|
||||
#include "runtime/safepoint.hpp"
|
||||
@ -85,28 +84,28 @@ SATBMarkQueueSet::~SATBMarkQueueSet() {
|
||||
// remains set until the count is reduced to zero.
|
||||
|
||||
// Increment count. If count > threshold, set flag, else maintain flag.
|
||||
static void increment_count(volatile size_t* cfptr, size_t threshold) {
|
||||
static void increment_count(Atomic<size_t>* cfptr, size_t threshold) {
|
||||
size_t old;
|
||||
size_t value = AtomicAccess::load(cfptr);
|
||||
size_t value = cfptr->load_relaxed();
|
||||
do {
|
||||
old = value;
|
||||
value += 2;
|
||||
assert(value > old, "overflow");
|
||||
if (value > threshold) value |= 1;
|
||||
value = AtomicAccess::cmpxchg(cfptr, old, value);
|
||||
value = cfptr->compare_exchange(old, value);
|
||||
} while (value != old);
|
||||
}
|
||||
|
||||
// Decrement count. If count == 0, clear flag, else maintain flag.
|
||||
static void decrement_count(volatile size_t* cfptr) {
|
||||
static void decrement_count(Atomic<size_t>* cfptr) {
|
||||
size_t old;
|
||||
size_t value = AtomicAccess::load(cfptr);
|
||||
size_t value = cfptr->load_relaxed();
|
||||
do {
|
||||
assert((value >> 1) != 0, "underflow");
|
||||
old = value;
|
||||
value -= 2;
|
||||
if (value <= 1) value = 0;
|
||||
value = AtomicAccess::cmpxchg(cfptr, old, value);
|
||||
value = cfptr->compare_exchange(old, value);
|
||||
} while (value != old);
|
||||
}
|
||||
|
||||
@ -332,7 +331,7 @@ void SATBMarkQueueSet::print_all(const char* msg) {
|
||||
#endif // PRODUCT
|
||||
|
||||
void SATBMarkQueueSet::abandon_completed_buffers() {
|
||||
AtomicAccess::store(&_count_and_process_flag, size_t(0));
|
||||
_count_and_process_flag.store_relaxed(0u);
|
||||
BufferNode* buffers_to_delete = _list.pop_all();
|
||||
while (buffers_to_delete != nullptr) {
|
||||
BufferNode* bn = buffers_to_delete;
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2001, 2025, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
@ -29,6 +29,7 @@
|
||||
#include "memory/allocation.hpp"
|
||||
#include "memory/padded.hpp"
|
||||
#include "oops/oopsHierarchy.hpp"
|
||||
#include "runtime/atomic.hpp"
|
||||
|
||||
class Thread;
|
||||
class Monitor;
|
||||
@ -87,7 +88,7 @@ class SATBMarkQueueSet: public PtrQueueSet {
|
||||
|
||||
DEFINE_PAD_MINUS_SIZE(1, DEFAULT_PADDING_SIZE, 0);
|
||||
PaddedEnd<BufferNode::Stack> _list;
|
||||
volatile size_t _count_and_process_flag;
|
||||
Atomic<size_t> _count_and_process_flag;
|
||||
// These are rarely (if ever) changed, so same cache line as count.
|
||||
size_t _process_completed_buffers_threshold;
|
||||
size_t _buffer_enqueue_threshold;
|
||||
@ -148,12 +149,12 @@ public:
|
||||
// The number of buffers in the list. Racy and not updated atomically
|
||||
// with the set of completed buffers.
|
||||
size_t completed_buffers_num() const {
|
||||
return _count_and_process_flag >> 1;
|
||||
return _count_and_process_flag.load_relaxed() >> 1;
|
||||
}
|
||||
|
||||
// Return true if completed buffers should be processed.
|
||||
bool process_completed_buffers() const {
|
||||
return (_count_and_process_flag & 1) != 0;
|
||||
return (_count_and_process_flag.load_relaxed() & 1) != 0;
|
||||
}
|
||||
|
||||
#ifndef PRODUCT
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user