[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
@@ -30,6 +30,7 @@
#include "Exceptions.h"
#include "KAssert.h"
#include "Memory.h"
#include "Natives.h"
#include "ObjCMMAPI.h"
#include "Runtime.h"
#include "Types.h"
@@ -632,6 +633,33 @@ class State {
}
}
KULong getWorkerPlatformThreadIdUnlocked(KInt id) {
Locker locker(&lock_);
auto it = workers_.find(id);
if (it == workers_.end()) {
ThrowWorkerAlreadyTerminated();
}
pthread_t thread = it->second->thread();
static_assert(sizeof(pthread_t) <= sizeof(KULong), "Casting pthread_t to ULong will lose data");
return reinterpret_cast<KULong>(thread);
}
OBJ_GETTER0(getActiveWorkers) {
std_support::vector<KInt> workers;
{
Locker locker(&lock_);
workers.reserve(workers_.size());
for (auto [id, worker] : workers_) {
workers.push_back(id);
}
}
ObjHolder arrayHolder;
AllocArrayInstance(theIntArrayTypeInfo, workers.size(), arrayHolder.slot());
std::copy(workers.begin(), workers.end(), IntArrayAddressOfElementAt(arrayHolder.obj()->array(), 0));
RETURN_OBJ(arrayHolder.obj());
}
private:
pthread_mutex_t lock_;
pthread_cond_t cond_;
@@ -764,6 +792,14 @@ KNativePtr detachObjectGraphInternal(KInt transferMode, KRef producer) {
}
}
KULong platformThreadId(KInt id) {
return theState()->getWorkerPlatformThreadIdUnlocked(id);
}
OBJ_GETTER0(activeWorkers) {
RETURN_RESULT_OF0(theState()->getActiveWorkers);
}
#else
KInt startWorker(WorkerExceptionHandling exceptionHandling, KRef customName) {
@@ -822,6 +858,14 @@ KNativePtr detachObjectGraphInternal(KInt transferMode, KRef producer) {
ThrowWorkerUnsupported();
}
KULong platformThreadId(KInt id) {
ThrowWorkerUnsupported();
}
OBJ_GETTER0(activeWorkers) {
ThrowWorkerUnsupported();
}
#endif // WITH_WORKERS
} // namespace
@@ -1224,4 +1268,12 @@ void Kotlin_Worker_waitTermination(KInt id) {
WaitNativeWorkerTermination(id);
}
KULong Kotlin_Worker_getPlatformThreadIdInternal(KInt id) {
return platformThreadId(id);
}
OBJ_GETTER0(Kotlin_Worker_getActiveWorkersInternal) {
RETURN_RESULT_OF0(activeWorkers);
}
} // extern "C"
@@ -128,3 +128,9 @@ external internal fun checkIfFrozen(ref: Any?)
@InternalForKotlinNative
@GCUnsafeCall("Kotlin_Worker_waitTermination")
external public fun waitWorkerTermination(worker: Worker)
@GCUnsafeCall("Kotlin_Worker_getPlatformThreadIdInternal")
external internal fun getPlatfromThreadIdInternal(id: Int): ULong
@GCUnsafeCall("Kotlin_Worker_getActiveWorkersInternal")
external internal fun getActiveWorkersInternal(): IntArray
@@ -60,6 +60,16 @@ public value class Worker @PublishedApi internal constructor(val id: Int) {
@Deprecated("Use kotlinx.cinterop.StableRef instead", level = DeprecationLevel.WARNING)
public fun fromCPointer(pointer: COpaquePointer?): Worker =
if (pointer != null) Worker(pointer.toLong().toInt()) else throw IllegalArgumentException()
/**
* Get a list of all unterminated workers.
*
* Thread safety: If some other thread calls [Worker.requestTermination] at the same time then this may
* return a [Worker] that's already terminated.
*/
@ExperimentalStdlibApi
public val activeWorkers: List<Worker>
get() = getActiveWorkersInternal().map { Worker(it) }
}
/**
@@ -170,6 +180,15 @@ public value class Worker @PublishedApi internal constructor(val id: Int) {
*/
@Deprecated("Use kotlinx.cinterop.StableRef instead", level = DeprecationLevel.WARNING)
public fun asCPointer() : COpaquePointer? = id.toLong().toCPointer()
/**
* Get platform thread id of the worker thread.
*
* Usually returns `pthread_t` casted to [ULong].
*/
@ExperimentalStdlibApi
public val platformThreadId: ULong
get() = getPlatfromThreadIdInternal(id)
}
/**