diff --git a/assets/disk1/!BOOTSEC b/assets/disk1/!BOOTSEC index da786b1..d17e967 100644 --- a/assets/disk1/!BOOTSEC +++ b/assets/disk1/!BOOTSEC @@ -1 +1,16 @@ -let p=_BIOS.FIRST_BOOTABLE_PORT;com.sendMessage(p[0],"DEVRST\x17");com.sendMessage(p[0],'OPENR"WORKBENCH",'+p[1]);let r=com.getStatusCode(p[0]);if(0==r)if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){let g=com.pullMessage(p[0]);eval(g)}else println("I/O Error");else println("WORKBENCH not found");println("Shutting down...");println("It is now safe to turn off the power"); +let p=_BIOS.FIRST_BOOTABLE_PORT; +com.sendMessage(p[0],"DEVRST\x17"); +com.sendMessage(p[0],'OPENR"DESKTOP",'+p[1]); +let r=com.getStatusCode(p[0]); +if(0==r) + if(com.sendMessage(p[0],"READ"),r=com.getStatusCode(p[0]),0==r){ + let g=com.pullMessage(p[0]); + eval(g) + } + else + println("I/O Error"); +else { + println("DESKTOP not found"); +} + +println("CPU halted"); diff --git a/assets/disk1/DESKTOP b/assets/disk1/DESKTOP new file mode 100644 index 0000000..371e2a1 --- /dev/null +++ b/assets/disk1/DESKTOP @@ -0,0 +1,65 @@ +con.move(2,1) + + + +let prog1 = "let k=3;while(1){print(k);sys.sleep(600);}" +let prog2 = "let k=4;while(1){print(k);sys.sleep(500);}" +let progIllegal = "parallel.spawnNewContext()" + +let context1 = parallel.spawnNewContext() +let context2 = parallel.spawnNewContext() +let contextIllegal = parallel.spawnNewContext() + +let runner1 = parallel.attachProgram("Program1", context1, prog1) +let runner2 = parallel.attachProgram("Program2", context2, prog2) +let runnerIllegal = parallel.attachProgram("ProgramIllegal", contextIllegal, progIllegal) + +con.move(2,1) +parallel.launch(runner1) +parallel.launch(runner2) + + + + +function showTaskmgr() { + let contexts = parallel.getThreadPool() + con.clear() + contexts.forEach(it=>{ + println("> "+it.getName()) + }) +} + + +let exit = false + +while (!exit) { + + parallel.suspend(runner1) + parallel.suspend(runner2) + let [y,x] = con.getyx() + con.move(1,2) + print(`Used mem: ${sys.getUsedMem()} ; ${Math.random()} `) + con.move(y,x) + parallel.resume(runner1) + parallel.resume(runner2) + + sys.spin() + + if (sys.getSysrq()) exit = true +} + +parallel.launch(runnerIllegal) // will throw TypeError with Unknown identifier + +sys.unsetSysrq() + +parallel.suspend(runner1) +parallel.suspend(runner2) + +showTaskmgr() // will show three programs + +parallel.kill(runner1) +parallel.kill(runner2) +parallel.kill(runnerIllegal) +//showTaskmgr() // will show nothing + +println("Threads killed") \ No newline at end of file diff --git a/assets/disk1/WORKBENCH b/assets/disk1/WORKBENCH deleted file mode 100644 index d491950..0000000 --- a/assets/disk1/WORKBENCH +++ /dev/null @@ -1,33 +0,0 @@ -con.move(2,1) - - - -let prog1 = "while(1){print(1);sys.sleep(600);}" -let prog2 = "while(1){print(2);sys.sleep(500);}" - -let context1 = parallel.spawnNewContext() -let context2 = parallel.spawnNewContext() - -let runner1 = parallel.attachProgram(context1, prog1) -let runner2 = parallel.attachProgram(context2, prog2) - -con.move(2,1) -parallel.launch(runner1) -parallel.launch(runner2) - - -let exit = false - -while (!exit) { - - parallel.suspend(runner1) - parallel.suspend(runner2) - let [y,x] = con.getyx() - con.move(1,2) - print(`Used mem: ${sys.getUsedMem()} ; ${Math.random()} `) - con.move(y,x) - parallel.resume(runner1) - parallel.resume(runner2) - - sys.spin() -} \ No newline at end of file diff --git a/tsvm_core/src/net/torvald/tsvm/VM.kt b/tsvm_core/src/net/torvald/tsvm/VM.kt index 2c9368d..90f6459 100644 --- a/tsvm_core/src/net/torvald/tsvm/VM.kt +++ b/tsvm_core/src/net/torvald/tsvm/VM.kt @@ -53,6 +53,7 @@ class VM( var resetDown = false var stopDown = false + var sysrqDown = false var romMapping = 255 internal set diff --git a/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt b/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt index 8258b13..dc89f0f 100644 --- a/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt +++ b/tsvm_core/src/net/torvald/tsvm/VMJSR223Delegate.kt @@ -144,6 +144,11 @@ class VMJSR223Delegate(val vm: VM) { fun waitForMemChg(addr: Int, andMask: Int) = waitForMemChg(addr, andMask, 0) fun getUsedMem() = vm.allocatedBlockCount * vm.MALLOC_UNIT + + fun getSysrq() = vm.sysrqDown + fun unsetSysrq() { + vm.sysrqDown = false + } } class VMSerialDebugger(val vm: VM) { @@ -156,8 +161,8 @@ class Parallel(val vm: VM) { fun spawnNewContext(): VMRunner { return VMRunnerFactory(vm.assetsDir, vm, "js") } - fun attachProgram(context: VMRunner, program: String): Thread { - Thread { context.eval(program) }.let { + fun attachProgram(name: String, context: VMRunner, program: String): Thread { + Thread({ context.eval(program) }, name).let { vm.contexts.add(it) return it } @@ -171,4 +176,11 @@ class Parallel(val vm: VM) { fun resume(thread: Thread) { thread.resume() } -} \ No newline at end of file + fun kill(thread: Thread) { + thread.interrupt() + vm.contexts.remove(thread) + } + fun getThreadPool() = vm.contexts +} + +class ParallelDummy() \ No newline at end of file diff --git a/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt b/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt index 0d26154..521a736 100644 --- a/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt +++ b/tsvm_core/src/net/torvald/tsvm/VMRunnerFactory.kt @@ -6,9 +6,9 @@ import java.io.FileReader import javax.script.ScriptEngineManager abstract class VMRunner(val extension: String) { - abstract suspend fun executeCommand(command: String) - abstract suspend fun evalGlobal(command: String) - abstract fun eval(command: String) + abstract suspend fun evalGlobal(command: String) // Ring 0 + abstract suspend fun executeCommand(command: String) // Ring 1 + abstract fun eval(command: String) // Ring 2 (for child processes spawned using Parallel API) abstract fun close() } @@ -47,6 +47,9 @@ object VMRunnerFactory { }*/ "js" -> { object : VMRunner(extension) { + private val ringOneParallel = Parallel(vm) + private val ringTwoParallel = ParallelDummy() + private val context = Context.newBuilder("js") .allowHostAccess(HostAccess.ALL) .allowHostClassLookup { false } @@ -66,7 +69,7 @@ object VMRunnerFactory { bind.putMember("base64", Base64Delegate) bind.putMember("com", SerialHelperDelegate(vm)) bind.putMember("dma", DMADelegate(vm)) - bind.putMember("parallel", Parallel(vm)) + bind.putMember("parallel", ringOneParallel) val fr = FileReader("$assetsRoot/JS_INIT.js") val prg = fr.readText() @@ -76,6 +79,7 @@ object VMRunnerFactory { override suspend fun executeCommand(command: String) { try { + bind.putMember("parallel", ringOneParallel) context.eval("js", encapsulateJS(sanitiseJS(command))) } catch (e: javax.script.ScriptException) { @@ -87,6 +91,7 @@ object VMRunnerFactory { override fun eval(command: String) { try { + bind.putMember("parallel", ringTwoParallel) context.eval("js", encapsulateJS(sanitiseJS(command))) } catch (e: javax.script.ScriptException) { @@ -96,6 +101,7 @@ object VMRunnerFactory { } } override suspend fun evalGlobal(command: String) { + bind.putMember("parallel", ringOneParallel) context.eval("js", "\"use strict\";" + sanitiseJS(command)) } diff --git a/tsvm_core/src/net/torvald/tsvm/peripheral/IOSpace.kt b/tsvm_core/src/net/torvald/tsvm/peripheral/IOSpace.kt index 53355a3..e6967af 100644 --- a/tsvm_core/src/net/torvald/tsvm/peripheral/IOSpace.kt +++ b/tsvm_core/src/net/torvald/tsvm/peripheral/IOSpace.kt @@ -255,10 +255,10 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor { } // SIGTERM key combination: Ctrl+Shift+T+R - vm.stopDown = Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) && + vm.stopDown = (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) && Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) && Gdx.input.isKeyPressed(Input.Keys.T) && - Gdx.input.isKeyPressed(Input.Keys.R) + Gdx.input.isKeyPressed(Input.Keys.R)) || Gdx.input.isKeyPressed(Input.Keys.PAUSE) if (vm.stopDown) println("[VM-${vm.id}] SIGTERM requested") // RESET key combination: Ctrl+Shift+R+S @@ -267,6 +267,13 @@ class IOSpace(val vm: VM) : PeriBase, InputProcessor { Gdx.input.isKeyPressed(Input.Keys.R) && Gdx.input.isKeyPressed(Input.Keys.S) if (vm.resetDown) println("[VM-${vm.id}] RESET requested") + + // SYSRQ key combination: Ctrl+Shift+S+Q + vm.sysrqDown = (Gdx.input.isKeyPressed(Input.Keys.SHIFT_LEFT) && + Gdx.input.isKeyPressed(Input.Keys.CONTROL_LEFT) && + Gdx.input.isKeyPressed(Input.Keys.Q) && + Gdx.input.isKeyPressed(Input.Keys.S)) || Gdx.input.isKeyPressed(Input.Keys.PRINT_SCREEN) + if (vm.sysrqDown) println("[VM-${vm.id}] SYSRQ requested") } override fun touchUp(p0: Int, p1: Int, p2: Int, p3: Int): Boolean {