NtQueryTimerResolution
This commit is contained in:
parent
4ff09bea2b
commit
d8f4d06d83
23
src/main/kotlin/ru/dbotthepony/kstarbound/WindowsBindings.kt
Normal file
23
src/main/kotlin/ru/dbotthepony/kstarbound/WindowsBindings.kt
Normal file
@ -0,0 +1,23 @@
|
||||
package ru.dbotthepony.kstarbound
|
||||
|
||||
import jnr.ffi.LibraryLoader
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import java.nio.LongBuffer
|
||||
|
||||
interface WindowsBindings {
|
||||
fun NtQueryTimerResolution(minimumResolution: LongBuffer, maximumResolution: LongBuffer, currentResolution: LongBuffer)
|
||||
fun NtSetTimerResolution(desiredResolution: Long, setResolution: Boolean, currentResolution: LongBuffer)
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
|
||||
val INSTANCE by lazy {
|
||||
try {
|
||||
LibraryLoader.create(WindowsBindings::class.java).load("ntdll")
|
||||
} catch (err: Throwable) {
|
||||
LOGGER.error("Failed to link against ntdll.dll, if we are not on Windows then ignore this message", err)
|
||||
null
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,8 +1,10 @@
|
||||
package ru.dbotthepony.kstarbound.util
|
||||
|
||||
import org.apache.logging.log4j.LogManager
|
||||
import org.lwjgl.system.MemoryStack
|
||||
import ru.dbotthepony.kommons.util.MailboxExecutorService
|
||||
import ru.dbotthepony.kstarbound.Starbound
|
||||
import ru.dbotthepony.kstarbound.WindowsBindings
|
||||
import java.util.concurrent.locks.LockSupport
|
||||
import java.util.function.BooleanSupplier
|
||||
|
||||
@ -54,7 +56,7 @@ class ExecutionSpinner(private val executor: MailboxExecutorService, private val
|
||||
while (diff > 0L) {
|
||||
executor.executeQueuedTasks()
|
||||
diff = timeUntilNextFrame()
|
||||
if (diff > 400_000L) LockSupport.parkNanos(100_000L)
|
||||
if (diff > SYSTEM_SCHEDULER_RESOLUTION) LockSupport.parkNanos(500_000L)
|
||||
}
|
||||
|
||||
val mark = System.nanoTime()
|
||||
@ -73,9 +75,33 @@ class ExecutionSpinner(private val executor: MailboxExecutorService, private val
|
||||
|
||||
companion object {
|
||||
private val LOGGER = LogManager.getLogger()
|
||||
private var SYSTEM_SCHEDULER_RESOLUTION = 1_000_000L
|
||||
|
||||
init {
|
||||
val thread = object : Thread("Fix God Damn Windows Process Scheduler For Once Please") {
|
||||
val bindings = WindowsBindings.INSTANCE
|
||||
|
||||
if (bindings != null) {
|
||||
MemoryStack.stackPush().use { stack ->
|
||||
val minimum = stack.mallocLong(1)
|
||||
val maximum = stack.mallocLong(1)
|
||||
val current = stack.mallocLong(1)
|
||||
|
||||
minimum.put(0L)
|
||||
maximum.put(0L)
|
||||
current.put(0L)
|
||||
|
||||
minimum.position(0)
|
||||
maximum.position(0)
|
||||
current.position(0)
|
||||
|
||||
bindings.NtQueryTimerResolution(minimum, maximum, current)
|
||||
|
||||
SYSTEM_SCHEDULER_RESOLUTION = current[0] * 150L // give some room for error
|
||||
LOGGER.info("NtQueryTimerResolution(): {} ns/{} ns/{} ns min/max/current", minimum[0] * 100L, maximum[0] * 100L, current[0] * 100L)
|
||||
}
|
||||
}
|
||||
|
||||
val thread = object : Thread("Process scheduler timer hack thread") {
|
||||
override fun run() {
|
||||
while (true) {
|
||||
try {
|
||||
|
Loading…
Reference in New Issue
Block a user