[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:
committed by
Commit Queue
parent
f7c4bcf3c9
commit
95f5efc697
+4
-38
@@ -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",
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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_
|
||||
@@ -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 };
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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_() {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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
@@ -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 = []
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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_() {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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() {}
|
||||
|
||||
@@ -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_);
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user