[K/N] Worker API improvements ^KT-52429

Merge-request: KT-MR-6898
Merged-by: Alexander Shabalin <Alexander.Shabalin@jetbrains.com>
This commit is contained in:
Alexander Shabalin
2022-08-22 10:41:14 +00:00
committed by Space
parent 6e2202ad5a
commit 6f844f15e0
9 changed files with 206 additions and 0 deletions
@@ -1115,6 +1115,11 @@ standaloneTest("worker_threadlocal_no_leak") {
source = "runtime/workers/worker_threadlocal_no_leak.kt"
}
task worker_list_workers(type: KonanLocalTest) {
disabled = (project.testTarget == 'wasm32') // Needs pthreads.
source = "runtime/workers/worker_list_workers.kt"
}
standaloneTest("freeze0") {
enabled = (project.testTarget != 'wasm32') && (cacheTesting == null) // No workers on WASM.
useGoldenData = true
@@ -4322,6 +4327,12 @@ createInterop("threadStates") {
it.extraOpts "-Xcompile-source", "$projectDir/interop/threadStates/threadStates.cpp"
}
createInterop("workerSignals") {
it.defFile "interop/workerSignals/workerSignals.def"
it.headers "$projectDir/interop/workerSignals/workerSignals.h"
it.extraOpts "-Xcompile-source", "$projectDir/interop/workerSignals/workerSignals.cpp"
}
if (PlatformInfo.isAppleTarget(project)) {
createInterop("objcSmoke") {
it.defFile 'interop/objc/objcSmoke.def'
@@ -4827,6 +4838,13 @@ interopTest("interop_cppSkiaSignature") {
UtilsKt.dependsOnPlatformLibs(it)
}
interopTest("interop_workerSignals") {
disabled = (project.testTarget == 'wasm32') || // No interop for wasm yet.
(project.testTarget == 'mingw_x86' || project.testTarget == 'mingw_x64') // cross-thread signalling does not work on Windows
source = "interop/workerSignals/workerSignals.kt"
interop = "workerSignals"
}
/*
TODO: This test isn't run automatically
task interop_echo_server(type: RunInteropKonanTest) {
@@ -0,0 +1,31 @@
#include "workerSignals.h"
#include <cassert>
#include <pthread.h>
#include <signal.h>
namespace {
int pendingValue = 0;
thread_local int value = 0;
void signalHandler(int signal) {
value = pendingValue;
}
} // namespace
extern "C" void setupSignalHandler(void) {
signal(SIGUSR1, &signalHandler);
}
extern "C" void signalThread(uint64_t thread, int value) {
pendingValue = value;
auto t = reinterpret_cast<pthread_t>(thread);
auto result = pthread_kill(t, SIGUSR1);
assert(result == 0);
}
extern "C" int getValue(void) {
return value;
}
@@ -0,0 +1,2 @@
language = C
headerFilter = **/workerSignals.h
@@ -0,0 +1,13 @@
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
void setupSignalHandler(void);
void signalThread(uint64_t thread, int value);
int getValue(void);
#ifdef __cplusplus
}
#endif
@@ -0,0 +1,27 @@
@file:OptIn(kotlin.ExperimentalStdlibApi::class)
import kotlin.native.concurrent.*
import kotlin.test.*
import workerSignals.*
const val defaultValue = 0
const val newValue = 42
fun main() {
setupSignalHandler()
withWorker {
val before = execute(TransferMode.SAFE, {}) {
getValue()
}.result
assertEquals(defaultValue, getValue())
assertEquals(defaultValue, before)
signalThread(platformThreadId, newValue)
val after = execute(TransferMode.SAFE, {}) {
getValue()
}.result
assertEquals(defaultValue, getValue())
assertEquals(newValue, after)
}
}
@@ -0,0 +1,38 @@
@file:OptIn(kotlin.ExperimentalStdlibApi::class)
package runtime.workers.worker_list_workers
import kotlin.native.concurrent.*
import kotlin.test.*
const val WORKER_COUNT = 10
@Test
fun getAllWorkers() {
val workers = Array(WORKER_COUNT) { Worker.start() }
val expectedWorkers = listOf(Worker.current) + workers
assertEquals(expectedWorkers.toSet(), Worker.activeWorkers.toSet())
workers.forEach {
it.requestTermination().result
}
}
@Test
fun getActiveWorkers() {
val workers = Array(WORKER_COUNT) { Worker.start() }
val expectedWorkers = mutableListOf(Worker.current)
(0 until WORKER_COUNT step 2).forEach { i ->
workers[i].requestTermination().result
expectedWorkers.add(workers[i + 1])
}
assertEquals(expectedWorkers.toSet(), Worker.activeWorkers.toSet())
(0 until WORKER_COUNT step 2).forEach { i ->
workers[i + 1].requestTermination().result
}
}