Replacing alloy::Mutex with std::mutex.

This commit is contained in:
Ben Vanik
2014-07-09 22:28:51 -07:00
parent 500647968c
commit c5f114018e
23 changed files with 170 additions and 371 deletions

View File

@@ -9,7 +9,8 @@
#include <alloy/runtime/debugger.h>
#include <alloy/mutex.h>
#include <mutex>
#include <alloy/runtime/runtime.h>
using namespace alloy;
@@ -24,34 +25,28 @@ Breakpoint::~Breakpoint() {
}
Debugger::Debugger(Runtime* runtime) :
runtime_(runtime) {
threads_lock_ = AllocMutex();
breakpoints_lock_ = AllocMutex();
}
runtime_(runtime) {}
Debugger::~Debugger() {
FreeMutex(breakpoints_lock_);
FreeMutex(threads_lock_);
}
Debugger::~Debugger() {}
int Debugger::SuspendAllThreads(uint32_t timeout_ms) {
std::lock_guard<std::mutex> guard(threads_lock_);
int result = 0;
LockMutex(threads_lock_);
for (auto it = threads_.begin(); it != threads_.end(); ++it) {
ThreadState* thread_state = it->second;
if (thread_state->Suspend(timeout_ms)) {
result = 1;
}
}
UnlockMutex(threads_lock_);
return result;
}
int Debugger::ResumeThread(uint32_t thread_id) {
LockMutex(threads_lock_);
std::lock_guard<std::mutex> guard(threads_lock_);
auto it = threads_.find(thread_id);
if (it == threads_.end()) {
UnlockMutex(threads_lock_);
return 1;
}
@@ -59,38 +54,38 @@ int Debugger::ResumeThread(uint32_t thread_id) {
ThreadState* thread_state = it->second;
int result = thread_state->Resume();
UnlockMutex(threads_lock_);
return result;
}
int Debugger::ResumeAllThreads(bool force) {
std::lock_guard<std::mutex> guard(threads_lock_);
int result = 0;
LockMutex(threads_lock_);
for (auto it = threads_.begin(); it != threads_.end(); ++it) {
ThreadState* thread_state = it->second;
if (thread_state->Resume(force)) {
result = 1;
}
}
UnlockMutex(threads_lock_);
return result;
}
void Debugger::ForEachThread(std::function<void(ThreadState*)> callback) {
LockMutex(threads_lock_);
std::lock_guard<std::mutex> guard(threads_lock_);
for (auto it = threads_.begin(); it != threads_.end(); ++it) {
ThreadState* thread_state = it->second;
callback(thread_state);
}
UnlockMutex(threads_lock_);
}
int Debugger::AddBreakpoint(Breakpoint* breakpoint) {
// Add to breakpoints map.
LockMutex(breakpoints_lock_);
breakpoints_.insert(
std::pair<uint64_t, Breakpoint*>(breakpoint->address(), breakpoint));
UnlockMutex(breakpoints_lock_);
{
std::lock_guard<std::mutex> guard(breakpoints_lock_);
breakpoints_.insert(
std::pair<uint64_t, Breakpoint*>(breakpoint->address(), breakpoint));
}
// Find all functions that contain the breakpoint address.
auto fns = runtime_->FindFunctionsWithAddress(breakpoint->address());
@@ -108,23 +103,23 @@ int Debugger::AddBreakpoint(Breakpoint* breakpoint) {
int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) {
// Remove from breakpoint map.
LockMutex(breakpoints_lock_);
auto range = breakpoints_.equal_range(breakpoint->address());
if (range.first == range.second) {
UnlockMutex(breakpoints_lock_);
return 1;
}
bool found = false;
for (auto it = range.first; it != range.second; ++it) {
if (it->second == breakpoint) {
breakpoints_.erase(it);
found = true;
break;
{
std::lock_guard<std::mutex> guard(breakpoints_lock_);
auto range = breakpoints_.equal_range(breakpoint->address());
if (range.first == range.second) {
return 1;
}
bool found = false;
for (auto it = range.first; it != range.second; ++it) {
if (it->second == breakpoint) {
breakpoints_.erase(it);
found = true;
break;
}
}
if (!found) {
return 1;
}
}
UnlockMutex(breakpoints_lock_);
if (!found) {
return 1;
}
// Find all functions that have the breakpoint set.
@@ -141,13 +136,12 @@ int Debugger::RemoveBreakpoint(Breakpoint* breakpoint) {
void Debugger::FindBreakpoints(
uint64_t address, std::vector<Breakpoint*>& out_breakpoints) {
out_breakpoints.clear();
std::lock_guard<std::mutex> guard(breakpoints_lock_);
LockMutex(breakpoints_lock_);
out_breakpoints.clear();
auto range = breakpoints_.equal_range(address);
if (range.first == range.second) {
UnlockMutex(breakpoints_lock_);
return;
}
@@ -155,42 +149,39 @@ void Debugger::FindBreakpoints(
Breakpoint* breakpoint = it->second;
out_breakpoints.push_back(breakpoint);
}
UnlockMutex(breakpoints_lock_);
}
void Debugger::OnThreadCreated(ThreadState* thread_state) {
LockMutex(threads_lock_);
std::lock_guard<std::mutex> guard(threads_lock_);
threads_[thread_state->thread_id()] = thread_state;
UnlockMutex(threads_lock_);
}
void Debugger::OnThreadDestroyed(ThreadState* thread_state) {
LockMutex(threads_lock_);
std::lock_guard<std::mutex> guard(threads_lock_);
auto it = threads_.find(thread_state->thread_id());
if (it != threads_.end()) {
threads_.erase(it);
}
UnlockMutex(threads_lock_);
}
void Debugger::OnFunctionDefined(FunctionInfo* symbol_info,
Function* function) {
// Man, I'd love not to take this lock.
std::vector<Breakpoint*> breakpoints;
LockMutex(breakpoints_lock_);
for (uint64_t address = symbol_info->address();
address <= symbol_info->end_address(); address += 4) {
auto range = breakpoints_.equal_range(address);
if (range.first == range.second) {
continue;
}
for (auto it = range.first; it != range.second; ++it) {
Breakpoint* breakpoint = it->second;
breakpoints.push_back(breakpoint);
{
std::lock_guard<std::mutex> guard(breakpoints_lock_);
for (uint64_t address = symbol_info->address();
address <= symbol_info->end_address(); address += 4) {
auto range = breakpoints_.equal_range(address);
if (range.first == range.second) {
continue;
}
for (auto it = range.first; it != range.second; ++it) {
Breakpoint* breakpoint = it->second;
breakpoints.push_back(breakpoint);
}
}
}
UnlockMutex(breakpoints_lock_);
if (breakpoints.size()) {
// Breakpoints to add!
@@ -210,4 +201,4 @@ void Debugger::OnBreakpointHit(
breakpoint_hit(e);
// Note that we stay suspended.
}
}

View File

@@ -10,9 +10,10 @@
#ifndef ALLOY_RUNTIME_DEBUGGER_H_
#define ALLOY_RUNTIME_DEBUGGER_H_
#include <alloy/core.h>
#include <map>
#include <mutex>
#include <alloy/core.h>
namespace alloy {
@@ -105,11 +106,11 @@ public:
private:
Runtime* runtime_;
Mutex* threads_lock_;
std::mutex threads_lock_;
typedef std::unordered_map<uint32_t, ThreadState*> ThreadMap;
ThreadMap threads_;
Mutex* breakpoints_lock_;
std::mutex breakpoints_lock_;
typedef std::multimap<uint64_t, Breakpoint*> BreakpointMultimap;
BreakpointMultimap breakpoints_;
};

View File

@@ -13,23 +13,19 @@ using namespace alloy;
using namespace alloy::runtime;
EntryTable::EntryTable() {
lock_ = AllocMutex(10000);
}
EntryTable::EntryTable() = default;
EntryTable::~EntryTable() {
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
EntryMap::iterator it = map_.begin();
for (; it != map_.end(); ++it) {
Entry* entry = it->second;
delete entry;
}
UnlockMutex(lock_);
FreeMutex(lock_);
}
Entry* EntryTable::Get(uint64_t address) {
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
EntryMap::const_iterator it = map_.find(address);
Entry* entry = it != map_.end() ? it->second : NULL;
if (entry) {
@@ -38,12 +34,11 @@ Entry* EntryTable::Get(uint64_t address) {
entry = NULL;
}
}
UnlockMutex(lock_);
return entry;
}
Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) {
LockMutex(lock_);
lock_.lock();
EntryMap::const_iterator it = map_.find(address);
Entry* entry = it != map_.end() ? it->second : NULL;
Entry::Status status;
@@ -52,10 +47,10 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) {
if (entry->status == Entry::STATUS_COMPILING) {
// Still compiling, so spin.
do {
UnlockMutex(lock_);
lock_.unlock();
// TODO(benvanik): sleep for less time?
Sleep(0);
LockMutex(lock_);
lock_.lock();
} while (entry->status == Entry::STATUS_COMPILING);
}
status = entry->status;
@@ -69,16 +64,15 @@ Entry::Status EntryTable::GetOrCreate(uint64_t address, Entry** out_entry) {
map_[address] = entry;
status = Entry::STATUS_NEW;
}
UnlockMutex(lock_);
lock_.unlock();
*out_entry = entry;
return status;
}
std::vector<Function*> EntryTable::FindWithAddress(uint64_t address) {
SCOPE_profile_cpu_f("alloy");
std::lock_guard<std::mutex> guard(lock_);
std::vector<Function*> fns;
LockMutex(lock_);
for (auto it = map_.begin(); it != map_.end(); ++it) {
Entry* entry = it->second;
if (address >= entry->address &&
@@ -88,6 +82,5 @@ std::vector<Function*> EntryTable::FindWithAddress(uint64_t address) {
}
}
}
UnlockMutex(lock_);
return fns;
}

View File

@@ -10,6 +10,8 @@
#ifndef ALLOY_RUNTIME_ENTRY_TABLE_H_
#define ALLOY_RUNTIME_ENTRY_TABLE_H_
#include <mutex>
#include <alloy/core.h>
@@ -46,7 +48,7 @@ public:
private:
// TODO(benvanik): replace with a better data structure.
Mutex* lock_;
std::mutex lock_;
typedef std::unordered_map<uint64_t, Entry*> EntryMap;
EntryMap map_;
};

View File

@@ -20,16 +20,12 @@ using namespace alloy::runtime;
Function::Function(FunctionInfo* symbol_info) :
address_(symbol_info->address()),
symbol_info_(symbol_info), debug_info_(0) {
// TODO(benvanik): create on demand?
lock_ = AllocMutex();
}
Function::~Function() {
FreeMutex(lock_);
}
Function::~Function() = default;
int Function::AddBreakpoint(Breakpoint* breakpoint) {
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
bool found = false;
for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) {
if (*it == breakpoint) {
@@ -40,12 +36,11 @@ int Function::AddBreakpoint(Breakpoint* breakpoint) {
breakpoints_.push_back(breakpoint);
AddBreakpointImpl(breakpoint);
}
UnlockMutex(lock_);
return found ? 1 : 0;
}
int Function::RemoveBreakpoint(Breakpoint* breakpoint) {
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
bool found = false;
for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) {
if (*it == breakpoint) {
@@ -55,12 +50,11 @@ int Function::RemoveBreakpoint(Breakpoint* breakpoint) {
break;
}
}
UnlockMutex(lock_);
return found ? 0 : 1;
}
Breakpoint* Function::FindBreakpoint(uint64_t address) {
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
Breakpoint* result = NULL;
for (auto it = breakpoints_.begin(); it != breakpoints_.end(); ++it) {
Breakpoint* breakpoint = *it;
@@ -69,7 +63,6 @@ Breakpoint* Function::FindBreakpoint(uint64_t address) {
break;
}
}
UnlockMutex(lock_);
return result;
}

View File

@@ -10,6 +10,9 @@
#ifndef ALLOY_RUNTIME_FUNCTION_H_
#define ALLOY_RUNTIME_FUNCTION_H_
#include <mutex>
#include <vector>
#include <alloy/core.h>
#include <alloy/runtime/debug_info.h>
@@ -46,12 +49,12 @@ protected:
uint64_t return_address) = 0;
protected:
uint64_t address_;
uint64_t address_;
FunctionInfo* symbol_info_;
DebugInfo* debug_info_;
DebugInfo* debug_info_;
// TODO(benvanik): move elsewhere? DebugData?
Mutex* lock_;
std::mutex lock_;
std::vector<Breakpoint*> breakpoints_;
};

View File

@@ -19,19 +19,15 @@ using namespace alloy::runtime;
Module::Module(Runtime* runtime) :
runtime_(runtime), memory_(runtime->memory()) {
lock_ = AllocMutex(10000);
}
runtime_(runtime), memory_(runtime->memory()) {}
Module::~Module() {
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
SymbolMap::iterator it = map_.begin();
for (; it != map_.end(); ++it) {
SymbolInfo* symbol_info = it->second;
delete symbol_info;
}
UnlockMutex(lock_);
FreeMutex(lock_);
}
bool Module::ContainsAddress(uint64_t address) {
@@ -39,7 +35,7 @@ bool Module::ContainsAddress(uint64_t address) {
}
SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) {
LockMutex(lock_);
lock_.lock();
SymbolMap::const_iterator it = map_.find(address);
SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL;
if (symbol_info) {
@@ -47,10 +43,10 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) {
// Some other thread is declaring the symbol - wait.
if (wait) {
do {
UnlockMutex(lock_);
lock_.unlock();
// TODO(benvanik): sleep for less time?
Sleep(0);
LockMutex(lock_);
lock_.lock();
} while (symbol_info->status() == SymbolInfo::STATUS_DECLARING);
} else {
// Immediate request, just return.
@@ -58,31 +54,31 @@ SymbolInfo* Module::LookupSymbol(uint64_t address, bool wait) {
}
}
}
UnlockMutex(lock_);
lock_.unlock();
return symbol_info;
}
SymbolInfo::Status Module::DeclareSymbol(
SymbolInfo::Type type, uint64_t address, SymbolInfo** out_symbol_info) {
*out_symbol_info = NULL;
LockMutex(lock_);
lock_.lock();
SymbolMap::const_iterator it = map_.find(address);
SymbolInfo* symbol_info = it != map_.end() ? it->second : NULL;
SymbolInfo::Status status;
if (symbol_info) {
// If we exist but are the wrong type, die.
if (symbol_info->type() != type) {
UnlockMutex(lock_);
lock_.unlock();
return SymbolInfo::STATUS_FAILED;
}
// If we aren't ready yet spin and wait.
if (symbol_info->status() == SymbolInfo::STATUS_DECLARING) {
// Still declaring, so spin.
do {
UnlockMutex(lock_);
lock_.unlock();
// TODO(benvanik): sleep for less time?
Sleep(0);
LockMutex(lock_);
lock_.lock();
} while (symbol_info->status() == SymbolInfo::STATUS_DECLARING);
}
status = symbol_info->status();
@@ -100,7 +96,7 @@ SymbolInfo::Status Module::DeclareSymbol(
list_.push_back(symbol_info);
status = SymbolInfo::STATUS_NEW;
}
UnlockMutex(lock_);
lock_.unlock();
*out_symbol_info = symbol_info;
// Get debug info from providers, if this is new.
@@ -130,7 +126,7 @@ SymbolInfo::Status Module::DeclareVariable(
}
SymbolInfo::Status Module::DefineSymbol(SymbolInfo* symbol_info) {
LockMutex(lock_);
lock_.lock();
SymbolInfo::Status status;
if (symbol_info->status() == SymbolInfo::STATUS_DECLARED) {
// Declared but undefined, so request caller define it.
@@ -139,16 +135,16 @@ SymbolInfo::Status Module::DefineSymbol(SymbolInfo* symbol_info) {
} else if (symbol_info->status() == SymbolInfo::STATUS_DEFINING) {
// Still defining, so spin.
do {
UnlockMutex(lock_);
lock_.unlock();
// TODO(benvanik): sleep for less time?
Sleep(0);
LockMutex(lock_);
lock_.lock();
} while (symbol_info->status() == SymbolInfo::STATUS_DEFINING);
status = symbol_info->status();
} else {
status = symbol_info->status();
}
UnlockMutex(lock_);
lock_.unlock();
return status;
}
@@ -162,8 +158,7 @@ SymbolInfo::Status Module::DefineVariable(VariableInfo* symbol_info) {
void Module::ForEachFunction(std::function<void (FunctionInfo*)> callback) {
SCOPE_profile_cpu_f("alloy");
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
for (auto it = list_.begin(); it != list_.end(); ++it) {
SymbolInfo* symbol_info = *it;
if (symbol_info->type() == SymbolInfo::TYPE_FUNCTION) {
@@ -171,14 +166,12 @@ void Module::ForEachFunction(std::function<void (FunctionInfo*)> callback) {
callback(info);
}
}
UnlockMutex(lock_);
}
void Module::ForEachFunction(size_t since, size_t& version,
std::function<void (FunctionInfo*)> callback) {
SCOPE_profile_cpu_f("alloy");
LockMutex(lock_);
std::lock_guard<std::mutex> guard(lock_);
size_t count = list_.size();
version = count;
for (size_t n = since; n < count; n++) {
@@ -188,7 +181,6 @@ void Module::ForEachFunction(size_t since, size_t& version,
callback(info);
}
}
UnlockMutex(lock_);
}
int Module::ReadMap(const char* file_name) {

View File

@@ -11,6 +11,9 @@
#define ALLOY_RUNTIME_MODULE_H_
#include <functional>
#include <mutex>
#include <unordered_map>
#include <vector>
#include <alloy/core.h>
#include <alloy/memory.h>
@@ -61,7 +64,7 @@ protected:
private:
// TODO(benvanik): replace with a better data structure.
Mutex* lock_;
std::mutex lock_;
typedef std::unordered_map<uint64_t, SymbolInfo*> SymbolMap;
SymbolMap map_;
typedef std::vector<SymbolInfo*> SymbolList;

View File

@@ -27,18 +27,17 @@ DEFINE_string(runtime_backend, "any",
Runtime::Runtime(Memory* memory) :
memory_(memory), debugger_(0), backend_(0), frontend_(0) {
tracing::Initialize();
modules_lock_ = AllocMutex(10000);
}
Runtime::~Runtime() {
LockMutex(modules_lock_);
for (ModuleList::iterator it = modules_.begin();
it != modules_.end(); ++it) {
Module* module = *it;
delete module;
{
std::lock_guard<std::mutex> guard(modules_lock_);
for (ModuleList::iterator it = modules_.begin();
it != modules_.end(); ++it) {
Module* module = *it;
delete module;
}
}
UnlockMutex(modules_lock_);
FreeMutex(modules_lock_);
delete frontend_;
delete backend_;
@@ -111,15 +110,14 @@ int Runtime::Initialize(Frontend* frontend, Backend* backend) {
}
int Runtime::AddModule(Module* module) {
LockMutex(modules_lock_);
std::lock_guard<std::mutex> guard(modules_lock_);
modules_.push_back(module);
UnlockMutex(modules_lock_);
return 0;
}
Module* Runtime::GetModule(const char* name) {
std::lock_guard<std::mutex> guard(modules_lock_);
Module* result = NULL;
LockMutex(modules_lock_);
for (ModuleList::iterator it = modules_.begin();
it != modules_.end(); ++it) {
Module* module = *it;
@@ -128,15 +126,12 @@ Module* Runtime::GetModule(const char* name) {
break;
}
}
UnlockMutex(modules_lock_);
return result;
}
Runtime::ModuleList Runtime::GetModules() {
ModuleList clone;
LockMutex(modules_lock_);
clone = modules_;
UnlockMutex(modules_lock_);
std::lock_guard<std::mutex> guard(modules_lock_);
ModuleList clone = modules_;
return clone;
}
@@ -188,18 +183,19 @@ int Runtime::LookupFunctionInfo(
// Find the module that contains the address.
Module* code_module = NULL;
LockMutex(modules_lock_);
// TODO(benvanik): sort by code address (if contiguous) so can bsearch.
// TODO(benvanik): cache last module low/high, as likely to be in there.
for (ModuleList::const_iterator it = modules_.begin();
it != modules_.end(); ++it) {
Module* module = *it;
if (module->ContainsAddress(address)) {
code_module = module;
break;
{
std::lock_guard<std::mutex> guard(modules_lock_);
// TODO(benvanik): sort by code address (if contiguous) so can bsearch.
// TODO(benvanik): cache last module low/high, as likely to be in there.
for (ModuleList::const_iterator it = modules_.begin();
it != modules_.end(); ++it) {
Module* module = *it;
if (module->ContainsAddress(address)) {
code_module = module;
break;
}
}
}
UnlockMutex(modules_lock_);
if (!code_module) {
// No module found that could contain the address.
return 1;

View File

@@ -10,6 +10,9 @@
#ifndef ALLOY_RUNTIME_RUNTIME_H_
#define ALLOY_RUNTIME_RUNTIME_H_
#include <mutex>
#include <vector>
#include <alloy/core.h>
#include <alloy/memory.h>
#include <alloy/backend/backend.h>
@@ -65,7 +68,7 @@ protected:
backend::Backend* backend_;
EntryTable entry_table_;
Mutex* modules_lock_;
std::mutex modules_lock_;
ModuleList modules_;
};