split booting into preBoot, boot and postBoot, booting performance improvements

This commit is contained in:
Moritz Zwerger 2023-10-11 19:26:08 +02:00
parent 84378cbcec
commit 68608934cb
No known key found for this signature in database
GPG Key ID: 5CAD791931B09AC4
11 changed files with 68 additions and 28 deletions

View File

@ -18,10 +18,10 @@ import de.bixilon.kutil.concurrent.pool.DefaultThreadPool.async
import de.bixilon.kutil.concurrent.pool.ThreadPool
import de.bixilon.kutil.concurrent.worker.task.TaskWorker
import de.bixilon.kutil.concurrent.worker.task.WorkerTask
import de.bixilon.kutil.exception.ExceptionUtil.catchAll
import de.bixilon.kutil.file.watcher.FileWatcherService
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.latch.CallbackLatch
import de.bixilon.kutil.latch.SimpleLatch
import de.bixilon.kutil.observer.DataObserver.Companion.observe
import de.bixilon.kutil.os.OSTypes
import de.bixilon.kutil.os.PlatformInfo
@ -62,6 +62,7 @@ import de.bixilon.minosoft.terminal.RunConfiguration
import de.bixilon.minosoft.terminal.cli.CLI
import de.bixilon.minosoft.util.DesktopUtil
import de.bixilon.minosoft.util.KUtil
import de.bixilon.minosoft.util.json.Jackson
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
@ -74,27 +75,30 @@ object Minosoft {
val LANGUAGE_MANAGER = MultiLanguageManager()
val BOOT_LATCH = CallbackLatch(1)
@JvmStatic
fun main(args: Array<String>) {
val start = nanos()
private fun preBoot(args: Array<String>) {
Log::class.java.forceInit()
ShutdownManager.addHook { Log.ASYNC_LOGGING = false; catchAll { Log.await() } }
async(ThreadPool.Priorities.HIGHEST) { Jackson.init(); MinosoftPropertiesLoader.init() }
CommandLineArguments.parse(args)
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "Starting minosoft..." }
val latch = SimpleLatch(2)
DefaultThreadPool += { MINOSOFT_ASSETS_MANAGER.load(); MinosoftPropertiesLoader.load(); latch.dec() }
DefaultThreadPool += { ModLoader.initModLoading(); latch.dec() }
KUtil.initBootClasses()
KUtil.init()
ModLoader.initModLoading()
latch.await()
ModLoader.load(LoadingPhases.PRE_BOOT)
ModLoader.await(LoadingPhases.PRE_BOOT)
MINOSOFT_ASSETS_MANAGER.load()
if (PlatformInfo.OS == OSTypes.MAC) {
checkMacOS()
}
MinosoftPropertiesLoader.load()
}
private fun boot() {
val taskWorker = TaskWorker(errorHandler = { _, error -> error.printStackTrace(); error.crash() })
taskWorker += WorkerTask(identifier = BootTasks.VERSIONS, priority = ThreadPool.HIGHER + 2, executor = VersionLoader::load)
@ -128,13 +132,14 @@ object Minosoft {
taskWorker.work(BOOT_LATCH)
BOOT_LATCH.dec() // remove initial count
BOOT_LATCH.dec() // initial count
BOOT_LATCH.await()
}
private fun postBoot() {
if (ErosCrashReport.alreadyCrashed) return
val end = nanos()
KUtil.initPlayClasses()
Log.log(LogMessageType.GENERAL, LogLevels.INFO) { "Minosoft boot sequence finished in ${(end - start).formatNanos()}!" }
GlobalEventMaster.fire(FinishBootEvent())
DefaultThreadPool += { ModLoader.load(LoadingPhases.POST_BOOT) }
if (RunConfiguration.DISABLE_EROS) {
@ -144,6 +149,23 @@ object Minosoft {
RunConfiguration.AUTO_CONNECT_TO?.let { AutoConnect.autoConnect(it) }
}
@JvmStatic
fun main(args: Array<String>) {
val start = nanos()
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Pre booting..." }
preBoot(args)
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Booting..." }
boot()
val delta = nanos() - start
Log.log(LogMessageType.GENERAL, LogLevels.INFO) { "Minosoft boot sequence finished in ${delta.formatNanos()}!" }
Log.log(LogMessageType.OTHER, LogLevels.VERBOSE) { "Post booting..." }
postBoot()
}
private fun startFileWatcherService(latch: AbstractLatch) {
Log.log(LogMessageType.GENERAL, LogLevels.VERBOSE) { "Starting file watcher service..." }
FileWatcherService.start()

View File

@ -13,6 +13,7 @@
package de.bixilon.minosoft.assets.util
import com.fasterxml.jackson.databind.JavaType
import com.fasterxml.jackson.module.kotlin.readValue
import de.bixilon.kutil.buffer.BufferDefinition
import de.bixilon.kutil.cast.CastUtil.unsafeCast
@ -67,6 +68,16 @@ object InputStreamUtil {
}
}
inline fun <reified T> InputStream.readJson(close: Boolean = true, type: JavaType): T {
try {
return Jackson.MAPPER.readValue(this, type)
} finally {
if (close) {
this.close()
}
}
}
fun InputStream.readArchive(): Map<String, ByteArray> {
val content: MutableMap<String, ByteArray> = mutableMapOf()
val stream = TarInputStream(this)

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.data.language
import de.bixilon.kutil.exception.ExceptionUtil
import de.bixilon.kutil.exception.ExceptionUtil.tryCatch
import de.bixilon.kutil.json.JsonObject
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.assets.util.InputStreamUtil.readJsonObject
@ -109,7 +109,7 @@ object LanguageUtil {
if (name != FALLBACK_LANGUAGE) {
ExceptionUtil.tryCatch(FileNotFoundException::class.java, executor = { languages += loadLanguage(name, assetsManager, json, path) ?: return@tryCatch })
tryCatch(FileNotFoundException::class.java, executor = { languages += loadLanguage(name, assetsManager, json, path) ?: return@tryCatch })
}
loadLanguage(FALLBACK_LANGUAGE, assetsManager, json, path)?.let { languages += it }

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.gui.rendering.tint.tints
import de.bixilon.kutil.exception.ExceptionUtil
import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.assets.util.InputStreamUtil.readRGBArray
import de.bixilon.minosoft.data.container.stack.ItemStack
@ -27,7 +27,7 @@ class FoliageTintCalculator : TintProvider {
private lateinit var colorMap: IntArray
fun init(assetsManager: AssetsManager) {
colorMap = ExceptionUtil.ignoreAll { assetsManager["minecraft:colormap/foliage".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256)
colorMap = ignoreAll { assetsManager["minecraft:colormap/foliage".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256)
}
fun getBlockColor(biome: Biome?, y: Int): Int {

View File

@ -13,7 +13,7 @@
package de.bixilon.minosoft.gui.rendering.tint.tints
import de.bixilon.kutil.exception.ExceptionUtil
import de.bixilon.kutil.exception.ExceptionUtil.ignoreAll
import de.bixilon.minosoft.assets.AssetsManager
import de.bixilon.minosoft.assets.util.InputStreamUtil.readRGBArray
import de.bixilon.minosoft.data.registries.biomes.Biome
@ -29,7 +29,7 @@ class GrassTintCalculator : TintProvider {
private lateinit var colorMap: IntArray
fun init(assetsManager: AssetsManager) {
colorMap = ExceptionUtil.ignoreAll { assetsManager["minecraft:colormap/grass".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256)
colorMap = ignoreAll { assetsManager["minecraft:colormap/grass".toResourceLocation().texture()].readRGBArray() } ?: IntArray(256)
}
inline fun getColor(downfall: Int, temperature: Int): Int {

View File

@ -13,7 +13,6 @@
package de.bixilon.minosoft.modding.loader
import de.bixilon.kutil.concurrent.pool.DefaultThreadPool
import de.bixilon.kutil.concurrent.worker.unconditional.UnconditionalWorker
import de.bixilon.kutil.latch.AbstractLatch
import de.bixilon.kutil.latch.AbstractLatch.Companion.child
@ -29,7 +28,6 @@ import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
import java.io.File
import kotlin.reflect.jvm.javaField
object ModLoader {
@ -58,7 +56,7 @@ object ModLoader {
}
fun initModLoading() {
DefaultThreadPool += { createDirectories() }
createDirectories()
}
@ -239,6 +237,7 @@ object ModLoader {
}
private val ASSETS_MANAGER_FIELD = ModMain::assets.javaField!!.apply { isAccessible = true }
private val LOGGER_FIELD = ModMain::logger.javaField!!.apply { isAccessible = true }
private val MOD_MAIN = ModMain::class.java
private val ASSETS_MANAGER_FIELD = MOD_MAIN.getDeclaredField("assets").apply { isAccessible = true }
private val LOGGER_FIELD = MOD_MAIN.getDeclaredField("logger").apply { isAccessible = true }
}

View File

@ -18,15 +18,17 @@ import de.bixilon.minosoft.assets.util.InputStreamUtil.readJson
import de.bixilon.minosoft.data.registries.identified.Namespaces.minosoft
import de.bixilon.minosoft.properties.general.GeneralP
import de.bixilon.minosoft.terminal.RunConfiguration
import de.bixilon.minosoft.util.json.Jackson
import de.bixilon.minosoft.util.logging.Log
import de.bixilon.minosoft.util.logging.LogLevels
import de.bixilon.minosoft.util.logging.LogMessageType
object MinosoftPropertiesLoader {
val type = Jackson.MAPPER.constructType(MinosoftP::class.java)
fun load() {
val properties = Minosoft.MINOSOFT_ASSETS_MANAGER.getOrNull(minosoft("version.json"))?.readJson<MinosoftP>()
val properties = Minosoft.MINOSOFT_ASSETS_MANAGER.getOrNull(minosoft("version.json"))?.readJson<MinosoftP>(type = type)
MinosoftProperties = if (properties == null) {
Log.log(LogMessageType.OTHER, LogLevels.FATAL) { "Can not load version.json! Did you compile with gradle?" }
MinosoftP(GeneralP("unknown", false), null)
@ -37,4 +39,6 @@ object MinosoftPropertiesLoader {
RunConfiguration.APPLICATION_NAME = "Minosoft ${MinosoftProperties.general.name}"
Log.log(LogMessageType.OTHER, LogLevels.INFO) { "This is minosoft version ${MinosoftProperties.general.name}${MinosoftProperties.git?.let { ", built on ${it.commitShort}/${it.branch}" } ?: ""}!" }
}
fun init() = Unit
}

View File

@ -279,7 +279,6 @@ object KUtil {
fun initBootClasses() {
DefaultThreadPool += { GlobalEventMaster::class.java.forceInit() }
DefaultThreadPool += { ShutdownManager::class.java.forceInit() }
DefaultThreadPool += { Jackson::class.java.forceInit() }
DefaultThreadPool += { URLProtocolStreamHandlers::class.java.forceInit() }
DefaultThreadPool += { MicrosoftOAuthUtils::class.java.forceInit() }
DefaultThreadPool += { TaskScheduler::class.java.forceInit() }

View File

@ -14,7 +14,7 @@
package de.bixilon.minosoft.util.collections.floats
import de.bixilon.kutil.collections.primitive.floats.AbstractFloatList
import de.bixilon.kutil.exception.ExceptionUtil
import de.bixilon.kutil.exception.ExceptionUtil.catchAll
import org.lwjgl.system.MemoryUtil.memAllocFloat
import org.lwjgl.system.MemoryUtil.memFree
import java.nio.FloatBuffer
@ -22,7 +22,7 @@ import java.nio.FloatBuffer
object FloatListUtil {
const val PREFER_FRAGMENTED = true
val FLOAT_PUT_METHOD = ExceptionUtil.catchAll { FloatBuffer::class.java.getMethod("put", Int::class.java, FloatBuffer::class.java, Int::class.java, Int::class.java) }
val FLOAT_PUT_METHOD = catchAll { FloatBuffer::class.java.getMethod("put", Int::class.java, FloatBuffer::class.java, Int::class.java, Int::class.java) }
const val DEFAULT_INITIAL_SIZE = 1000
fun direct(initialSize: Int = DEFAULT_INITIAL_SIZE): AbstractFloatList {

View File

@ -61,4 +61,6 @@ object Jackson {
val JSON_MAP_TYPE: MapType = MAPPER.typeFactory.constructMapType(HashMap::class.java, Any::class.java, Any::class.java)
fun init() = Unit
}

View File

@ -13,6 +13,8 @@
package de.bixilon.minosoft.util.logging
import de.bixilon.kutil.ansi.ANSI
import de.bixilon.kutil.exception.ExceptionUtil.catchAll
import de.bixilon.kutil.shutdown.ShutdownManager
import de.bixilon.kutil.time.TimeUtil.millis
import de.bixilon.minosoft.config.StaticConfiguration
import de.bixilon.minosoft.config.profile.profiles.other.OtherProfileSelectEvent
@ -62,6 +64,7 @@ object Log {
}, "Log").start()
GlobalEventMaster.register(CallbackEventListener.of<OtherProfileSelectEvent> { this.levels = it.profile.log.levels })
ShutdownManager.addHook { ASYNC_LOGGING = false; catchAll { await() } }
}
private fun QueuedMessage.print() {