# Node ID c3977836244e4867c0222f03b2cb90a25a888f57 # Parent c00b5ba43967e7e48a28b7ddc48c9f4afaf2ab76 diff --git a/src/arch/x86/decoder.cc b/src/arch/x86/decoder.cc --- a/src/arch/x86/decoder.cc +++ b/src/arch/x86/decoder.cc @@ -460,10 +460,19 @@ Decoder::InstBytes Decoder::dummy; Decoder::InstCacheMap Decoder::instCacheMap; +std::mutex decodeMtx; StaticInstPtr Decoder::decode(ExtMachInst mach_inst, Addr addr) { + // Prevents race-conditions when using multiple EventQueues + // This is a temporary fix, not an optimal solution since it doesn't allow + // concurrent readers on instMap. Alternative solutions include: + // 1) Make instCacheMap non-static so that each core has it's own map + // 2) Use a multiple-reader/single-writer lock, e.g. from the Boost library + // 3) Use a read-copy-update hash table. See http://lwn.net/Articles/573431 + // 4) Use a concurrent hash table, like the one in Intel's TBB + std::lock_guard lock(decodeMtx); DecodeCache::InstMap::iterator iter = instMap->find(mach_inst); if (iter != instMap->end()) return iter->second; diff --git a/src/base/refcnt.hh b/src/base/refcnt.hh --- a/src/base/refcnt.hh +++ b/src/base/refcnt.hh @@ -31,6 +31,8 @@ #ifndef __BASE_REFCNT_HH__ #define __BASE_REFCNT_HH__ +#include + /** * @file base/refcnt.hh * @@ -49,7 +51,7 @@ // reference count a const pointer. This really is OK because // const is about logical constness of the object not really about // strictly disallowing an object to change. - mutable int count; + mutable std::atomic_int count; private: // Don't allow a default copy constructor or copy operator on diff --git a/src/base/trace.cc b/src/base/trace.cc --- a/src/base/trace.cc +++ b/src/base/trace.cc @@ -33,6 +33,7 @@ #include #include #include +#include #include "base/misc.hh" #include "base/output.hh" @@ -47,6 +48,12 @@ const string DefaultName("global"); bool enabled = false; +/* + * Mutex to prevent interleaved output between multiple threads. + * We use this to lock the print statements in both dprintf() and dump(). + */ +std::mutex dprintfMtx; + // // This variable holds the output stream for debug information. Other // than setting up/redirecting this stream, do *NOT* reference this @@ -94,6 +101,8 @@ fmt += format; + // lock to prevent interleaved output + std::lock_guard lock(dprintfMtx); ccprintf(os, fmt.c_str(), args); os.flush(); } @@ -121,6 +130,8 @@ const char *data = static_cast(d); int c, i, j; + // lock to prevent interleaved output + std::lock_guard lock(dprintfMtx); for (i = 0; i < len; i += 16) { ccprintf(os, fmt, args); ccprintf(os, "%08x ", i); diff --git a/src/sim/syscall_emul.cc b/src/sim/syscall_emul.cc --- a/src/sim/syscall_emul.cc +++ b/src/sim/syscall_emul.cc @@ -35,6 +35,7 @@ #include #include #include +#include #include "arch/utility.hh" #include "base/chunk_generator.hh" @@ -52,6 +53,9 @@ using namespace std; using namespace TheISA; +/* This is used to make system calls thread-safe */ +std::mutex syscallMutex; + void SyscallDesc::doSyscall(int callnum, LiveProcess *process, ThreadContext *tc) { @@ -69,7 +73,9 @@ arg[0], arg[1], arg[2], arg[3]); } + syscallMutex.lock(); SyscallReturn retval = (*funcPtr)(this, callnum, process, tc); + syscallMutex.unlock(); DPRINTFR(SyscallVerbose, "%d: %s: syscall %s returns %d\n", curTick(), tc->getCpuPtr()->name(), name, retval.encodedValue());