mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-28 23:34:52 +02:00
8272807: Permit use of memory concurrent with pretouch
Reviewed-by: shade, stuefe
This commit is contained in:
parent
cb2f8caed2
commit
072e7b4da0
2 changed files with 27 additions and 10 deletions
|
@ -1745,13 +1745,31 @@ void os::print_memory_mappings(outputStream* st) {
|
|||
os::print_memory_mappings(nullptr, (size_t)-1, st);
|
||||
}
|
||||
|
||||
// Pretouching must use a store, not just a load. On many OSes loads from
|
||||
// fresh memory would be satisfied from a single mapped page containing all
|
||||
// zeros. We need to store something to each page to get them backed by
|
||||
// their own memory, which is the effect we want here. An atomic add of
|
||||
// zero is used instead of a simple store, allowing the memory to be used
|
||||
// while pretouch is in progress, rather than requiring users of the memory
|
||||
// to wait until the entire range has been touched. This is technically
|
||||
// a UB data race, but doesn't cause any problems for us.
|
||||
void os::pretouch_memory(void* start, void* end, size_t page_size) {
|
||||
for (volatile char *p = (char*)start; p < (char*)end; p += page_size) {
|
||||
// Note: this must be a store, not a load. On many OSes loads from fresh
|
||||
// memory would be satisfied from a single mapped page containing all zeros.
|
||||
// We need to store something to each page to get them backed by their own
|
||||
// memory, which is the effect we want here.
|
||||
*p = 0;
|
||||
assert(start <= end, "invalid range: " PTR_FORMAT " -> " PTR_FORMAT, p2i(start), p2i(end));
|
||||
assert(is_power_of_2(page_size), "page size misaligned: %zu", page_size);
|
||||
assert(page_size >= sizeof(int), "page size too small: %zu", page_size);
|
||||
if (start < end) {
|
||||
// We're doing concurrent-safe touch and memory state has page
|
||||
// granularity, so we can touch anywhere in a page. Touch at the
|
||||
// beginning of each page to simplify iteration.
|
||||
char* cur = static_cast<char*>(align_down(start, page_size));
|
||||
void* last = align_down(static_cast<char*>(end) - 1, page_size);
|
||||
assert(cur <= last, "invariant");
|
||||
// Iterate from first page through last (inclusive), being careful to
|
||||
// avoid overflow if the last page abuts the end of the address range.
|
||||
for ( ; true; cur += page_size) {
|
||||
Atomic::add(reinterpret_cast<int*>(cur), 0, memory_order_relaxed);
|
||||
if (cur >= last) break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue