fix some potential dead locks

This commit is contained in:
Bixilon 2022-10-03 00:09:20 +02:00
parent 0eb265aebb
commit 5ca8e057f6
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
5 changed files with 31 additions and 40 deletions

View File

@ -134,7 +134,7 @@ Support for macOS is a delicate topic. Let's say it works for now, but it is not
Using IntelliJ IDEA for building or developing is strongly recommended. There you have features like build caching. Using IntelliJ IDEA for building or developing is strongly recommended. There you have features like build caching.
If you run into errors, please ensure you have the latest version of it. If you run into errors, please ensure you have the latest version of it.
You might need to increase heap memory for the compiler (`File` -> `Settings` -> `Build, Execution and Compiler` -> `Compiler` -> `Shared build process heap size`). You might need to increase heap memory for the compiler (`File` -> `Settings` -> `Build, Execution, Deployment` -> `Compiler` -> `Shared build process heap size`).
Allow at least 1500 MBytes. Allow at least 1500 MBytes.
## Code mirrors ## Code mirrors

View File

@ -1,6 +1,6 @@
/* /*
* Minosoft * Minosoft
* Copyright (C) 2020-2022 Moritz Zwerger and contributors * Copyright (C) 2020-2022 Moritz Zwerger
* *
* This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. * This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.
* *
@ -17,11 +17,9 @@ import de.bixilon.kotlinglm.vec3.Vec3i
import de.bixilon.kutil.array.ArrayUtil.cast import de.bixilon.kutil.array.ArrayUtil.cast
import de.bixilon.kutil.collections.map.LockMap import de.bixilon.kutil.collections.map.LockMap
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.concurrent.pool.ThreadPool import de.bixilon.kutil.concurrent.pool.ThreadPool
import de.bixilon.kutil.concurrent.pool.ThreadPoolRunnable
import de.bixilon.kutil.concurrent.worker.TaskWorker import de.bixilon.kutil.concurrent.worker.TaskWorker
import de.bixilon.kutil.latch.CountUpAndDownLatch import de.bixilon.kutil.concurrent.worker.tasks.Task
import de.bixilon.kutil.watcher.DataWatcher.Companion.watched import de.bixilon.kutil.watcher.DataWatcher.Companion.watched
import de.bixilon.minosoft.data.Difficulties import de.bixilon.minosoft.data.Difficulties
import de.bixilon.minosoft.data.entities.block.BlockEntity import de.bixilon.minosoft.data.entities.block.BlockEntity
@ -36,6 +34,7 @@ import de.bixilon.minosoft.data.world.biome.accessor.BiomeAccessor
import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor import de.bixilon.minosoft.data.world.biome.accessor.NoiseBiomeAccessor
import de.bixilon.minosoft.data.world.border.WorldBorder import de.bixilon.minosoft.data.world.border.WorldBorder
import de.bixilon.minosoft.data.world.chunk.Chunk import de.bixilon.minosoft.data.world.chunk.Chunk
import de.bixilon.minosoft.data.world.chunk.light.SectionLight
import de.bixilon.minosoft.data.world.particle.AbstractParticleRenderer import de.bixilon.minosoft.data.world.particle.AbstractParticleRenderer
import de.bixilon.minosoft.data.world.particle.WorldParticleRenderer import de.bixilon.minosoft.data.world.particle.WorldParticleRenderer
import de.bixilon.minosoft.data.world.positions.BlockPosition import de.bixilon.minosoft.data.world.positions.BlockPosition
@ -281,18 +280,17 @@ class World(
val simulationDistance = view.simulationDistance val simulationDistance = view.simulationDistance
val cameraPosition = connection.player.positionInfo.chunkPosition val cameraPosition = connection.player.positionInfo.chunkPosition
chunks.lock.acquire() chunks.lock.acquire()
val latch = CountUpAndDownLatch(chunks.unsafe.size) val worker = TaskWorker()
for ((chunkPosition, chunk) in chunks.unsafe) { for ((chunkPosition, chunk) in chunks.unsafe) {
// ToDo: Cache (improve performance) // ToDo: Cache (improve performance)
if (!chunkPosition.isInViewDistance(simulationDistance, cameraPosition)) { if (!chunkPosition.isInViewDistance(simulationDistance, cameraPosition)) {
latch.dec()
continue continue
} }
DefaultThreadPool += ThreadPoolRunnable(priority = ThreadPool.HIGH) { chunk.tick(connection, chunkPosition); latch.dec() } worker += Task(priority = ThreadPool.HIGH) { chunk.tick(connection, chunkPosition) }
} }
chunks.lock.release() chunks.lock.release()
worker.work()
border.tick() border.tick()
latch.await()
} }
fun randomTick() { fun randomTick() {
@ -406,7 +404,7 @@ class World(
fun getBrightness(position: BlockPosition): Float { fun getBrightness(position: BlockPosition): Float {
val light = getLight(position) val light = getLight(position)
val level = maxOf(light and 0x0F, light and 0xF0 shr 4) val level = maxOf(light and SectionLight.BLOCK_LIGHT_MASK, light and SectionLight.SKY_LIGHT_MASK shr 4)
return dimension?.lightLevels?.get(level) ?: 0.0f return dimension?.lightLevels?.get(level) ?: 0.0f
} }

View File

@ -15,10 +15,9 @@ package de.bixilon.minosoft.data.world
import de.bixilon.kotlinglm.vec3.Vec3d import de.bixilon.kotlinglm.vec3.Vec3d
import de.bixilon.kutil.concurrent.lock.simple.SimpleLock import de.bixilon.kutil.concurrent.lock.simple.SimpleLock
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.concurrent.pool.ThreadPool import de.bixilon.kutil.concurrent.pool.ThreadPool
import de.bixilon.kutil.concurrent.pool.ThreadPoolRunnable import de.bixilon.kutil.concurrent.worker.TaskWorker
import de.bixilon.kutil.latch.CountUpAndDownLatch import de.bixilon.kutil.concurrent.worker.tasks.Task
import de.bixilon.minosoft.data.abilities.Gamemodes import de.bixilon.minosoft.data.abilities.Gamemodes
import de.bixilon.minosoft.data.entities.entities.Entity import de.bixilon.minosoft.data.entities.entities.Entity
import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity import de.bixilon.minosoft.data.entities.entities.player.PlayerEntity
@ -185,12 +184,12 @@ class WorldEntities : Iterable<Entity> {
fun tick() { fun tick() {
lock.acquire() lock.acquire()
val latch = CountUpAndDownLatch(entities.size) val worker = TaskWorker()
for (entity in entities) { for (entity in entities) {
DefaultThreadPool += ThreadPoolRunnable(priority = ThreadPool.Priorities.HIGH) { entity.tryTick(); latch.dec() } worker += Task(priority = ThreadPool.Priorities.HIGH) { entity.tryTick() }
} }
lock.release() lock.release()
latch.await() worker.work()
} }
companion object { companion object {

View File

@ -14,7 +14,6 @@
package de.bixilon.minosoft.data.world.weather package de.bixilon.minosoft.data.world.weather
class WorldWeather { class WorldWeather {
var raining = false var raining = false
var rainGradient = 0.0f var rainGradient = 0.0f
var thunderGradient = 0.0f var thunderGradient = 0.0f

View File

@ -15,9 +15,9 @@ package de.bixilon.minosoft.gui.rendering.renderer.renderer
import de.bixilon.kutil.cast.CastUtil.unsafeCast import de.bixilon.kutil.cast.CastUtil.unsafeCast
import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf import de.bixilon.kutil.collections.CollectionUtil.synchronizedMapOf
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.concurrent.pool.ThreadPool import de.bixilon.kutil.concurrent.pool.ThreadPool
import de.bixilon.kutil.concurrent.pool.ThreadPoolRunnable import de.bixilon.kutil.concurrent.worker.TaskWorker
import de.bixilon.kutil.concurrent.worker.tasks.Task
import de.bixilon.kutil.latch.CountUpAndDownLatch import de.bixilon.kutil.latch.CountUpAndDownLatch
import de.bixilon.minosoft.config.profile.ConnectionProfiles import de.bixilon.minosoft.config.profile.ConnectionProfiles
import de.bixilon.minosoft.data.registries.ResourceLocation import de.bixilon.minosoft.data.registries.ResourceLocation
@ -64,38 +64,34 @@ class RendererManager(
} }
fun init(latch: CountUpAndDownLatch) { fun init(latch: CountUpAndDownLatch) {
val inner = CountUpAndDownLatch(1, latch) val inner = CountUpAndDownLatch(0, latch)
var worker = TaskWorker()
for (renderer in renderers.values) { for (renderer in renderers.values) {
inner.inc() worker += { renderer.preAsyncInit(inner) }
DefaultThreadPool += { renderer.preAsyncInit(inner); inner.dec() }
} }
inner.dec() worker.work(inner)
inner.await()
for (renderer in renderers.values) { for (renderer in renderers.values) {
renderer.init(latch) renderer.init(inner)
} }
val inner2 = CountUpAndDownLatch(1, latch) worker = TaskWorker()
for (renderer in renderers.values) { for (renderer in renderers.values) {
inner2.inc() worker += { renderer.asyncInit(inner) }
DefaultThreadPool += { renderer.asyncInit(inner2); inner2.dec() }
} }
inner2.dec() worker.work(inner)
inner2.await()
} }
fun postInit(latch: CountUpAndDownLatch) { fun postInit(latch: CountUpAndDownLatch) {
for (renderer in renderers.values) { for (renderer in renderers.values) {
renderer.postInit(latch) renderer.postInit(latch)
} }
val inner = CountUpAndDownLatch(1, latch) val inner = CountUpAndDownLatch(0, latch)
val worker = TaskWorker()
for (renderer in renderers.values) { for (renderer in renderers.values) {
inner.inc() worker += { renderer.postAsyncInit(inner) }
DefaultThreadPool += { renderer.postAsyncInit(inner); inner.dec() }
} }
inner.dec() worker.work(inner)
inner.await()
} }
private fun renderNormal(rendererList: Collection<Renderer>) { private fun renderNormal(rendererList: Collection<Renderer>) {
@ -123,16 +119,15 @@ class RendererManager(
renderer.prePrepareDraw() renderer.prePrepareDraw()
} }
val latch = CountUpAndDownLatch(1) val latch = CountUpAndDownLatch(0)
val worker = TaskWorker()
for (renderer in rendererList) { for (renderer in rendererList) {
if (renderer !is AsyncRenderer) { if (renderer !is AsyncRenderer) {
continue continue
} }
latch.inc() worker += Task(priority = ThreadPool.HIGHER) { renderer.prepareDrawAsync() }
DefaultThreadPool += ThreadPoolRunnable(priority = ThreadPool.HIGHER) { renderer.prepareDrawAsync(); latch.dec() }
} }
latch.dec() worker.work(latch)
latch.await()
for (renderer in rendererList) { for (renderer in rendererList) {
renderer.postPrepareDraw() renderer.postPrepareDraw()