OpenHFT / Java-Thread-Affinity

Bind a java thread to a given core
http://chronicle.software/products/thread-affinity/
Apache License 2.0
1.78k stars 360 forks source link

setAffinity does not work as expected in Windows #117

Open kopavel opened 5 months ago

kopavel commented 5 months ago

On win 11 got warning: "Tried to set affinity to {7} but was {0,1,2,3,4,5,6,7} you may have insufficient access rights" and nohing heppend - thread remain affined to all cores.

Java version: jdk-21.0.2.13-hotspot (Eclipse Adoptium) jna and jna-platform verstion: 5.14.0 affinity version: 3.23.3

Thread, for which i try to lock affiniti created by :

Thread.ofPlatform().name("AffinedThread").start(() -> { try (AffinityLock al = AffinityLock.acquireLock()) { ..... } });

Starting console in which java started with Admin rights change nothing.

tgd commented 5 months ago

Thanks @kopavel we will take a look soon.

For expedited support we do offer commercial options - https://chronicle.software/contact-us/

kopavel commented 5 months ago

Just re-check sittuation again using task manager - thead actually ARE binded as expected... so actually - it'a a false WARNing from code...

tgd commented 5 months ago

Thanks for letting us know - we will close for now and potentially re-open in future.

mr-infty commented 3 months ago

I am experiencing the same problem (affinity version 3.23.3), i.e. I get the same error message. I have also checked manually using the task manager, and it shows that the affinity was not modified.

According to https://learn.microsoft.com/en-en/windows/win32/api/winbase/nf-winbase-setthreadaffinitymask the return value of SetThreadAffinityMask already indicates whether the operation was succesful. Why don't you test for that?

P.S.: I have run java.exe from a PowerShell with administrative privileges.

tgd commented 3 months ago

Thanks for reporting it @mr-infty - we have a PR in flight for this and will work on getting it tested and released. We will update the ticket here when that's done.

mr-infty commented 3 months ago

Sorry, my bad: I failed to distinguish between processes and threads.

Indeed, the affinity of my process is not changed by .acquireCore(); however, the thread's one is (probably), at least calling SetThreadAffinityMask manually from my own binding to kernel32.dll works. So I guess the problem really lies in the code that checks the result.

On that note, an alternative would be to call SetThreadAffinityMask twice, as that method returns (on a succesful call) the previous affinity mask. Also, checking the return value for null already allows you to determine whether the call was successful, at least if you believe the Windows API.

yevgenp commented 3 months ago

Thanks @mr-infty. We considered such option (call SetThreadAffinityMask twice) as Win API is not flexible enough. But I'm afraid it's gonna be too expensive (latency wise).

mr-infty commented 3 months ago

I see @yevgenp. However, you could still just check the return value.