8233378: CHT: Fast reset
Reviewed-by: tschatzl, rehn
This commit is contained in:
parent
f3b510b9aa
commit
dcf250d5d4
src/hotspot/share/utilities
test/hotspot/gtest/utilities
@ -292,6 +292,7 @@ class ConcurrentHashTable : public CHeapObj<F> {
|
||||
void internal_shrink_epilog(Thread* thread);
|
||||
void internal_shrink_range(Thread* thread, size_t start, size_t stop);
|
||||
bool internal_shrink(Thread* thread, size_t size_limit_log2);
|
||||
void internal_reset(size_t log2_size);
|
||||
|
||||
// Methods for growing.
|
||||
bool unzip_bucket(Thread* thread, InternalTable* old_table,
|
||||
@ -388,6 +389,10 @@ class ConcurrentHashTable : public CHeapObj<F> {
|
||||
// Re-size operations.
|
||||
bool shrink(Thread* thread, size_t size_limit_log2 = 0);
|
||||
bool grow(Thread* thread, size_t size_limit_log2 = 0);
|
||||
// Unsafe reset and resize the table. This method assumes that we
|
||||
// want to clear and maybe resize the internal table without the
|
||||
// overhead of clearing individual items in the table.
|
||||
void unsafe_reset(size_t size_log2 = 0);
|
||||
|
||||
// All callbacks for get are under critical sections. Other callbacks may be
|
||||
// under critical section or may have locked parts of table. Calling any
|
||||
|
@ -781,6 +781,20 @@ inline bool ConcurrentHashTable<CONFIG, F>::
|
||||
return true;
|
||||
}
|
||||
|
||||
template <typename CONFIG, MEMFLAGS F>
|
||||
inline void ConcurrentHashTable<CONFIG, F>::
|
||||
internal_reset(size_t log2_size)
|
||||
{
|
||||
assert(_table != NULL, "table failed");
|
||||
assert(_log2_size_limit >= log2_size, "bad ergo");
|
||||
|
||||
delete _table;
|
||||
// Create and publish a new table
|
||||
InternalTable* table = new InternalTable(log2_size);
|
||||
_size_limit_reached = (log2_size == _log2_size_limit);
|
||||
Atomic::release_store(&_table, table);
|
||||
}
|
||||
|
||||
template <typename CONFIG, MEMFLAGS F>
|
||||
inline bool ConcurrentHashTable<CONFIG, F>::
|
||||
internal_grow_prolog(Thread* thread, size_t log2_size)
|
||||
@ -1032,6 +1046,14 @@ inline bool ConcurrentHashTable<CONFIG, F>::
|
||||
return ret;
|
||||
}
|
||||
|
||||
template <typename CONFIG, MEMFLAGS F>
|
||||
inline void ConcurrentHashTable<CONFIG, F>::
|
||||
unsafe_reset(size_t size_log2)
|
||||
{
|
||||
size_t tmp = size_log2 == 0 ? _log2_start_size : size_log2;
|
||||
internal_reset(tmp);
|
||||
}
|
||||
|
||||
template <typename CONFIG, MEMFLAGS F>
|
||||
inline bool ConcurrentHashTable<CONFIG, F>::
|
||||
grow(Thread* thread, size_t size_limit_log2)
|
||||
|
@ -49,8 +49,46 @@ struct Pointer : public AllStatic {
|
||||
}
|
||||
};
|
||||
|
||||
struct Config : public AllStatic {
|
||||
typedef uintptr_t Value;
|
||||
struct TableElement{
|
||||
TableElement * volatile _next;
|
||||
Value _value;
|
||||
};
|
||||
|
||||
static const uint nelements = 5;
|
||||
static TableElement* elements;
|
||||
static uint cur_index;
|
||||
|
||||
static uintx get_hash(const Value& value, bool* dead_hash) {
|
||||
return (uintx)value;
|
||||
}
|
||||
static void initialize() {
|
||||
elements = (TableElement*)::malloc(nelements * sizeof(TableElement));
|
||||
}
|
||||
static void* allocate_node(size_t size, const Value& value) {
|
||||
return (void*)&elements[cur_index++];
|
||||
}
|
||||
|
||||
static void free_node(void* memory, const Value& value) {
|
||||
return;
|
||||
}
|
||||
|
||||
static void reset() {
|
||||
cur_index = 0;
|
||||
}
|
||||
|
||||
static void bulk_free() {
|
||||
::free(elements);
|
||||
}
|
||||
};
|
||||
|
||||
Config::TableElement* Config::elements = nullptr;
|
||||
uint Config::cur_index = 0;
|
||||
|
||||
typedef ConcurrentHashTable<Pointer, mtInternal> SimpleTestTable;
|
||||
typedef ConcurrentHashTable<Pointer, mtInternal>::MultiGetHandle SimpleTestGetHandle;
|
||||
typedef ConcurrentHashTable<Config, mtInternal> CustomTestTable;
|
||||
|
||||
struct SimpleTestLookup {
|
||||
uintptr_t _val;
|
||||
@ -75,20 +113,23 @@ struct ValueGet {
|
||||
}
|
||||
};
|
||||
|
||||
static uintptr_t cht_get_copy(SimpleTestTable* cht, Thread* thr, SimpleTestLookup stl) {
|
||||
template <typename T=SimpleTestTable>
|
||||
static uintptr_t cht_get_copy(T* cht, Thread* thr, SimpleTestLookup stl) {
|
||||
ValueGet vg;
|
||||
cht->get(thr, stl, vg);
|
||||
return vg.get_value();
|
||||
}
|
||||
|
||||
static void cht_find(Thread* thr, SimpleTestTable* cht, uintptr_t val) {
|
||||
template <typename T=SimpleTestTable>
|
||||
static void cht_find(Thread* thr, T* cht, uintptr_t val) {
|
||||
SimpleTestLookup stl(val);
|
||||
ValueGet vg;
|
||||
EXPECT_EQ(cht->get(thr, stl, vg), true) << "Getting an old value failed.";
|
||||
EXPECT_EQ(val, vg.get_value()) << "Getting an old value failed.";
|
||||
}
|
||||
|
||||
static void cht_insert_and_find(Thread* thr, SimpleTestTable* cht, uintptr_t val) {
|
||||
template <typename T=SimpleTestTable>
|
||||
static void cht_insert_and_find(Thread* thr, T* cht, uintptr_t val) {
|
||||
SimpleTestLookup stl(val);
|
||||
EXPECT_EQ(cht->insert(thr, stl, val), true) << "Inserting an unique value failed.";
|
||||
cht_find(thr, cht, val);
|
||||
@ -220,6 +261,32 @@ static void cht_getinsert_bulkdelete_task(Thread* thr) {
|
||||
delete cht;
|
||||
}
|
||||
|
||||
static void cht_reset_shrink(Thread* thr) {
|
||||
uintptr_t val1 = 1;
|
||||
uintptr_t val2 = 2;
|
||||
uintptr_t val3 = 3;
|
||||
SimpleTestLookup stl1(val1), stl2(val2), stl3(val3);
|
||||
|
||||
Config::initialize();
|
||||
CustomTestTable* cht = new CustomTestTable();
|
||||
|
||||
cht_insert_and_find(thr, cht, val1);
|
||||
cht_insert_and_find(thr, cht, val2);
|
||||
cht_insert_and_find(thr, cht, val3);
|
||||
|
||||
cht->unsafe_reset();
|
||||
Config::reset();
|
||||
|
||||
EXPECT_EQ(cht_get_copy(cht, thr, stl1), (uintptr_t)0) << "Table should have been reset";
|
||||
// Re-inserted values should not be considered duplicates; table was reset.
|
||||
cht_insert_and_find(thr, cht, val1);
|
||||
cht_insert_and_find(thr, cht, val2);
|
||||
cht_insert_and_find(thr, cht, val3);
|
||||
|
||||
delete cht;
|
||||
Config::bulk_free();
|
||||
}
|
||||
|
||||
static void cht_scope(Thread* thr) {
|
||||
uintptr_t val = 0x2;
|
||||
SimpleTestLookup stl(val);
|
||||
@ -394,6 +461,10 @@ TEST_VM(ConcurrentHashTable, basic_get_insert_bulk_delete_task) {
|
||||
nomt_test_doer(cht_getinsert_bulkdelete_task);
|
||||
}
|
||||
|
||||
TEST_VM(ConcurrentHashTable, basic_reset_shrink) {
|
||||
nomt_test_doer(cht_reset_shrink);
|
||||
}
|
||||
|
||||
TEST_VM(ConcurrentHashTable, basic_scan) {
|
||||
nomt_test_doer(cht_scan);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user