Remove unused Runtime suspend/resume (#4451)
This commit is contained in:
committed by
GitHub
parent
f6116477dd
commit
705f509028
@@ -2014,16 +2014,6 @@ void deinitMemory(MemoryState* memoryState) {
|
|||||||
::memoryState = nullptr;
|
::memoryState = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryState* suspendMemory() {
|
|
||||||
auto result = ::memoryState;
|
|
||||||
::memoryState = nullptr;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void resumeMemory(MemoryState* state) {
|
|
||||||
::memoryState = state;
|
|
||||||
}
|
|
||||||
|
|
||||||
void makeShareable(ContainerHeader* container) {
|
void makeShareable(ContainerHeader* container) {
|
||||||
if (!container->frozen())
|
if (!container->frozen())
|
||||||
container->makeShared();
|
container->makeShared();
|
||||||
@@ -3189,12 +3179,9 @@ void DeinitMemory(MemoryState* memoryState) {
|
|||||||
deinitMemory(memoryState);
|
deinitMemory(memoryState);
|
||||||
}
|
}
|
||||||
|
|
||||||
MemoryState* SuspendMemory() {
|
void RestoreMemory(MemoryState* memoryState) {
|
||||||
return suspendMemory();
|
RuntimeAssert((::memoryState == nullptr) || (::memoryState == memoryState), "Must not replace with unrelated memory state");
|
||||||
}
|
::memoryState = memoryState;
|
||||||
|
|
||||||
void ResumeMemory(MemoryState* state) {
|
|
||||||
resumeMemory(state);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OBJ_GETTER(AllocInstanceStrict, const TypeInfo* type_info) {
|
OBJ_GETTER(AllocInstanceStrict, const TypeInfo* type_info) {
|
||||||
|
|||||||
@@ -429,9 +429,7 @@ struct MemoryState;
|
|||||||
|
|
||||||
MemoryState* InitMemory();
|
MemoryState* InitMemory();
|
||||||
void DeinitMemory(MemoryState*);
|
void DeinitMemory(MemoryState*);
|
||||||
|
void RestoreMemory(MemoryState*);
|
||||||
MemoryState* SuspendMemory();
|
|
||||||
void ResumeMemory(MemoryState* state);
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// Object allocation.
|
// Object allocation.
|
||||||
|
|||||||
@@ -17,14 +17,12 @@ OBJ_GETTER(DescribeObjectForDebugging, KConstNativePtr typeInfo, KConstNativePtr
|
|||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
inline bool isForeignRefAccessible(ObjHeader* object, ForeignRefContext context) {
|
inline bool isForeignRefAccessible(ObjHeader* object, ForeignRefContext context) {
|
||||||
if (!Kotlin_hasRuntime()) {
|
// If runtime has not been initialized on this thread, then the object is either unowned or shared.
|
||||||
// So the object is either unowned or shared.
|
|
||||||
// In the former case initialized runtime is required to throw exceptions
|
// In the former case initialized runtime is required to throw exceptions
|
||||||
// in the latter case -- to provide proper execution context for caller.
|
// in the latter case -- to provide proper execution context for caller.
|
||||||
Kotlin_initRuntimeIfNeeded();
|
Kotlin_initRuntimeIfNeeded();
|
||||||
}
|
|
||||||
|
|
||||||
return IsForeignRefAccessible(object, context);
|
return IsForeignRefAccessible(object, context);
|
||||||
}
|
}
|
||||||
|
|
||||||
RUNTIME_NORETURN inline void throwIllegalSharingException(ObjHeader* object) {
|
RUNTIME_NORETURN inline void throwIllegalSharingException(ObjHeader* object) {
|
||||||
|
|||||||
@@ -25,12 +25,6 @@
|
|||||||
#include "Runtime.h"
|
#include "Runtime.h"
|
||||||
#include "Worker.h"
|
#include "Worker.h"
|
||||||
|
|
||||||
struct RuntimeState {
|
|
||||||
MemoryState* memoryState;
|
|
||||||
Worker* worker;
|
|
||||||
volatile int executionStatus;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef void (*Initializer)(int initialize, MemoryState* memory);
|
typedef void (*Initializer)(int initialize, MemoryState* memory);
|
||||||
struct InitNode {
|
struct InitNode {
|
||||||
Initializer init;
|
Initializer init;
|
||||||
@@ -42,6 +36,18 @@ namespace {
|
|||||||
InitNode* initHeadNode = nullptr;
|
InitNode* initHeadNode = nullptr;
|
||||||
InitNode* initTailNode = nullptr;
|
InitNode* initTailNode = nullptr;
|
||||||
|
|
||||||
|
enum class RuntimeStatus {
|
||||||
|
kUninitialized,
|
||||||
|
kRunning,
|
||||||
|
kDestroying,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct RuntimeState {
|
||||||
|
MemoryState* memoryState;
|
||||||
|
Worker* worker;
|
||||||
|
RuntimeStatus status = RuntimeStatus::kUninitialized;
|
||||||
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
INIT_GLOBALS = 0,
|
INIT_GLOBALS = 0,
|
||||||
INIT_THREAD_LOCAL_GLOBALS = 1,
|
INIT_THREAD_LOCAL_GLOBALS = 1,
|
||||||
@@ -49,24 +55,6 @@ enum {
|
|||||||
DEINIT_GLOBALS = 3
|
DEINIT_GLOBALS = 3
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
|
||||||
SUSPENDED = 0,
|
|
||||||
RUNNING,
|
|
||||||
DESTROYING
|
|
||||||
};
|
|
||||||
|
|
||||||
bool updateStatusIf(RuntimeState* state, int oldStatus, int newStatus) {
|
|
||||||
#if KONAN_NO_THREADS
|
|
||||||
if (state->executionStatus == oldStatus) {
|
|
||||||
state->executionStatus = newStatus;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
#else
|
|
||||||
return __sync_bool_compare_and_swap(&state->executionStatus, oldStatus, newStatus);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
void InitOrDeinitGlobalVariables(int initialize, MemoryState* memory) {
|
void InitOrDeinitGlobalVariables(int initialize, MemoryState* memory) {
|
||||||
InitNode* currentNode = initHeadNode;
|
InitNode* currentNode = initHeadNode;
|
||||||
while (currentNode != nullptr) {
|
while (currentNode != nullptr) {
|
||||||
@@ -108,11 +96,16 @@ RuntimeState* initRuntime() {
|
|||||||
InitOrDeinitGlobalVariables(INIT_GLOBALS, result->memoryState);
|
InitOrDeinitGlobalVariables(INIT_GLOBALS, result->memoryState);
|
||||||
}
|
}
|
||||||
InitOrDeinitGlobalVariables(INIT_THREAD_LOCAL_GLOBALS, result->memoryState);
|
InitOrDeinitGlobalVariables(INIT_THREAD_LOCAL_GLOBALS, result->memoryState);
|
||||||
|
RuntimeAssert(result->status == RuntimeStatus::kUninitialized, "Runtime must still be in the uninitialized state");
|
||||||
|
result->status = RuntimeStatus::kRunning;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
void deinitRuntime(RuntimeState* state) {
|
void deinitRuntime(RuntimeState* state) {
|
||||||
ResumeMemory(state->memoryState);
|
RuntimeAssert(state->status == RuntimeStatus::kRunning, "Runtime must be in the running state");
|
||||||
|
state->status = RuntimeStatus::kDestroying;
|
||||||
|
// This may be called after TLS is zeroed out, so ::memoryState in Memory cannot be trusted.
|
||||||
|
RestoreMemory(state->memoryState);
|
||||||
bool lastRuntime = atomicAdd(&aliveRuntimesCount, -1) == 0;
|
bool lastRuntime = atomicAdd(&aliveRuntimesCount, -1) == 0;
|
||||||
InitOrDeinitGlobalVariables(DEINIT_THREAD_LOCAL_GLOBALS, state->memoryState);
|
InitOrDeinitGlobalVariables(DEINIT_THREAD_LOCAL_GLOBALS, state->memoryState);
|
||||||
if (lastRuntime)
|
if (lastRuntime)
|
||||||
@@ -126,7 +119,6 @@ void deinitRuntime(RuntimeState* state) {
|
|||||||
|
|
||||||
void Kotlin_deinitRuntimeCallback(void* argument) {
|
void Kotlin_deinitRuntimeCallback(void* argument) {
|
||||||
auto* state = reinterpret_cast<RuntimeState*>(argument);
|
auto* state = reinterpret_cast<RuntimeState*>(argument);
|
||||||
RuntimeCheck(updateStatusIf(state, RUNNING, DESTROYING), "Cannot transition state to DESTROYING");
|
|
||||||
deinitRuntime(state);
|
deinitRuntime(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -147,7 +139,6 @@ void AppendToInitializersTail(InitNode *next) {
|
|||||||
void Kotlin_initRuntimeIfNeeded() {
|
void Kotlin_initRuntimeIfNeeded() {
|
||||||
if (!isValidRuntime()) {
|
if (!isValidRuntime()) {
|
||||||
initRuntime();
|
initRuntime();
|
||||||
RuntimeCheck(updateStatusIf(::runtimeState, SUSPENDED, RUNNING), "Cannot transition state to RUNNING for init");
|
|
||||||
// Register runtime deinit function at thread cleanup.
|
// Register runtime deinit function at thread cleanup.
|
||||||
konan::onThreadExit(Kotlin_deinitRuntimeCallback, runtimeState);
|
konan::onThreadExit(Kotlin_deinitRuntimeCallback, runtimeState);
|
||||||
}
|
}
|
||||||
@@ -160,42 +151,6 @@ void Kotlin_deinitRuntimeIfNeeded() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RuntimeState* Kotlin_createRuntime() {
|
|
||||||
return initRuntime();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Kotlin_destroyRuntime(RuntimeState* state) {
|
|
||||||
RuntimeCheck(updateStatusIf(state, SUSPENDED, DESTROYING), "Cannot transition state to DESTROYING");
|
|
||||||
deinitRuntime(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeState* Kotlin_suspendRuntime() {
|
|
||||||
RuntimeCheck(isValidRuntime(), "Runtime must be active on the current thread");
|
|
||||||
auto result = ::runtimeState;
|
|
||||||
RuntimeCheck(updateStatusIf(result, RUNNING, SUSPENDED), "Cannot transition state to SUSPENDED for suspend");
|
|
||||||
result->memoryState = SuspendMemory();
|
|
||||||
result->worker = WorkerSuspend();
|
|
||||||
::runtimeState = kInvalidRuntime;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Kotlin_resumeRuntime(RuntimeState* state) {
|
|
||||||
RuntimeCheck(!isValidRuntime(), "Runtime must not be active on the current thread");
|
|
||||||
RuntimeCheck(updateStatusIf(state, SUSPENDED, RUNNING), "Cannot transition state to RUNNING for resume");
|
|
||||||
::runtimeState = state;
|
|
||||||
ResumeMemory(state->memoryState);
|
|
||||||
WorkerResume(state->worker);
|
|
||||||
}
|
|
||||||
|
|
||||||
RuntimeState* Kotlin_getRuntime() {
|
|
||||||
RuntimeCheck(isValidRuntime(), "Runtime must be active on the current thread");
|
|
||||||
return ::runtimeState;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Kotlin_hasRuntime() {
|
|
||||||
return isValidRuntime();
|
|
||||||
}
|
|
||||||
|
|
||||||
void CheckIsMainThread() {
|
void CheckIsMainThread() {
|
||||||
if (!isMainThread)
|
if (!isMainThread)
|
||||||
ThrowIncorrectDereferenceException();
|
ThrowIncorrectDereferenceException();
|
||||||
|
|||||||
@@ -19,7 +19,6 @@
|
|||||||
|
|
||||||
#include "Porting.h"
|
#include "Porting.h"
|
||||||
|
|
||||||
struct RuntimeState;
|
|
||||||
struct InitNode;
|
struct InitNode;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
@@ -29,24 +28,6 @@ extern "C" {
|
|||||||
void Kotlin_initRuntimeIfNeeded();
|
void Kotlin_initRuntimeIfNeeded();
|
||||||
void Kotlin_deinitRuntimeIfNeeded();
|
void Kotlin_deinitRuntimeIfNeeded();
|
||||||
|
|
||||||
// Operations below allow flexible runtime scheduling on different threads.
|
|
||||||
// Created runtime is in SUSPENDED state, and need to be resumed for actual execution.
|
|
||||||
RuntimeState* Kotlin_createRuntime();
|
|
||||||
// Runtime must be in SUSPENDED state, before it could be destroyed.
|
|
||||||
void Kotlin_destroyRuntime(RuntimeState*);
|
|
||||||
|
|
||||||
// Transition current runtime from RUNNING to SUSPENDED state, and clearing thread local variable caching
|
|
||||||
// the runtime. After suspension, runtime could be rescheduled to a different thread.
|
|
||||||
RuntimeState* Kotlin_suspendRuntime();
|
|
||||||
// Transition runtime from SUSPENDED to RUNNING state, and sets thread local variable caching
|
|
||||||
// the runtime. After resume, current thread could be used for executing Kotlin code.
|
|
||||||
void Kotlin_resumeRuntime(RuntimeState*);
|
|
||||||
|
|
||||||
// Gets currently active runtime, fails if no runtime is currently available.
|
|
||||||
RuntimeState* Kotlin_getRuntime();
|
|
||||||
|
|
||||||
bool Kotlin_hasRuntime();
|
|
||||||
|
|
||||||
// Appends given node to an initializer list.
|
// Appends given node to an initializer list.
|
||||||
void AppendToInitializersTail(struct InitNode*);
|
void AppendToInitializersTail(struct InitNode*);
|
||||||
|
|
||||||
|
|||||||
@@ -752,22 +752,6 @@ void WaitNativeWorkerTermination(KInt id) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Worker* WorkerSuspend() {
|
|
||||||
#if WITH_WORKERS
|
|
||||||
auto* result = ::g_worker;
|
|
||||||
::g_worker = nullptr;
|
|
||||||
return result;
|
|
||||||
#else
|
|
||||||
return nullptr;
|
|
||||||
#endif // WITH_WORKERS
|
|
||||||
}
|
|
||||||
|
|
||||||
void WorkerResume(Worker* worker) {
|
|
||||||
#if WITH_WORKERS
|
|
||||||
::g_worker = worker;
|
|
||||||
#endif // WITH_WORKERS
|
|
||||||
}
|
|
||||||
|
|
||||||
bool WorkerSchedule(KInt id, KNativePtr jobStablePtr) {
|
bool WorkerSchedule(KInt id, KNativePtr jobStablePtr) {
|
||||||
#if WITH_WORKERS
|
#if WITH_WORKERS
|
||||||
return theState()->scheduleJobInWorkerUnlocked(id, jobStablePtr);
|
return theState()->scheduleJobInWorkerUnlocked(id, jobStablePtr);
|
||||||
@@ -819,7 +803,9 @@ namespace {
|
|||||||
void* workerRoutine(void* argument) {
|
void* workerRoutine(void* argument) {
|
||||||
Worker* worker = reinterpret_cast<Worker*>(argument);
|
Worker* worker = reinterpret_cast<Worker*>(argument);
|
||||||
|
|
||||||
WorkerResume(worker);
|
// Kotlin_initRuntimeIfNeeded calls WorkerInit that needs
|
||||||
|
// to see there's already a worker created for this thread.
|
||||||
|
::g_worker = worker;
|
||||||
Kotlin_initRuntimeIfNeeded();
|
Kotlin_initRuntimeIfNeeded();
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
|||||||
@@ -19,7 +19,4 @@ void WaitNativeWorkerTermination(KInt id);
|
|||||||
// Schedule the job without the result.
|
// Schedule the job without the result.
|
||||||
bool WorkerSchedule(KInt id, KNativePtr jobStablePtr);
|
bool WorkerSchedule(KInt id, KNativePtr jobStablePtr);
|
||||||
|
|
||||||
Worker* WorkerSuspend();
|
|
||||||
void WorkerResume(Worker* worker);
|
|
||||||
|
|
||||||
#endif // RUNTIME_WORKER_H
|
#endif // RUNTIME_WORKER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user