Skip to content

Commit 2e9fd56

Browse files
committed
8283670: gtest os.release_multi_mappings_vm is still racy
Reviewed-by: mdoerr, dholmes
1 parent f01cce2 commit 2e9fd56

File tree

1 file changed

+34
-24
lines changed

1 file changed

+34
-24
lines changed

test/hotspot/gtest/runtime/test_os.cpp

Lines changed: 34 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,15 @@ static inline bool can_reserve_executable_memory(void) {
373373
#define PRINT_MAPPINGS(s) { tty->print_cr("%s", s); os::print_memory_mappings((char*)p, total_range_len, tty); }
374374
//#define PRINT_MAPPINGS
375375

376+
// Release a range allocated with reserve_multiple carefully, to not trip mapping
377+
// asserts on Windows in os::release_memory()
378+
static void carefully_release_multiple(address start, int num_stripes, size_t stripe_len) {
379+
for (int stripe = 0; stripe < num_stripes; stripe++) {
380+
address q = start + (stripe * stripe_len);
381+
EXPECT_TRUE(os::release_memory((char*)q, stripe_len));
382+
}
383+
}
384+
376385
#ifndef _AIX // JDK-8257041
377386
// Reserve an area consisting of multiple mappings
378387
// (from multiple calls to os::reserve_memory)
@@ -385,25 +394,34 @@ static address reserve_multiple(int num_stripes, size_t stripe_len) {
385394
const bool exec_supported = can_reserve_executable_memory();
386395
#endif
387396

388-
size_t total_range_len = num_stripes * stripe_len;
389-
// Reserve a large contiguous area to get the address space...
390-
address p = (address)os::reserve_memory(total_range_len);
391-
EXPECT_NE(p, (address)NULL);
392-
// .. release it...
393-
EXPECT_TRUE(os::release_memory((char*)p, total_range_len));
394-
// ... re-reserve in the same spot multiple areas...
395-
for (int stripe = 0; stripe < num_stripes; stripe++) {
396-
address q = p + (stripe * stripe_len);
397-
// Commit, alternatingly with or without exec permission,
398-
// to prevent kernel from folding these mappings.
397+
address p = NULL;
398+
for (int tries = 0; tries < 256 && p == NULL; tries ++) {
399+
size_t total_range_len = num_stripes * stripe_len;
400+
// Reserve a large contiguous area to get the address space...
401+
p = (address)os::reserve_memory(total_range_len);
402+
EXPECT_NE(p, (address)NULL);
403+
// .. release it...
404+
EXPECT_TRUE(os::release_memory((char*)p, total_range_len));
405+
// ... re-reserve in the same spot multiple areas...
406+
for (int stripe = 0; stripe < num_stripes; stripe++) {
407+
address q = p + (stripe * stripe_len);
408+
// Commit, alternatingly with or without exec permission,
409+
// to prevent kernel from folding these mappings.
399410
#ifdef __APPLE__
400-
const bool executable = exec_supported ? (stripe % 2 == 0) : false;
411+
const bool executable = exec_supported ? (stripe % 2 == 0) : false;
401412
#else
402-
const bool executable = stripe % 2 == 0;
413+
const bool executable = stripe % 2 == 0;
403414
#endif
404-
q = (address)os::attempt_reserve_memory_at((char*)q, stripe_len, executable);
405-
EXPECT_NE(q, (address)NULL);
406-
EXPECT_TRUE(os::commit_memory((char*)q, stripe_len, executable));
415+
q = (address)os::attempt_reserve_memory_at((char*)q, stripe_len, executable);
416+
if (q == NULL) {
417+
// Someone grabbed that area concurrently. Cleanup, then retry.
418+
tty->print_cr("reserve_multiple: retry (%d)...", stripe);
419+
carefully_release_multiple(p, stripe, stripe_len);
420+
p = NULL;
421+
} else {
422+
EXPECT_TRUE(os::commit_memory((char*)q, stripe_len, executable));
423+
}
424+
}
407425
}
408426
return p;
409427
}
@@ -426,14 +444,6 @@ static address reserve_one_commit_multiple(int num_stripes, size_t stripe_len) {
426444
}
427445

428446
#ifdef _WIN32
429-
// Release a range allocated with reserve_multiple carefully, to not trip mapping
430-
// asserts on Windows in os::release_memory()
431-
static void carefully_release_multiple(address start, int num_stripes, size_t stripe_len) {
432-
for (int stripe = 0; stripe < num_stripes; stripe++) {
433-
address q = start + (stripe * stripe_len);
434-
EXPECT_TRUE(os::release_memory((char*)q, stripe_len));
435-
}
436-
}
437447
struct NUMASwitcher {
438448
const bool _b;
439449
NUMASwitcher(bool v): _b(UseNUMAInterleaving) { UseNUMAInterleaving = v; }

0 commit comments

Comments
 (0)