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
|
package ru.dbotthepony.kstarbound.util
|
||||||
|
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
|
import org.lwjgl.system.MemoryStack
|
||||||
import ru.dbotthepony.kommons.util.MailboxExecutorService
|
import ru.dbotthepony.kommons.util.MailboxExecutorService
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
import ru.dbotthepony.kstarbound.Starbound
|
||||||
|
import ru.dbotthepony.kstarbound.WindowsBindings
|
||||||
import java.util.concurrent.locks.LockSupport
|
import java.util.concurrent.locks.LockSupport
|
||||||
import java.util.function.BooleanSupplier
|
import java.util.function.BooleanSupplier
|
||||||
|
|
||||||
@ -54,7 +56,7 @@ class ExecutionSpinner(private val executor: MailboxExecutorService, private val
|
|||||||
while (diff > 0L) {
|
while (diff > 0L) {
|
||||||
executor.executeQueuedTasks()
|
executor.executeQueuedTasks()
|
||||||
diff = timeUntilNextFrame()
|
diff = timeUntilNextFrame()
|
||||||
if (diff > 400_000L) LockSupport.parkNanos(100_000L)
|
if (diff > SYSTEM_SCHEDULER_RESOLUTION) LockSupport.parkNanos(500_000L)
|
||||||
}
|
}
|
||||||
|
|
||||||
val mark = System.nanoTime()
|
val mark = System.nanoTime()
|
||||||
@ -73,9 +75,33 @@ class ExecutionSpinner(private val executor: MailboxExecutorService, private val
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val LOGGER = LogManager.getLogger()
|
private val LOGGER = LogManager.getLogger()
|
||||||
|
private var SYSTEM_SCHEDULER_RESOLUTION = 1_000_000L
|
||||||
|
|
||||||
init {
|
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() {
|
override fun run() {
|
||||||
while (true) {
|
while (true) {
|
||||||
try {
|
try {
|
||||||
|
Loading…
Reference in New Issue
Block a user