Skip to content

Commit e5fc2cb

Browse files
committed
- convert to FFI
1 parent 6ac30f5 commit e5fc2cb

File tree

4 files changed

+101
-23
lines changed

4 files changed

+101
-23
lines changed

src/main/java/mediathek/Main.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/*
2+
* Copyright (c) 2025 derreisende77.
3+
* This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
119
package mediathek;
220

321
import com.formdev.flatlaf.FlatLaf;

src/main/java/mediathek/tool/affinity/IAffinity.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/*
2+
* Copyright (c) 2025 derreisende77.
3+
* This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
119
package mediathek.tool.affinity
220

321
interface IAffinity {
Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,59 @@
1+
/*
2+
* Copyright (c) 2025 derreisende77.
3+
* This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
119
package mediathek.tool.affinity
220

3-
import com.sun.jna.Native
4-
import com.sun.jna.Pointer
5-
import com.sun.jna.platform.win32.Kernel32
6-
import com.sun.jna.platform.win32.WinNT.HANDLE
721
import org.apache.logging.log4j.LogManager
8-
import java.util.*
22+
import java.lang.foreign.*
23+
import java.lang.invoke.MethodHandle
924

1025
class WindowsAffinity : IAffinity {
1126
override fun setDesiredCpuAffinity(numCpus: Int) {
12-
val pid = -1 // current process
13-
val bitSet = BitSet()
14-
bitSet[0] = numCpus
15-
val affinity = bitSet.stream()
16-
.takeWhile { i: Int -> i < java.lang.Long.SIZE }
17-
.mapToLong { i: Int -> 1L shl i }
18-
.reduce(0) { a: Long, b: Long -> a or b }
19-
val affinityMask = affinity.toInt()
20-
val instance = Native.load("Kernel32", AffinityKernel::class.java)
21-
val result = instance.SetProcessAffinityMask(HANDLE(Pointer(pid.toLong())), affinityMask)
22-
if (result) {
23-
logger.info("CPU affinity was set successfully.")
24-
logger.trace("Available processors: {}", Runtime.getRuntime().availableProcessors())
25-
} else logger.warn("Failed to set CPU affinity.")
26-
}
27+
require(numCpus in 1..64) { "numCpus must be between 1 and 64" }
28+
29+
val affinityMask = (0 until numCpus).fold(0L) { acc, i -> acc or (1L shl i) }
30+
31+
Linker.nativeLinker().let { linker ->
32+
val symbolLookup = SymbolLookup.loaderLookup()
33+
34+
val getCurrentProcess: MethodHandle = linker.downcallHandle(
35+
symbolLookup.find("GetCurrentProcess").orElseThrow(),
36+
FunctionDescriptor.of(ValueLayout.ADDRESS)
37+
)
38+
39+
val setAffinity: MethodHandle = linker.downcallHandle(
40+
symbolLookup.find("SetProcessAffinityMask").orElseThrow(),
41+
FunctionDescriptor.of(ValueLayout.JAVA_INT, ValueLayout.ADDRESS, ValueLayout.JAVA_LONG)
42+
)
43+
44+
val processHandle = getCurrentProcess.invoke() as MemorySegment
45+
val result = setAffinity.invoke(processHandle, affinityMask) as Int
2746

28-
private interface AffinityKernel : Kernel32 {
29-
fun SetProcessAffinityMask(hProcess: HANDLE?, dwProcessAffinityMask: Int): Boolean
47+
if (result != 0) {
48+
logger.info("CPU affinity was set successfully to mask: 0x${affinityMask.toString(16)}")
49+
logger.trace("Available processors: {}", Runtime.getRuntime().availableProcessors())
50+
} else {
51+
logger.warn("Failed to set CPU affinity.")
52+
}
53+
}
3054
}
3155

3256
companion object {
3357
private val logger = LogManager.getLogger()
3458
}
35-
}
59+
}

src/main/kotlin/mediathek/windows/TaskbarIndicatorThread.kt

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
/*
2+
* Copyright (c) 2025 derreisende77.
3+
* This code was developed as part of the MediathekView project https://github.com/mediathekview/MediathekView
4+
*
5+
* This program is free software: you can redistribute it and/or modify
6+
* it under the terms of the GNU General Public License as published by
7+
* the Free Software Foundation, either version 3 of the License, or
8+
* (at your option) any later version.
9+
*
10+
* This program is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13+
* GNU General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU General Public License
16+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*/
18+
119
package mediathek.windows
220

321
import mediathek.tool.threads.IndicatorThread

0 commit comments

Comments
 (0)