Files
sdk/runtime/lib/concurrent.cc
T
Ryan Macnak 12be1f79d2 [vm] Test active mutator stealing works with dart:concurrent locks.
- Add Monitor.notifyAll.
 - Refactor Mutex.runLocked to unlock if interrupted by unwind error.
 - Fix skipped DLRT_ExitHandleScope during an unwind error.

TEST=vm/dart/isolates/many_isolates_blocked_at_monitor_test
Bug: https://github.com/dart-lang/sdk/issues/55991
CoreLibraryReviewExempt: VM-only experimental library
Change-Id: I7a37544436e22158e45ee44567600fcf7ff7d7b6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/409561
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
2025-02-18 10:33:14 -08:00

114 lines
3.8 KiB
C++

// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#include "include/dart_api.h"
#include "vm/bootstrap_natives.h"
#include "vm/os_thread.h"
namespace dart {
static void DeleteMutex(void* isolate_data, void* mutex_pointer) {
delete reinterpret_cast<Mutex*>(mutex_pointer);
}
static constexpr int kMutexNativeField = 0;
DEFINE_FFI_NATIVE_ENTRY(Mutex_Initialize, void, (Dart_Handle mutex_handle)) {
Mutex* mutex = new Mutex();
Dart_Handle err = Dart_SetNativeInstanceField(
mutex_handle, kMutexNativeField, reinterpret_cast<intptr_t>(mutex));
if (Dart_IsError(err)) {
delete mutex;
Dart_PropagateError(err);
}
Dart_NewFinalizableHandle(mutex_handle, mutex, sizeof(Mutex), DeleteMutex);
};
DEFINE_FFI_NATIVE_ENTRY(Mutex_RunLocked,
Dart_Handle,
(Dart_Handle mutex_handle,
Dart_Handle closure_handle)) {
Mutex* mutex;
Dart_Handle result = Dart_GetNativeInstanceField(
mutex_handle, kMutexNativeField, reinterpret_cast<intptr_t*>(&mutex));
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
mutex->Lock();
result = Dart_InvokeClosure(closure_handle, 0, nullptr);
mutex->Unlock();
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
return result;
}
static void DeleteConditionVariable(void* isolate_data, void* condvar_pointer) {
delete reinterpret_cast<ConditionVariable*>(condvar_pointer);
}
static constexpr int kCondVarNativeField = 0;
DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_Initialize,
void,
(Dart_Handle condvar_handle)) {
ConditionVariable* condvar = new ConditionVariable();
Dart_Handle err = Dart_SetNativeInstanceField(
condvar_handle, kCondVarNativeField, reinterpret_cast<intptr_t>(condvar));
if (Dart_IsError(err)) {
delete condvar;
Dart_PropagateError(err);
}
Dart_NewFinalizableHandle(condvar_handle, condvar, sizeof(ConditionVariable),
DeleteConditionVariable);
}
DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_Wait,
void,
(Dart_Handle condvar_handle,
Dart_Handle mutex_handle)) {
Mutex* mutex;
Dart_Handle result_mutex = Dart_GetNativeInstanceField(
mutex_handle, kCondVarNativeField, reinterpret_cast<intptr_t*>(&mutex));
if (Dart_IsError(result_mutex)) {
Dart_PropagateError(result_mutex);
}
ConditionVariable* condvar;
Dart_Handle result_condvar =
Dart_GetNativeInstanceField(condvar_handle, kCondVarNativeField,
reinterpret_cast<intptr_t*>(&condvar));
if (Dart_IsError(result_condvar)) {
Dart_PropagateError(result_condvar);
}
condvar->Wait(mutex);
}
DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_Notify,
void,
(Dart_Handle condvar_handle)) {
ConditionVariable* condvar;
Dart_Handle result_condvar =
Dart_GetNativeInstanceField(condvar_handle, kCondVarNativeField,
reinterpret_cast<intptr_t*>(&condvar));
if (Dart_IsError(result_condvar)) {
Dart_PropagateError(result_condvar);
}
condvar->Notify();
}
DEFINE_FFI_NATIVE_ENTRY(ConditionVariable_NotifyAll,
void,
(Dart_Handle condvar_handle)) {
ConditionVariable* condvar;
Dart_Handle result_condvar =
Dart_GetNativeInstanceField(condvar_handle, kCondVarNativeField,
reinterpret_cast<intptr_t*>(&condvar));
if (Dart_IsError(result_condvar)) {
Dart_PropagateError(result_condvar);
}
condvar->NotifyAll();
}
} // namespace dart