[VM, Platform] Allow assigning names to mutexes.

Use this name when reporting errors.

We need this sort of debug information to better understand Isolate shutdown races like one in https://github.com/dart-lang/sdk/issues/28549

Bug: https://github.com/dart-lang/sdk/issues/28549
Change-Id: I24f27b4eef4faf4b2f80f82b269d88a6e5c3880b
Reviewed-on: https://dart-review.googlesource.com/4721
Commit-Queue: Vyacheslav Egorov <vegorov@google.com>
Reviewed-by: Zach Anderson <zra@google.com>
This commit is contained in:
Vyacheslav Egorov
2017-09-11 19:17:46 +00:00
parent f7eba2359b
commit c25ebfff96
7 changed files with 110 additions and 32 deletions
+10 -6
View File
@@ -846,11 +846,14 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
api_state_(NULL),
random_(),
simulator_(NULL),
mutex_(new Mutex()),
symbols_mutex_(new Mutex()),
type_canonicalization_mutex_(new Mutex()),
constant_canonicalization_mutex_(new Mutex()),
megamorphic_lookup_mutex_(new Mutex()),
mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::mutex_"))),
symbols_mutex_(new Mutex(NOT_IN_PRODUCT("Isolate::symbols_mutex_"))),
type_canonicalization_mutex_(
new Mutex(NOT_IN_PRODUCT("Isolate::type_canonicalization_mutex_"))),
constant_canonicalization_mutex_(new Mutex(
NOT_IN_PRODUCT("Isolate::constant_canonicalization_mutex_"))),
megamorphic_lookup_mutex_(
new Mutex(NOT_IN_PRODUCT("Isolate::megamorphic_lookup_mutex_"))),
message_handler_(NULL),
spawn_state_(NULL),
defer_finalization_count_(0),
@@ -862,7 +865,8 @@ Isolate::Isolate(const Dart_IsolateFlags& api_flags)
next_(NULL),
loading_invalidation_gen_(kInvalidGen),
top_level_parsing_count_(0),
field_list_mutex_(new Mutex()),
field_list_mutex_(
new Mutex(NOT_IN_PRODUCT("Isolate::field_list_mutex_"))),
boxed_field_list_(GrowableObjectArray::null()),
spawn_count_monitor_(new Monitor()),
spawn_count_(0),
+2 -1
View File
@@ -273,7 +273,7 @@ class OSThreadIterator : public ValueObject {
class Mutex {
public:
Mutex();
explicit Mutex(NOT_IN_PRODUCT(const char* name = "anonymous mutex"));
~Mutex();
#if defined(DEBUG)
@@ -293,6 +293,7 @@ class Mutex {
void Unlock();
MutexData data_;
NOT_IN_PRODUCT(const char* name_);
#if defined(DEBUG)
ThreadId owner_;
#endif // defined(DEBUG)
+23 -6
View File
@@ -28,6 +28,19 @@ namespace dart {
FATAL2("pthread error: %d (%s)", result, error_message); \
}
#if defined(PRODUCT)
#define VALIDATE_PTHREAD_RESULT_NAMED(result) VALIDATE_PTHREAD_RESULT(result)
#else
#define VALIDATE_PTHREAD_RESULT_NAMED(result) \
if (result != 0) { \
const int kBufferSize = 1024; \
char error_message[kBufferSize]; \
NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
Utils::StrError(result, error_message, kBufferSize); \
FATAL3("[%s] pthread error: %d (%s)", name_, result, error_message); \
}
#endif
#if defined(DEBUG)
#define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result)
#else
@@ -232,22 +245,26 @@ bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) {
return true;
}
Mutex::Mutex() {
Mutex::Mutex(NOT_IN_PRODUCT(const char* name))
#if !defined(PRODUCT)
: name_(name)
#endif
{
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#endif // defined(DEBUG)
result = pthread_mutex_init(data_.mutex(), &attr);
// Verify that creating a pthread_mutex succeeded.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
result = pthread_mutexattr_destroy(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we do track the owner.
@@ -258,7 +275,7 @@ Mutex::Mutex() {
Mutex::~Mutex() {
int result = pthread_mutex_destroy(data_.mutex());
// Verify that the pthread_mutex was destroyed.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we do track the owner.
+19 -6
View File
@@ -25,6 +25,15 @@ namespace dart {
FATAL1("pthread error: %d", result); \
}
#if defined(PRODUCT)
#define VALIDATE_PTHREAD_RESULT_NAMED(result) VALIDATE_PTHREAD_RESULT(result)
#else
#define VALIDATE_PTHREAD_RESULT_NAMED(result) \
if (result != 0) { \
FATAL2("[%s] pthread error: %d", name_, result); \
}
#endif
#if defined(DEBUG)
#define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result)
#else
@@ -200,22 +209,26 @@ bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) {
return false;
}
Mutex::Mutex() {
Mutex::Mutex(NOT_IN_PRODUCT(const char* name))
#if !defined(PRODUCT)
: name_(name)
#endif
{
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#endif // defined(DEBUG)
result = pthread_mutex_init(data_.mutex(), &attr);
// Verify that creating a pthread_mutex succeeded.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
result = pthread_mutexattr_destroy(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we track the owner.
@@ -226,7 +239,7 @@ Mutex::Mutex() {
Mutex::~Mutex() {
int result = pthread_mutex_destroy(data_.mutex());
// Verify that the pthread_mutex was destroyed.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we track the owner.
+24 -6
View File
@@ -30,6 +30,20 @@ namespace dart {
Utils::StrError(result, error_buf, kBufferSize)); \
}
// Variation of VALIDATE_PTHREAD_RESULT for named objects.
#if defined(PRODUCT)
#define VALIDATE_PTHREAD_RESULT_NAMED(result) VALIDATE_PTHREAD_RESULT(result)
#else
#define VALIDATE_PTHREAD_RESULT_NAMED(result) \
if (result != 0) { \
const int kBufferSize = 1024; \
char error_buf[kBufferSize]; \
NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
FATAL3("[%s] pthread error: %d (%s)", name_, result, \
Utils::StrError(result, error_buf, kBufferSize)); \
}
#endif
#if defined(DEBUG)
#define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result)
#else
@@ -233,22 +247,26 @@ bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) {
return true;
}
Mutex::Mutex() {
Mutex::Mutex(NOT_IN_PRODUCT(const char* name))
#if !defined(PRODUCT)
: name_(name)
#endif
{
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#endif // defined(DEBUG)
result = pthread_mutex_init(data_.mutex(), &attr);
// Verify that creating a pthread_mutex succeeded.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
result = pthread_mutexattr_destroy(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we track the owner.
@@ -259,7 +277,7 @@ Mutex::Mutex() {
Mutex::~Mutex() {
int result = pthread_mutex_destroy(data_.mutex());
// Verify that the pthread_mutex was destroyed.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we track the owner.
+23 -6
View File
@@ -34,6 +34,19 @@ namespace dart {
FATAL2("pthread error: %d (%s)", result, error_message); \
}
#if defined(PRODUCT)
#define VALIDATE_PTHREAD_RESULT_NAMED(result) VALIDATE_PTHREAD_RESULT(result)
#else
#define VALIDATE_PTHREAD_RESULT_NAMED(result) \
if (result != 0) { \
const int kBufferSize = 1024; \
char error_message[kBufferSize]; \
NOT_IN_PRODUCT(Profiler::DumpStackTrace()); \
Utils::StrError(result, error_message, kBufferSize); \
FATAL3("[%s] pthread error: %d (%s)", name_, result, error_message); \
}
#endif
#if defined(DEBUG)
#define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result)
#else
@@ -197,22 +210,26 @@ bool OSThread::GetCurrentStackBounds(uword* lower, uword* upper) {
return true;
}
Mutex::Mutex() {
Mutex::Mutex(NOT_IN_PRODUCT(const char* name))
#if !defined(PRODUCT)
: name_(name)
#endif
{
pthread_mutexattr_t attr;
int result = pthread_mutexattr_init(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#endif // defined(DEBUG)
result = pthread_mutex_init(data_.mutex(), &attr);
// Verify that creating a pthread_mutex succeeded.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
result = pthread_mutexattr_destroy(&attr);
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we do track the owner.
@@ -223,7 +240,7 @@ Mutex::Mutex() {
Mutex::~Mutex() {
int result = pthread_mutex_destroy(data_.mutex());
// Verify that the pthread_mutex was destroyed.
VALIDATE_PTHREAD_RESULT(result);
VALIDATE_PTHREAD_RESULT_NAMED(result);
#if defined(DEBUG)
// When running with assertions enabled we do track the owner.
+9 -1
View File
@@ -181,11 +181,19 @@ void OSThread::SetThreadLocal(ThreadLocalKey key, uword value) {
}
}
Mutex::Mutex() {
Mutex::Mutex(NOT_IN_PRODUCT(const char* name))
#if !defined(PRODUCT)
: name_(name)
#endif
{
// Allocate unnamed semaphore with initial count 1 and max count 1.
data_.semaphore_ = CreateSemaphore(NULL, 1, 1, NULL);
if (data_.semaphore_ == NULL) {
#if defined(PRODUCT)
FATAL1("Mutex allocation failed %d", GetLastError());
#else
FATAL2("[%s] Mutex allocation failed %d", name_, GetLastError());
#endif
}
#if defined(DEBUG)
// When running with assertions enabled we do track the owner.