[vm/concurrent] Use ffi native resolver for dart:concurrent native functions.

Ffi native interface should be faster, more effecient for Dart->C++ communication, so switching to it.
TEST=ci

Change-Id: I9e1d18a666737799194c0435c300e4b81783c0ec
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/377541
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Daco Harkes <dacoharkes@google.com>
This commit is contained in:
Alexander Aprelev
2024-07-26 19:26:11 +00:00
committed by Commit Queue
parent f7c4bcf3c9
commit 95f5efc697
35 changed files with 449 additions and 448 deletions
+4 -38
View File
@@ -14,7 +14,6 @@ import("../vm/vm_sources.gni")
import("builtin_impl_sources.gni")
import("builtin_sources.gni")
import("cli_sources.gni")
import("concurrent_impl_sources.gni")
import("io_impl_sources.gni")
import("io_sources.gni")
import("native_assets_impl_sources.gni")
@@ -136,37 +135,11 @@ build_native_assets_api("native_assets_api_product") {
]
}
template("build_concurrent_api") {
extra_configs = []
if (defined(invoker.extra_configs)) {
extra_configs += invoker.extra_configs
}
source_set(target_name) {
configs += [ "..:dart_config" ] + extra_configs
deps = []
include_dirs = [ ".." ]
sources = concurrent_api_sources
sources += [
"concurrent_natives.cc",
"concurrent_natives.h",
]
}
# TODO(aam): Remove once https://dart-review.googlesource.com/c/sdk/+/377541
# rolls into flutter engine.
source_set("concurrent_api") {
}
build_concurrent_api("concurrent_api") {
extra_configs = [
"..:dart_maybe_product_config",
"..:dart_os_config",
"..:dart_arch_config",
]
}
build_concurrent_api("concurrent_api_product") {
extra_configs = [
"..:dart_product_config",
"..:dart_os_config",
"..:dart_arch_config",
]
source_set("concurrent_api_product") {
}
static_library("crashpad") {
@@ -881,12 +854,6 @@ template("dart_executable") {
deps += [ ":standalone_dart_io" ]
}
if (use_product_mode) {
deps += [ ":concurrent_api_product" ]
} else {
deps += [ ":concurrent_api" ]
}
configs += [ ":export_api_symbols" ]
ldflags = extra_ldflags
@@ -1133,7 +1100,6 @@ executable("run_vm_tests") {
}
deps = [
":concurrent_api",
":crashpad",
":dart_kernel_platform_cc",
":dart_snapshot_cc",
+1 -7
View File
@@ -13,7 +13,6 @@
#include "platform/assert.h"
#include "bin/builtin.h"
#include "bin/concurrent_natives.h"
#include "bin/dartutils.h"
#include "bin/file.h"
#include "bin/io_natives.h"
@@ -25,8 +24,7 @@ namespace bin {
// Lists the native functions implementing basic functionality in
// standalone dart, such as printing, file I/O, and platform information.
// Advanced I/O classes like sockets and process management are implemented
// using functions listed in io_natives.cc and synchronization primitives -
// in concurrent_natives.cc.
// using functions listed in io_natives.cc.
#define BUILTIN_NATIVE_LIST(V) V(Builtin_PrintString, 1)
BUILTIN_NATIVE_LIST(DECLARE_FUNCTION);
@@ -65,10 +63,6 @@ Dart_NativeFunction Builtin::NativeLookup(Dart_Handle name,
}
Dart_NativeFunction result =
IONativeLookup(name, argument_count, auto_setup_scope);
if (result != nullptr) {
return result;
}
result = ConcurrentNativeLookup(name, argument_count, auto_setup_scope);
if (result == nullptr) {
result = Builtin_DummyNative;
}
-104
View File
@@ -1,104 +0,0 @@
// 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 "bin/builtin.h"
#include "bin/thread.h"
#include "include/dart_api.h"
namespace dart {
namespace bin {
static constexpr int kMutexNativeField = 0;
static constexpr int kCondVarNativeField = 0;
static void DeleteMutex(void* isolate_data, void* mutex_pointer) {
delete reinterpret_cast<Mutex*>(mutex_pointer);
}
void FUNCTION_NAME(Mutex_Initialize)(Dart_NativeArguments args) {
Dart_Handle mutex_obj = Dart_GetNativeArgument(args, 0);
Mutex* mutex = new Mutex();
Dart_Handle err = Dart_SetNativeInstanceField(
mutex_obj, kMutexNativeField, reinterpret_cast<intptr_t>(mutex));
if (Dart_IsError(err)) {
delete mutex;
Dart_PropagateError(err);
}
Dart_NewFinalizableHandle(mutex_obj, mutex, sizeof(Mutex), DeleteMutex);
}
void FUNCTION_NAME(Mutex_Lock)(Dart_NativeArguments args) {
Dart_Handle mutex_obj = Dart_GetNativeArgument(args, 0);
Mutex* mutex;
Dart_Handle result = Dart_GetNativeInstanceField(
mutex_obj, kMutexNativeField, reinterpret_cast<intptr_t*>(&mutex));
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
mutex->Lock();
Dart_SetReturnValue(args, Dart_Null());
}
void FUNCTION_NAME(Mutex_Unlock)(Dart_NativeArguments args) {
Dart_Handle mutex_obj = Dart_GetNativeArgument(args, 0);
Mutex* mutex;
Dart_Handle result = Dart_GetNativeInstanceField(
mutex_obj, kMutexNativeField, reinterpret_cast<intptr_t*>(&mutex));
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
mutex->Unlock();
Dart_SetReturnValue(args, Dart_Null());
}
static void DeleteConditionVariable(void* isolate_data, void* condvar_pointer) {
delete reinterpret_cast<ConditionVariable*>(condvar_pointer);
}
void FUNCTION_NAME(ConditionVariable_Initialize)(Dart_NativeArguments args) {
Dart_Handle condvar_obj = Dart_GetNativeArgument(args, 0);
ConditionVariable* condvar = new ConditionVariable();
Dart_Handle err = Dart_SetNativeInstanceField(
condvar_obj, kCondVarNativeField, reinterpret_cast<intptr_t>(condvar));
if (Dart_IsError(err)) {
delete condvar;
Dart_PropagateError(err);
}
Dart_NewFinalizableHandle(condvar_obj, condvar, sizeof(ConditionVariable),
DeleteConditionVariable);
}
void FUNCTION_NAME(ConditionVariable_Wait)(Dart_NativeArguments args) {
Dart_Handle condvar_obj = Dart_GetNativeArgument(args, 0);
Dart_Handle mutex_obj = Dart_GetNativeArgument(args, 1);
Mutex* mutex;
Dart_Handle result_mutex = Dart_GetNativeInstanceField(
mutex_obj, kCondVarNativeField, reinterpret_cast<intptr_t*>(&mutex));
if (Dart_IsError(result_mutex)) {
Dart_PropagateError(result_mutex);
}
ConditionVariable* condvar;
Dart_Handle result_condvar = Dart_GetNativeInstanceField(
condvar_obj, kCondVarNativeField, reinterpret_cast<intptr_t*>(&condvar));
if (Dart_IsError(result_condvar)) {
Dart_PropagateError(result_condvar);
}
condvar->Wait(mutex);
Dart_SetReturnValue(args, Dart_Null());
}
void FUNCTION_NAME(ConditionVariable_Notify)(Dart_NativeArguments args) {
Dart_Handle condvar_obj = Dart_GetNativeArgument(args, 0);
ConditionVariable* condvar;
Dart_Handle result_condvar = Dart_GetNativeInstanceField(
condvar_obj, kCondVarNativeField, reinterpret_cast<intptr_t*>(&condvar));
if (Dart_IsError(result_condvar)) {
Dart_PropagateError(result_condvar);
}
condvar->Notify();
Dart_SetReturnValue(args, Dart_Null());
}
} // namespace bin
} // namespace dart
-63
View File
@@ -1,63 +0,0 @@
// 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 "bin/concurrent_natives.h"
#include "bin/builtin.h"
namespace dart {
namespace bin {
// Lists the native functions implementing advanced dart:io classes.
// Some classes, like File and Directory, list their implementations in
// builtin_natives.cc instead.
#define CONCURRENT_NATIVE_LIST(V) \
V(Mutex_Initialize, 1) \
V(Mutex_Lock, 1) \
V(Mutex_Unlock, 1) \
V(ConditionVariable_Initialize, 1) \
V(ConditionVariable_Wait, 2) \
V(ConditionVariable_Notify, 1)
CONCURRENT_NATIVE_LIST(DECLARE_FUNCTION);
static const struct NativeEntries {
const char* name_;
Dart_NativeFunction function_;
int argument_count_;
} ConcurrentEntries[] = {CONCURRENT_NATIVE_LIST(REGISTER_FUNCTION)};
Dart_NativeFunction ConcurrentNativeLookup(Dart_Handle name,
int argument_count,
bool* auto_setup_scope) {
const char* function_name = nullptr;
Dart_Handle result = Dart_StringToCString(name, &function_name);
ASSERT(!Dart_IsError(result));
ASSERT(function_name != nullptr);
ASSERT(auto_setup_scope != nullptr);
*auto_setup_scope = true;
int num_entries = sizeof(ConcurrentEntries) / sizeof(struct NativeEntries);
for (int i = 0; i < num_entries; i++) {
const struct NativeEntries* entry = &(ConcurrentEntries[i]);
if ((strcmp(function_name, entry->name_) == 0) &&
(entry->argument_count_ == argument_count)) {
return reinterpret_cast<Dart_NativeFunction>(entry->function_);
}
}
return nullptr;
}
const uint8_t* ConcurrentNativeSymbol(Dart_NativeFunction nf) {
int num_entries = sizeof(ConcurrentEntries) / sizeof(struct NativeEntries);
for (int i = 0; i < num_entries; i++) {
const struct NativeEntries* entry = &(ConcurrentEntries[i]);
if (reinterpret_cast<Dart_NativeFunction>(entry->function_) == nf) {
return reinterpret_cast<const uint8_t*>(entry->name_);
}
}
return nullptr;
}
} // namespace bin
} // namespace dart
-22
View File
@@ -1,22 +0,0 @@
// 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.
#ifndef RUNTIME_BIN_CONCURRENT_NATIVES_H_
#define RUNTIME_BIN_CONCURRENT_NATIVES_H_
#include "include/dart_api.h"
namespace dart {
namespace bin {
Dart_NativeFunction ConcurrentNativeLookup(Dart_Handle name,
int argument_count,
bool* auto_setup_scope);
const uint8_t* ConcurrentNativeSymbol(Dart_NativeFunction nf);
} // namespace bin
} // namespace dart
#endif // RUNTIME_BIN_CONCURRENT_NATIVES_H_
-16
View File
@@ -69,25 +69,9 @@ class Mutex {
private:
MutexData data_;
friend class ConditionVariable;
DISALLOW_COPY_AND_ASSIGN(Mutex);
};
class ConditionVariable {
public:
ConditionVariable();
~ConditionVariable();
void Wait(Mutex* mutex);
void Notify();
private:
ConditionVariableData data_;
DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
};
class Monitor {
public:
enum WaitResult { kNotified, kTimedOut };
-13
View File
@@ -150,19 +150,6 @@ void Mutex::Unlock() {
data_.mutex()->Unlock();
}
ConditionVariable::ConditionVariable() {}
ConditionVariable::~ConditionVariable() {}
ABSL_NO_THREAD_SAFETY_ANALYSIS
void ConditionVariable::Wait(Mutex* mutex) {
data_.cond()->Wait(mutex->data_.mutex());
}
void ConditionVariable::Notify() {
data_.cond()->Signal();
}
Monitor::Monitor() : data_() {}
Monitor::~Monitor() {}
-16
View File
@@ -30,27 +30,11 @@ class MutexData {
absl::Mutex mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() : cond_() {}
~ConditionVariableData() {}
absl::CondVar* cond() { return &cond_; }
absl::CondVar cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() : mutex_(), cond_() {}
-31
View File
@@ -193,37 +193,6 @@ void Mutex::Unlock() {
ASSERT(result == 0); // Verify no other errors.
}
ConditionVariable::ConditionVariable() {
pthread_condattr_t cond_attr;
int result = pthread_condattr_init(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_cond_init(data_.cond(), &cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_destroy(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
}
ConditionVariable::~ConditionVariable() {
int result = pthread_cond_destroy(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Wait(Mutex* mutex) {
int result = pthread_cond_wait(data_.cond(), mutex->data_.mutex());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Notify() {
// TODO(iposva): Do we need to track lock owners?
int result = pthread_cond_signal(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
Monitor::Monitor() {
pthread_mutexattr_t mutex_attr;
int result = pthread_mutexattr_init(&mutex_attr);
-15
View File
@@ -29,26 +29,11 @@ class MutexData {
pthread_mutex_t mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
pthread_cond_t* cond() { return &cond_; }
pthread_cond_t cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
-31
View File
@@ -190,37 +190,6 @@ void Mutex::Unlock() {
ASSERT(result == 0); // Verify no other errors.
}
ConditionVariable::ConditionVariable() {
pthread_condattr_t cond_attr;
int result = pthread_condattr_init(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_cond_init(data_.cond(), &cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_destroy(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
}
ConditionVariable::~ConditionVariable() {
int result = pthread_cond_destroy(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Wait(Mutex* mutex) {
int result = pthread_cond_wait(data_.cond(), mutex->data_.mutex());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Notify() {
// TODO(iposva): Do we need to track lock owners?
int result = pthread_cond_signal(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
Monitor::Monitor() {
pthread_mutexattr_t mutex_attr;
int result = pthread_mutexattr_init(&mutex_attr);
-15
View File
@@ -29,26 +29,11 @@ class MutexData {
pthread_mutex_t mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
pthread_cond_t* cond() { return &cond_; }
pthread_cond_t cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
-21
View File
@@ -184,27 +184,6 @@ void Mutex::Unlock() {
ASSERT(result == 0); // Verify no other errors.
}
ConditionVariable::ConditionVariable() {
int result = pthread_cond_init(data_.cond(), nullptr);
VALIDATE_PTHREAD_RESULT(result);
}
ConditionVariable::~ConditionVariable() {
int result = pthread_cond_destroy(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Wait(Mutex* mutex) {
int result = pthread_cond_wait(data_.cond(), mutex->data_.mutex());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Notify() {
// TODO(iposva): Do we need to track lock owners?
int result = pthread_cond_signal(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
Monitor::Monitor() {
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
-15
View File
@@ -29,26 +29,11 @@ class MutexData {
pthread_mutex_t mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
pthread_cond_t* cond() { return &cond_; }
pthread_cond_t cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
-14
View File
@@ -106,20 +106,6 @@ void Mutex::Unlock() {
ReleaseSRWLockExclusive(&data_.lock_);
}
ConditionVariable::ConditionVariable() {
InitializeConditionVariable(&data_.cond_);
}
ConditionVariable::~ConditionVariable() {}
void ConditionVariable::Wait(Mutex* mutex) {
SleepConditionVariableSRW(&data_.cond_, &mutex->data_.lock_, INFINITE, 0);
}
void ConditionVariable::Notify() {
WakeConditionVariable(&data_.cond_);
}
Monitor::Monitor() {
InitializeCriticalSection(&data_.cs_);
InitializeConditionVariable(&data_.cond_);
-14
View File
@@ -25,25 +25,11 @@ class MutexData {
SRWLOCK lock_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
CONDITION_VARIABLE cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
+101
View File
@@ -0,0 +1,101 @@
// 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_Lock, void, (Dart_Handle mutex_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();
}
DEFINE_FFI_NATIVE_ENTRY(Mutex_Unlock, void, (Dart_Handle mutex_handle)) {
Mutex* mutex;
Dart_Handle result = Dart_GetNativeInstanceField(
mutex_handle, kMutexNativeField, reinterpret_cast<intptr_t*>(&mutex));
if (Dart_IsError(result)) {
Dart_PropagateError(result);
}
mutex->Unlock();
}
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();
}
} // namespace dart
@@ -2,4 +2,4 @@
# 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.
concurrent_api_sources = [ "concurrent.cc" ]
concurrent_runtime_cc_files = [ "concurrent.cc" ]
+6 -4
View File
@@ -24,6 +24,7 @@ import("../bin/cli_sources.gni")
import("../bin/io_sources.gni")
import("../configs.gni")
import("../lib/async_sources.gni")
import("../lib/concurrent_sources.gni")
import("../lib/convert_sources.gni")
import("../lib/core_sources.gni")
import("../lib/developer_sources.gni")
@@ -222,11 +223,12 @@ library_for_all_configs("libdart_lib") {
extra_deps += [ "$fuchsia_sdk/pkg/trace-engine" ]
}
include_dirs = [ ".." ]
allsources = async_runtime_cc_files + core_runtime_cc_files +
developer_runtime_cc_files + isolate_runtime_cc_files +
allsources = async_runtime_cc_files + concurrent_runtime_cc_files +
core_runtime_cc_files + developer_runtime_cc_files +
ffi_runtime_cc_files + isolate_runtime_cc_files +
math_runtime_cc_files + mirrors_runtime_cc_files +
typed_data_runtime_cc_files + vmservice_runtime_cc_files +
ffi_runtime_cc_files
typed_data_runtime_cc_files + vmservice_runtime_cc_files
sources = [ "bootstrap.cc" ] + rebase_path(allsources, ".", "../lib")
snapshot_sources = []
}
+1
View File
@@ -117,6 +117,7 @@ void Bootstrap::SetupNativeResolver() {
ASSERT(!library.IsNull());
library.set_native_entry_resolver(resolver);
library.set_native_entry_symbol_resolver(symbol_resolver);
library.set_ffi_native_resolver(ffi_native_resolver);
library = Library::CoreLibrary();
ASSERT(!library.IsNull());
+6
View File
@@ -366,7 +366,13 @@ namespace dart {
V(VariableMirror_type, 2)
#define BOOTSTRAP_FFI_NATIVE_LIST(V) \
V(ConditionVariable_Initialize, void, (Dart_Handle)) \
V(ConditionVariable_Notify, void, (Dart_Handle)) \
V(ConditionVariable_Wait, void, (Dart_Handle, Dart_Handle)) \
V(FinalizerEntry_SetExternalSize, void, (Dart_Handle, intptr_t)) \
V(Mutex_Initialize, void, (Dart_Handle)) \
V(Mutex_Lock, void, (Dart_Handle)) \
V(Mutex_Unlock, void, (Dart_Handle)) \
V(Pointer_asTypedListFinalizerAllocateData, void*, ()) \
V(Pointer_asTypedListFinalizerCallbackPointer, void*, ())
+38 -2
View File
@@ -42,19 +42,23 @@ class Mutex {
explicit Mutex(NOT_IN_PRODUCT(const char* name = "anonymous mutex"));
~Mutex();
ThreadId InvalidateOwner();
void SetCurrentThreadAsOwner();
bool IsOwnedByCurrentThread() const;
private:
void Lock();
bool TryLock(); // Returns false if lock is busy and locking failed.
void Unlock();
private:
bool TryLock(); // Returns false if lock is busy and locking failed.
MutexData data_;
NOT_IN_PRODUCT(const char* name_);
#if defined(DEBUG)
ThreadId owner_;
#endif // defined(DEBUG)
friend class ConditionVariable;
friend class MallocLocker;
friend class MutexLocker;
friend class SafepointMutexLocker;
@@ -66,6 +70,20 @@ class Mutex {
DISALLOW_COPY_AND_ASSIGN(Mutex);
};
class ConditionVariable {
public:
ConditionVariable();
~ConditionVariable();
void Wait(Mutex* mutex);
void Notify();
private:
Mutex* mutex_;
ConditionVariableData data_;
DISALLOW_COPY_AND_ASSIGN(ConditionVariable);
};
class BaseThread {
public:
bool is_os_thread() const { return is_os_thread_; }
@@ -408,6 +426,24 @@ inline bool Mutex::IsOwnedByCurrentThread() const {
#endif
}
inline ThreadId Mutex::InvalidateOwner() {
#if defined(DEBUG)
ThreadId saved_owner = owner_;
owner_ = OSThread::kInvalidThreadId;
return saved_owner;
#else
UNREACHABLE();
#endif
}
inline void Mutex::SetCurrentThreadAsOwner() {
#if defined(DEBUG)
owner_ = OSThread::GetCurrentThreadId();
#else
UNREACHABLE();
#endif
}
// Mark when we are running in a signal handler (Linux, Android) or with a
// suspended thread (Windows, Mac, Fuchia). During this time, we cannot take
// locks, access Thread/Isolate::Current(), or use malloc.
+21
View File
@@ -374,6 +374,27 @@ void Mutex::Unlock() {
data_.mutex()->Unlock();
}
ConditionVariable::ConditionVariable() {}
ConditionVariable::~ConditionVariable() {}
void ConditionVariable::Wait(Mutex* mutex) {
#if defined(DEBUG)
ThreadId saved_owner = mutex->InvalidateOwner();
#endif
data_.cond()->Wait(mutex->data_.mutex());
#if defined(DEBUG)
mutex->SetCurrentThreadAsOwner();
ASSERT(OSThread::GetCurrentThreadId() == saved_owner);
#endif
}
void ConditionVariable::Notify() {
data_.cond()->Signal();
}
Monitor::Monitor() {
#if defined(DEBUG)
// When running with assertions enabled we track the owner.
+16
View File
@@ -50,11 +50,27 @@ class MutexData {
absl::Mutex mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() : cond_() {}
~ConditionVariableData() {}
absl::CondVar* cond() { return &cond_; }
absl::CondVar cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() : mutex_(), cond_() {}
+39
View File
@@ -369,6 +369,45 @@ void Mutex::Unlock() {
ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors.
}
ConditionVariable::ConditionVariable() {
pthread_condattr_t cond_attr;
int result = pthread_condattr_init(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_cond_init(data_.cond(), &cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_destroy(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
}
ConditionVariable::~ConditionVariable() {
int result = pthread_cond_destroy(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Wait(Mutex* mutex) {
#if defined(DEBUG)
ThreadId saved_owner = mutex->InvalidateOwner();
#endif
int result = pthread_cond_wait(data_.cond(), mutex->data_.mutex());
VALIDATE_PTHREAD_RESULT(result);
#if defined(DEBUG)
mutex->SetCurrentThreadAsOwner();
ASSERT(OSThread::GetCurrentThreadId() == saved_owner);
#endif
}
void ConditionVariable::Notify() {
int result = pthread_cond_signal(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
Monitor::Monitor() {
pthread_mutexattr_t mutex_attr;
int result = pthread_mutexattr_init(&mutex_attr);
+16
View File
@@ -49,11 +49,27 @@ class MutexData {
pthread_mutex_t mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
pthread_cond_t* cond() { return &cond_; }
pthread_cond_t cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
+39
View File
@@ -362,6 +362,45 @@ void Mutex::Unlock() {
ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors.
}
ConditionVariable::ConditionVariable() {
pthread_condattr_t cond_attr;
int result = pthread_condattr_init(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_cond_init(data_.cond(), &cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_destroy(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
}
ConditionVariable::~ConditionVariable() {
int result = pthread_cond_destroy(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Wait(Mutex* mutex) {
#if defined(DEBUG)
ThreadId saved_owner = mutex->InvalidateOwner();
#endif
int result = pthread_cond_wait(data_.cond(), mutex->data_.mutex());
VALIDATE_PTHREAD_RESULT(result);
#if defined(DEBUG)
mutex->SetCurrentThreadAsOwner();
ASSERT(OSThread::GetCurrentThreadId() == saved_owner);
#endif
}
void ConditionVariable::Notify() {
int result = pthread_cond_signal(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
Monitor::Monitor() {
pthread_mutexattr_t mutex_attr;
int result = pthread_mutexattr_init(&mutex_attr);
+16
View File
@@ -50,11 +50,27 @@ class MutexData {
pthread_mutex_t mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
pthread_cond_t* cond() { return &cond_; }
pthread_cond_t cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
+39
View File
@@ -370,6 +370,45 @@ void Mutex::Unlock() {
ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors.
}
ConditionVariable::ConditionVariable() {
pthread_condattr_t cond_attr;
int result = pthread_condattr_init(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_cond_init(data_.cond(), &cond_attr);
VALIDATE_PTHREAD_RESULT(result);
result = pthread_condattr_destroy(&cond_attr);
VALIDATE_PTHREAD_RESULT(result);
}
ConditionVariable::~ConditionVariable() {
int result = pthread_cond_destroy(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Wait(Mutex* mutex) {
#if defined(DEBUG)
ThreadId saved_owner = mutex->InvalidateOwner();
#endif
int result = pthread_cond_wait(data_.cond(), mutex->data_.mutex());
VALIDATE_PTHREAD_RESULT(result);
#if defined(DEBUG)
mutex->SetCurrentThreadAsOwner();
ASSERT(OSThread::GetCurrentThreadId() == saved_owner);
#endif
}
void ConditionVariable::Notify() {
int result = pthread_cond_signal(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
Monitor::Monitor() {
pthread_mutexattr_t mutex_attr;
int result = pthread_mutexattr_init(&mutex_attr);
+16
View File
@@ -49,11 +49,27 @@ class MutexData {
pthread_mutex_t mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
pthread_cond_t* cond() { return &cond_; }
pthread_cond_t cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
+29
View File
@@ -338,6 +338,35 @@ void Mutex::Unlock() {
ASSERT_PTHREAD_SUCCESS(result); // Verify no other errors.
}
ConditionVariable::ConditionVariable() {
int result = pthread_cond_init(data_.cond(), nullptr);
VALIDATE_PTHREAD_RESULT(result);
}
ConditionVariable::~ConditionVariable() {
int result = pthread_cond_destroy(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
void ConditionVariable::Wait(Mutex* mutex) {
#if defined(DEBUG)
ThreadId saved_owner = mutex->InvalidateOwner();
#endif
int result = pthread_cond_wait(data_.cond(), mutex->data_.mutex());
VALIDATE_PTHREAD_RESULT(result);
#if defined(DEBUG)
mutex->SetCurrentThreadAsOwner();
ASSERT(OSThread::GetCurrentThreadId() == saved_owner);
#endif
}
void ConditionVariable::Notify() {
int result = pthread_cond_signal(data_.cond());
VALIDATE_PTHREAD_RESULT(result);
}
Monitor::Monitor() {
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
+16
View File
@@ -50,11 +50,27 @@ class MutexData {
pthread_mutex_t mutex_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
pthread_cond_t* cond() { return &cond_; }
pthread_cond_t cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
+23
View File
@@ -278,6 +278,29 @@ void Mutex::Unlock() {
ReleaseSRWLockExclusive(&data_.lock_);
}
ConditionVariable::ConditionVariable() {
InitializeConditionVariable(&data_.cond_);
}
ConditionVariable::~ConditionVariable() {}
void ConditionVariable::Wait(Mutex* mutex) {
#if defined(DEBUG)
ThreadId saved_owner = mutex->InvalidateOwner();
#endif
SleepConditionVariableSRW(&data_.cond_, &mutex->data_.lock_, INFINITE, 0);
#if defined(DEBUG)
mutex->SetCurrentThreadAsOwner();
ASSERT(OSThread::GetCurrentThreadId() == saved_owner);
#endif
}
void ConditionVariable::Notify() {
WakeConditionVariable(&data_.cond_);
}
Monitor::Monitor() {
InitializeSRWLock(&data_.lock_);
InitializeConditionVariable(&data_.cond_);
+14
View File
@@ -47,11 +47,25 @@ class MutexData {
SRWLOCK lock_;
friend class Mutex;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(MutexData);
};
class ConditionVariableData {
private:
ConditionVariableData() {}
~ConditionVariableData() {}
CONDITION_VARIABLE cond_;
friend class ConditionVariable;
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(ConditionVariableData);
};
class MonitorData {
private:
MonitorData() {}
@@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
import "dart:_internal" show patch;
import "dart:ffi" show Handle, Void, Native;
import "dart:nativewrappers" show NativeFieldWrapperClass1;
@patch
@@ -18,15 +19,15 @@ base class _MutexImpl extends NativeFieldWrapperClass1 implements Mutex {
_initialize();
}
@pragma("vm:external-name", "Mutex_Initialize")
@Native<Void Function(Handle)>(symbol: "Mutex_Initialize")
external void _initialize();
@patch
@pragma("vm:external-name", "Mutex_Lock")
@Native<Void Function(Handle)>(symbol: "Mutex_Lock")
external void _lock();
@patch
@pragma("vm:external-name", "Mutex_Unlock")
@Native<Void Function(Handle)>(symbol: "Mutex_Unlock")
external void _unlock();
R runLocked<R>(R Function() action) {
@@ -55,14 +56,14 @@ base class _ConditionVariableImpl extends NativeFieldWrapperClass1
_initialize();
}
@pragma("vm:external-name", "ConditionVariable_Initialize")
@Native<Void Function(Handle)>(symbol: "ConditionVariable_Initialize")
external void _initialize();
@patch
@pragma("vm:external-name", "ConditionVariable_Wait")
@Native<Void Function(Handle, Handle)>(symbol: "ConditionVariable_Wait")
external void wait(Mutex mutex);
@patch
@pragma("vm:external-name", "ConditionVariable_Notify")
@Native<Void Function(Handle)>(symbol: "ConditionVariable_Notify")
external void notify();
}