Misc fixes
This commit is contained in:
parent
7fcad1352e
commit
0c6736ef90
@ -1,13 +1,15 @@
|
|||||||
package ru.dbotthepony.kstarbound.api
|
package ru.dbotthepony.kstarbound.api
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap
|
import com.google.common.collect.ImmutableMap
|
||||||
import com.google.gson.JsonElement
|
|
||||||
import com.google.gson.JsonParser
|
|
||||||
import com.google.gson.stream.JsonReader
|
import com.google.gson.stream.JsonReader
|
||||||
import ru.dbotthepony.kstarbound.Starbound
|
|
||||||
import ru.dbotthepony.kstarbound.io.StarboundPak
|
import ru.dbotthepony.kstarbound.io.StarboundPak
|
||||||
import ru.dbotthepony.kstarbound.stream
|
import ru.dbotthepony.kstarbound.stream
|
||||||
import java.io.*
|
import java.io.BufferedInputStream
|
||||||
|
import java.io.File
|
||||||
|
import java.io.FileNotFoundException
|
||||||
|
import java.io.InputStream
|
||||||
|
import java.io.InputStreamReader
|
||||||
|
import java.io.Reader
|
||||||
import java.nio.ByteBuffer
|
import java.nio.ByteBuffer
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
|
|
||||||
|
@ -74,6 +74,8 @@ import java.nio.ByteOrder
|
|||||||
import java.time.Duration
|
import java.time.Duration
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.ForkJoinPool
|
import java.util.concurrent.ForkJoinPool
|
||||||
|
import java.util.concurrent.ForkJoinWorkerThread
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import java.util.concurrent.locks.LockSupport
|
import java.util.concurrent.locks.LockSupport
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
import java.util.function.IntConsumer
|
import java.util.function.IntConsumer
|
||||||
@ -86,10 +88,26 @@ class StarboundClient : Closeable {
|
|||||||
val camera = Camera(this)
|
val camera = Camera(this)
|
||||||
val input = UserInput()
|
val input = UserInput()
|
||||||
val thread: Thread = Thread.currentThread()
|
val thread: Thread = Thread.currentThread()
|
||||||
|
private val threadCounter = AtomicInteger()
|
||||||
// client specific executor which will accept tasks which involve probable
|
// client specific executor which will accept tasks which involve probable
|
||||||
// callback to foreground executor to initialize thread-unsafe data
|
// callback to foreground executor to initialize thread-unsafe data
|
||||||
// In above case too many threads will introduce big congestion for resources, stalling entire workload; wasting cpu resources
|
// In above case too many threads will introduce big congestion for resources, stalling entire workload; wasting cpu resources
|
||||||
val backgroundExecutor = ForkJoinPool(Runtime.getRuntime().availableProcessors().coerceAtMost(4))
|
val backgroundExecutor = ForkJoinPool(Runtime.getRuntime().availableProcessors().coerceAtMost(4), {
|
||||||
|
object : ForkJoinWorkerThread(it) {
|
||||||
|
init {
|
||||||
|
name = "Background Executor for '${thread.name}'-${threadCounter.incrementAndGet()}"
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTermination(exception: Throwable?) {
|
||||||
|
super.onTermination(exception)
|
||||||
|
|
||||||
|
if (exception != null) {
|
||||||
|
LOGGER.error("$this encountered an exception while executing task", exception)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}, null, false)
|
||||||
|
|
||||||
val foregroundExecutor = ManualExecutorService(thread)
|
val foregroundExecutor = ManualExecutorService(thread)
|
||||||
val capabilities: GLCapabilities
|
val capabilities: GLCapabilities
|
||||||
|
|
||||||
|
@ -7,6 +7,8 @@ import ru.dbotthepony.kstarbound.stream
|
|||||||
import java.lang.ref.ReferenceQueue
|
import java.lang.ref.ReferenceQueue
|
||||||
import java.lang.ref.WeakReference
|
import java.lang.ref.WeakReference
|
||||||
import java.util.concurrent.locks.LockSupport
|
import java.util.concurrent.locks.LockSupport
|
||||||
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
import kotlin.concurrent.withLock
|
||||||
|
|
||||||
// hand-rolled interner, which has similar performance to ConcurrentHashMap
|
// hand-rolled interner, which has similar performance to ConcurrentHashMap
|
||||||
// (given there is no strong congestion, otherwise it performs somewhere above Caffeine interner),
|
// (given there is no strong congestion, otherwise it performs somewhere above Caffeine interner),
|
||||||
@ -124,7 +126,7 @@ class HashTableInterner<T : Any>(private val segmentBits: Int) : Interner<T> {
|
|||||||
actualSegmentBits = result
|
actualSegmentBits = result
|
||||||
}
|
}
|
||||||
|
|
||||||
private val locks: Array<Any> = Array(1.shl(segmentBits)) { Any() }
|
private val locks: Array<ReentrantLock> = Array(1.shl(segmentBits)) { ReentrantLock() }
|
||||||
private val segments: Array<Segment> = Array(1.shl(segmentBits)) { Segment(32, locks[it]) }
|
private val segments: Array<Segment> = Array(1.shl(segmentBits)) { Segment(32, locks[it]) }
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -137,7 +139,7 @@ class HashTableInterner<T : Any>(private val segmentBits: Int) : Interner<T> {
|
|||||||
// while this increase memory usage (linked list), this greatly
|
// while this increase memory usage (linked list), this greatly
|
||||||
// simplify logic, and make scanning a bit faster because we don't jump to neighbour nodes
|
// simplify logic, and make scanning a bit faster because we don't jump to neighbour nodes
|
||||||
// (assuming past our neighbour there is no such key)
|
// (assuming past our neighbour there is no such key)
|
||||||
private inner class Segment(val size: Int, private val lock: Any) {
|
private inner class Segment(val size: Int, private val lock: ReentrantLock) {
|
||||||
private val queue = ReferenceQueue<T>()
|
private val queue = ReferenceQueue<T>()
|
||||||
|
|
||||||
val mask = size - 1
|
val mask = size - 1
|
||||||
@ -183,7 +185,7 @@ class HashTableInterner<T : Any>(private val segmentBits: Int) : Interner<T> {
|
|||||||
var p: Ref<T>? = queue.poll() as Ref<T>? ?: return 0
|
var p: Ref<T>? = queue.poll() as Ref<T>? ?: return 0
|
||||||
var any = 0
|
var any = 0
|
||||||
|
|
||||||
synchronized(lock) {
|
lock.withLock {
|
||||||
while (p != null) {
|
while (p != null) {
|
||||||
check(remove(p!!)) { "Unable to remove null entry $p at hash ${hash(p!!)}" }
|
check(remove(p!!)) { "Unable to remove null entry $p at hash ${hash(p!!)}" }
|
||||||
p = queue.poll() as Ref<T>?
|
p = queue.poll() as Ref<T>?
|
||||||
@ -234,7 +236,7 @@ class HashTableInterner<T : Any>(private val segmentBits: Int) : Interner<T> {
|
|||||||
val find = segment.search(sample)
|
val find = segment.search(sample)
|
||||||
if (find != null) return find
|
if (find != null) return find
|
||||||
|
|
||||||
synchronized(locks[segmentIndex]) {
|
locks[segmentIndex].withLock {
|
||||||
segment = segments[segmentIndex]
|
segment = segments[segmentIndex]
|
||||||
|
|
||||||
val find = segment.search(sample)
|
val find = segment.search(sample)
|
||||||
|
Loading…
Reference in New Issue
Block a user