Skip to content
This repository has been archived by the owner. It is now read-only.
Permalink
Browse files
8252368: Undo JDK-8245002: Windows GDI functions don't support NUMA i…
…nterleaving

Reviewed-by: eosterlund, sjohanss
  • Loading branch information
stefank committed Aug 31, 2020
1 parent e95e138 commit 44ad9322e6145c825a32aed493b2baab340a0be8
Showing with 0 additions and 121 deletions.
  1. +0 −121 src/hotspot/os/windows/os_windows.cpp
@@ -2696,121 +2696,6 @@ int os::vm_allocation_granularity() {
#define MEM_LARGE_PAGES 0x20000000
#endif

#define VirtualFreeChecked(mem, size, type) \
do { \
bool ret = VirtualFree(mem, size, type); \
assert(ret, "Failed to free memory: " PTR_FORMAT, p2i(mem)); \
} while (false)

// The number of bytes is setup to match 1 pixel and 32 bits per pixel.
static const int gdi_tiny_bitmap_width_bytes = 4;

static HBITMAP gdi_create_tiny_bitmap(void* mem) {
// The documentation for CreateBitmap states a word-alignment requirement.
STATIC_ASSERT(is_aligned_(gdi_tiny_bitmap_width_bytes, sizeof(WORD)));

// Some callers use this function to test if memory crossing separate memory
// reservations can be used. Create a height of 2 to make sure that one pixel
// ends up in the first reservation and the other in the second.
int nHeight = 2;

assert(is_aligned(mem, gdi_tiny_bitmap_width_bytes), "Incorrect alignment");

// Width is one pixel and correlates with gdi_tiny_bitmap_width_bytes.
int nWidth = 1;

// Calculate bit count - will be 32.
UINT nBitCount = gdi_tiny_bitmap_width_bytes / nWidth * BitsPerByte;

return CreateBitmap(
nWidth,
nHeight,
1, // nPlanes
nBitCount,
mem); // lpBits
}

// It has been found that some of the GDI functions fail under these two situations:
// 1) When used with large pages
// 2) When mem crosses the boundary between two separate memory reservations.
//
// This is a small test used to see if the current GDI implementation is
// susceptible to any of these problems.
static bool gdi_can_use_memory(void* mem) {
HBITMAP bitmap = gdi_create_tiny_bitmap(mem);
if (bitmap != NULL) {
DeleteObject(bitmap);
return true;
}

// Verify that the bitmap could be created with a normal page.
// If this fails, the testing method above isn't reliable.
#ifdef ASSERT
void* verify_mem = ::malloc(4 * 1024);
HBITMAP verify_bitmap = gdi_create_tiny_bitmap(verify_mem);
if (verify_bitmap == NULL) {
fatal("Couldn't create test bitmap with malloced memory");
} else {
DeleteObject(verify_bitmap);
}
::free(verify_mem);
#endif

return false;
}

// Test if GDI functions work when memory spans
// two adjacent memory reservations.
static bool gdi_can_use_split_reservation_memory() {
size_t granule = os::vm_allocation_granularity();

// Find virtual memory range
void* reserved = VirtualAlloc(NULL,
granule * 2,
MEM_RESERVE,
PAGE_NOACCESS);
if (reserved == NULL) {
// Can't proceed with test - pessimistically report false
return false;
}
VirtualFreeChecked(reserved, 0, MEM_RELEASE);

void* res0 = reserved;
void* res1 = (char*)reserved + granule;

// Reserve and commit the first part
void* mem0 = VirtualAlloc(res0,
granule,
MEM_RESERVE|MEM_COMMIT,
PAGE_READWRITE);
if (mem0 != res0) {
// Can't proceed with test - pessimistically report false
return false;
}

// Reserve and commit the second part
void* mem1 = VirtualAlloc(res1,
granule,
MEM_RESERVE|MEM_COMMIT,
PAGE_READWRITE);
if (mem1 != res1) {
VirtualFreeChecked(mem0, 0, MEM_RELEASE);
// Can't proceed with test - pessimistically report false
return false;
}

// Set the bitmap's bits to point one "width" bytes before, so that
// the bitmap extends across the reservation boundary.
void* bitmapBits = (char*)mem1 - gdi_tiny_bitmap_width_bytes;

bool success = gdi_can_use_memory(bitmapBits);

VirtualFreeChecked(mem1, 0, MEM_RELEASE);
VirtualFreeChecked(mem0, 0, MEM_RELEASE);

return success;
}

// Container for NUMA node list info
class NUMANodeListHolder {
private:
@@ -2913,12 +2798,6 @@ static bool numa_interleaving_init() {
return false;
}

if (!gdi_can_use_split_reservation_memory()) {
WARN("Windows GDI cannot handle split reservations.");
WARN("...Ignoring UseNUMAInterleaving flag.");
return false;
}

if (log_is_enabled(Debug, os, cpu)) {
Log(os, cpu) log;
log.debug("NUMA UsedNodeCount=%d, namely ", numa_node_list_holder.get_count());

0 comments on commit 44ad932

Please sign in to comment.