|
62 | 62 | import com.sun.jna.Platform; |
63 | 63 | import com.sun.jna.Pointer; |
64 | 64 | import com.sun.jna.platform.win32.BaseTSD.SIZE_T; |
| 65 | +import com.sun.jna.platform.win32.BaseTSD.ULONG_PTR; |
65 | 66 | import com.sun.jna.platform.win32.BaseTSD.ULONG_PTRByReference; |
66 | 67 | import com.sun.jna.platform.win32.Ntifs.REPARSE_DATA_BUFFER; |
67 | 68 | import com.sun.jna.platform.win32.Ntifs.SymbolicLinkReparseBuffer; |
@@ -464,22 +465,58 @@ public void testGetProcessIoCounters() { |
464 | 465 | } |
465 | 466 | } |
466 | 467 |
|
467 | | - public void testGetProcessAffinityMask() { |
468 | | - int myPid = Kernel32.INSTANCE.GetCurrentProcessId(); |
469 | | - HANDLE pHandle = Kernel32.INSTANCE.OpenProcess(WinNT.PROCESS_QUERY_INFORMATION, false, myPid); |
| 468 | + public void testGetAndSetProcessAffinityMask() { |
| 469 | + // Pseudo handle, no need to close. Has PROCESS_ALL_ACCESS right. |
| 470 | + HANDLE pHandle = Kernel32.INSTANCE.GetCurrentProcess(); |
470 | 471 | assertNotNull(pHandle); |
471 | 472 |
|
472 | 473 | ULONG_PTRByReference pProcessAffinity = new ULONG_PTRByReference(); |
473 | 474 | ULONG_PTRByReference pSystemAffinity = new ULONG_PTRByReference(); |
474 | | - assertTrue(Kernel32.INSTANCE.GetProcessAffinityMask(pHandle, pProcessAffinity, pSystemAffinity)); |
| 475 | + assertTrue("Failed to get affinity masks.", |
| 476 | + Kernel32.INSTANCE.GetProcessAffinityMask(pHandle, pProcessAffinity, pSystemAffinity)); |
475 | 477 |
|
476 | 478 | long processAffinity = pProcessAffinity.getValue().longValue(); |
477 | 479 | long systemAffinity = pSystemAffinity.getValue().longValue(); |
478 | 480 |
|
479 | | - assertEquals("Process affinity must be a subset of system affinity", processAffinity, |
480 | | - processAffinity & systemAffinity); |
481 | | - assertEquals("System affinity must be a superset of process affinity", systemAffinity, |
482 | | - processAffinity | systemAffinity); |
| 481 | + if (systemAffinity == 0) { |
| 482 | + // Rare case for process to be running in multiple processor groups, where both |
| 483 | + // systemAffinity and processAffinity are 0 and we can't do anything else. |
| 484 | + assertEquals( |
| 485 | + "Both process and system affinity must be zero if this process is running in multiple processor groups", |
| 486 | + processAffinity, systemAffinity); |
| 487 | + } else { |
| 488 | + // Test current affinity |
| 489 | + assertEquals("Process affinity must be a subset of system affinity", processAffinity, |
| 490 | + processAffinity & systemAffinity); |
| 491 | + assertEquals("System affinity must be a superset of process affinity", systemAffinity, |
| 492 | + processAffinity | systemAffinity); |
| 493 | + |
| 494 | + // Set affinity to a single processor in the current system |
| 495 | + long lowestOneBit = Long.lowestOneBit(systemAffinity); |
| 496 | + ULONG_PTR dwProcessAffinityMask = new ULONG_PTR(lowestOneBit); |
| 497 | + assertTrue("Failed to set affinity", |
| 498 | + Kernel32.INSTANCE.SetProcessAffinityMask(pHandle, dwProcessAffinityMask)); |
| 499 | + assertTrue("Failed to get affinity masks.", |
| 500 | + Kernel32.INSTANCE.GetProcessAffinityMask(pHandle, pProcessAffinity, pSystemAffinity)); |
| 501 | + assertEquals("Process affinity doesn't match what was just set", lowestOneBit, |
| 502 | + pProcessAffinity.getValue().longValue()); |
| 503 | + |
| 504 | + // Now try to set affinity to an invalid processor |
| 505 | + lowestOneBit = Long.lowestOneBit(~systemAffinity); |
| 506 | + // In case we have exactly 64 processors we can't do this, otherwise... |
| 507 | + if (lowestOneBit != 0) { |
| 508 | + dwProcessAffinityMask = new ULONG_PTR(lowestOneBit); |
| 509 | + assertFalse("Successfully set affinity when it should have failed", |
| 510 | + Kernel32.INSTANCE.SetProcessAffinityMask(pHandle, dwProcessAffinityMask)); |
| 511 | + assertEquals("Last error should be ERROR_INVALID_PARAMETER", WinError.ERROR_INVALID_PARAMETER, |
| 512 | + Kernel32.INSTANCE.GetLastError()); |
| 513 | + } |
| 514 | + |
| 515 | + // Cleanup. Be nice and put affinity back where it started! |
| 516 | + dwProcessAffinityMask = new ULONG_PTR(processAffinity); |
| 517 | + assertTrue("Failed to restore affinity to original setting", |
| 518 | + Kernel32.INSTANCE.SetProcessAffinityMask(pHandle, dwProcessAffinityMask)); |
| 519 | + } |
483 | 520 | } |
484 | 521 |
|
485 | 522 | public void testGetTempPath() { |
|
0 commit comments