From: bmeurer@chromium.org Date: Tue, 30 Jul 2013 17:12:49 +0000 (+0000) Subject: Simplify implementation of Mutex. X-Git-Tag: upstream/4.7.83~13132 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=64bfd42a4c356881d9d315b6d85308f39221ed8c;p=platform%2Fupstream%2Fv8.git Simplify implementation of Mutex. Also moves Mutex to its own file mutex.{cc,h}. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/21087012 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@15964 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- diff --git a/src/assembler.cc b/src/assembler.cc index ae8a0b5..ab957be 100644 --- a/src/assembler.cc +++ b/src/assembler.cc @@ -891,7 +891,7 @@ void ExternalReference::SetUp() { double_constants.the_hole_nan = BitCast(kHoleNanInt64); double_constants.negative_infinity = -V8_INFINITY; - math_exp_data_mutex = OS::CreateMutex(); + math_exp_data_mutex = new Mutex; } @@ -899,7 +899,7 @@ void ExternalReference::InitializeMathExpData() { // Early return? if (math_exp_data_initialized) return; - math_exp_data_mutex->Lock(); + ScopedLock with(math_exp_data_mutex); if (!math_exp_data_initialized) { // If this is changed, generated code must be adapted too. const int kTableSizeBits = 11; @@ -935,7 +935,6 @@ void ExternalReference::InitializeMathExpData() { math_exp_data_initialized = true; } - math_exp_data_mutex->Unlock(); } diff --git a/src/d8-debug.cc b/src/d8-debug.cc index 9a72518..5499d20 100644 --- a/src/d8-debug.cc +++ b/src/d8-debug.cc @@ -248,7 +248,7 @@ void RemoteDebugger::ConnectionClosed() { void RemoteDebugger::AddEvent(RemoteDebuggerEvent* event) { - i::ScopedLock lock(event_access_); + i::ScopedLock lock(&event_access_); if (head_ == NULL) { ASSERT(tail_ == NULL); head_ = event; @@ -263,7 +263,7 @@ void RemoteDebugger::AddEvent(RemoteDebuggerEvent* event) { RemoteDebuggerEvent* RemoteDebugger::GetEvent() { - i::ScopedLock lock(event_access_); + i::ScopedLock lock(&event_access_); ASSERT(head_ != NULL); RemoteDebuggerEvent* result = head_; head_ = head_->next(); diff --git a/src/d8-debug.h b/src/d8-debug.h index 2386b6b..276cbd8 100644 --- a/src/d8-debug.h +++ b/src/d8-debug.h @@ -53,7 +53,6 @@ class RemoteDebugger { explicit RemoteDebugger(Isolate* isolate, int port) : isolate_(isolate), port_(port), - event_access_(i::OS::CreateMutex()), event_available_(i::OS::CreateSemaphore(0)), head_(NULL), tail_(NULL) {} void Run(); @@ -84,7 +83,7 @@ class RemoteDebugger { // Linked list of events from debugged V8 and from keyboard input. Access to // the list is guarded by a mutex and a semaphore signals new items in the // list. - i::Mutex* event_access_; + i::Mutex event_access_; i::Semaphore* event_available_; RemoteDebuggerEvent* head_; RemoteDebuggerEvent* tail_; diff --git a/src/d8.cc b/src/d8.cc index 1efe2ae..4cdafee 100644 --- a/src/d8.cc +++ b/src/d8.cc @@ -157,7 +157,7 @@ CounterMap* Shell::counter_map_; i::OS::MemoryMappedFile* Shell::counters_file_ = NULL; CounterCollection Shell::local_counters_; CounterCollection* Shell::counters_ = &local_counters_; -i::Mutex* Shell::context_mutex_(i::OS::CreateMutex()); +i::Mutex Shell::context_mutex_; Persistent Shell::utility_context_; #endif // V8_SHARED @@ -925,7 +925,7 @@ void Shell::InitializeDebugger(Isolate* isolate) { Local Shell::CreateEvaluationContext(Isolate* isolate) { #ifndef V8_SHARED // This needs to be a critical section since this is not thread-safe - i::ScopedLock lock(context_mutex_); + i::ScopedLock lock(&context_mutex_); #endif // V8_SHARED // Initialize the global objects Handle global_template = CreateGlobalTemplate(isolate); @@ -1011,7 +1011,6 @@ void Shell::OnExit() { "-------------+\n"); delete [] counters; } - delete context_mutex_; delete counters_file_; delete counter_map_; #endif // V8_SHARED diff --git a/src/d8.h b/src/d8.h index 4f04342..7e5e3d5 100644 --- a/src/d8.h +++ b/src/d8.h @@ -388,7 +388,7 @@ class Shell : public i::AllStatic { static CounterCollection local_counters_; static CounterCollection* counters_; static i::OS::MemoryMappedFile* counters_file_; - static i::Mutex* context_mutex_; + static i::Mutex context_mutex_; static Counter* GetCounter(const char* name, bool is_histogram); static void InstallUtilityScript(Isolate* isolate); diff --git a/src/debug-agent.cc b/src/debug-agent.cc index 811c00e..fc16bf9 100644 --- a/src/debug-agent.cc +++ b/src/debug-agent.cc @@ -106,7 +106,7 @@ static const char* kCreateSessionMessage = "Remote debugging session already active\r\n"; void DebuggerAgent::CreateSession(Socket* client) { - ScopedLock with(session_access_); + ScopedLock with(&session_access_); // If another session is already established terminate this one. if (session_ != NULL) { @@ -123,7 +123,7 @@ void DebuggerAgent::CreateSession(Socket* client) { void DebuggerAgent::CloseSession() { - ScopedLock with(session_access_); + ScopedLock with(&session_access_); // Terminate the session. if (session_ != NULL) { @@ -136,7 +136,7 @@ void DebuggerAgent::CloseSession() { void DebuggerAgent::DebuggerMessage(const v8::Debug::Message& message) { - ScopedLock with(session_access_); + ScopedLock with(&session_access_); // Forward the message handling to the session. if (session_ != NULL) { @@ -154,7 +154,7 @@ void DebuggerAgent::OnSessionClosed(DebuggerAgentSession* session) { } // Terminate the session. - ScopedLock with(session_access_); + ScopedLock with(&session_access_); ASSERT(session == session_); if (session == session_) { session_->Shutdown(); diff --git a/src/debug-agent.h b/src/debug-agent.h index 6115190..577239c 100644 --- a/src/debug-agent.h +++ b/src/debug-agent.h @@ -48,7 +48,7 @@ class DebuggerAgent: public Thread { isolate_(Isolate::Current()), name_(StrDup(name)), port_(port), server_(OS::CreateSocket()), terminate_(false), - session_access_(OS::CreateMutex()), session_(NULL), + session_(NULL), terminate_now_(OS::CreateSemaphore(0)), listening_(OS::CreateSemaphore(0)) { ASSERT(isolate_->debugger_agent_instance() == NULL); @@ -76,7 +76,7 @@ class DebuggerAgent: public Thread { int port_; // Port to use for the agent. Socket* server_; // Server socket for listen/accept. bool terminate_; // Termination flag. - Mutex* session_access_; // Mutex guarging access to session_. + Mutex session_access_; // Mutex guarging access to session_. DebuggerAgentSession* session_; // Current active session if any. Semaphore* terminate_now_; // Semaphore to signal termination. Semaphore* listening_; diff --git a/src/debug.cc b/src/debug.cc index a0b9884..80885da 100644 --- a/src/debug.cc +++ b/src/debug.cc @@ -2606,7 +2606,6 @@ Debugger::Debugger(Isolate* isolate) message_handler_(NULL), debugger_unload_pending_(false), host_dispatch_handler_(NULL), - dispatch_handler_access_(OS::CreateMutex()), debug_message_dispatch_handler_(NULL), message_dispatch_helper_thread_(NULL), host_dispatch_micros_(100 * 1000), @@ -2619,8 +2618,6 @@ Debugger::Debugger(Isolate* isolate) Debugger::~Debugger() { - delete dispatch_handler_access_; - dispatch_handler_access_ = 0; delete command_received_; command_received_ = 0; } @@ -3303,7 +3300,7 @@ void Debugger::SetHostDispatchHandler(v8::Debug::HostDispatchHandler handler, void Debugger::SetDebugMessageDispatchHandler( v8::Debug::DebugMessageDispatchHandler handler, bool provide_locker) { - ScopedLock with(dispatch_handler_access_); + ScopedLock with(&dispatch_handler_access_); debug_message_dispatch_handler_ = handler; if (provide_locker && message_dispatch_helper_thread_ == NULL) { @@ -3346,7 +3343,7 @@ void Debugger::ProcessCommand(Vector command, MessageDispatchHelperThread* dispatch_thread; { - ScopedLock with(dispatch_handler_access_); + ScopedLock with(&dispatch_handler_access_); dispatch_thread = message_dispatch_helper_thread_; } @@ -3466,7 +3463,7 @@ void Debugger::WaitForAgent() { void Debugger::CallMessageDispatchHandler() { v8::Debug::DebugMessageDispatchHandler handler; { - ScopedLock with(dispatch_handler_access_); + ScopedLock with(&dispatch_handler_access_); handler = Debugger::debug_message_dispatch_handler_; } if (handler != NULL) { @@ -3787,24 +3784,20 @@ void CommandMessageQueue::Expand() { LockingCommandMessageQueue::LockingCommandMessageQueue(Logger* logger, int size) - : logger_(logger), queue_(size) { - lock_ = OS::CreateMutex(); -} + : logger_(logger), queue_(size) {} -LockingCommandMessageQueue::~LockingCommandMessageQueue() { - delete lock_; -} +LockingCommandMessageQueue::~LockingCommandMessageQueue() {} -bool LockingCommandMessageQueue::IsEmpty() const { - ScopedLock sl(lock_); +bool LockingCommandMessageQueue::IsEmpty() { + ScopedLock sl(&lock_); return queue_.IsEmpty(); } CommandMessage LockingCommandMessageQueue::Get() { - ScopedLock sl(lock_); + ScopedLock sl(&lock_); CommandMessage result = queue_.Get(); logger_->DebugEvent("Get", result.text()); return result; @@ -3812,14 +3805,14 @@ CommandMessage LockingCommandMessageQueue::Get() { void LockingCommandMessageQueue::Put(const CommandMessage& message) { - ScopedLock sl(lock_); + ScopedLock sl(&lock_); queue_.Put(message); logger_->DebugEvent("Put", message.text()); } void LockingCommandMessageQueue::Clear() { - ScopedLock sl(lock_); + ScopedLock sl(&lock_); queue_.Clear(); } @@ -3827,19 +3820,17 @@ void LockingCommandMessageQueue::Clear() { MessageDispatchHelperThread::MessageDispatchHelperThread(Isolate* isolate) : Thread("v8:MsgDispHelpr"), isolate_(isolate), sem_(OS::CreateSemaphore(0)), - mutex_(OS::CreateMutex()), already_signalled_(false) { -} + already_signalled_(false) {} MessageDispatchHelperThread::~MessageDispatchHelperThread() { - delete mutex_; delete sem_; } void MessageDispatchHelperThread::Schedule() { { - ScopedLock lock(mutex_); + ScopedLock lock(&mutex_); if (already_signalled_) { return; } @@ -3853,7 +3844,7 @@ void MessageDispatchHelperThread::Run() { while (true) { sem_->Wait(); { - ScopedLock lock(mutex_); + ScopedLock lock(&mutex_); already_signalled_ = false; } { diff --git a/src/debug.h b/src/debug.h index 67debc7..e7b919e 100644 --- a/src/debug.h +++ b/src/debug.h @@ -763,14 +763,15 @@ class LockingCommandMessageQueue BASE_EMBEDDED { public: LockingCommandMessageQueue(Logger* logger, int size); ~LockingCommandMessageQueue(); - bool IsEmpty() const; + bool IsEmpty(); CommandMessage Get(); void Put(const CommandMessage& message); void Clear(); + private: Logger* logger_; CommandMessageQueue queue_; - Mutex* lock_; + Mutex lock_; DISALLOW_COPY_AND_ASSIGN(LockingCommandMessageQueue); }; @@ -929,7 +930,7 @@ class Debugger { v8::Debug::MessageHandler2 message_handler_; bool debugger_unload_pending_; // Was message handler cleared? v8::Debug::HostDispatchHandler host_dispatch_handler_; - Mutex* dispatch_handler_access_; // Mutex guarding dispatch handler. + Mutex dispatch_handler_access_; // Mutex guarding dispatch handler. v8::Debug::DebugMessageDispatchHandler debug_message_dispatch_handler_; MessageDispatchHelperThread* message_dispatch_helper_thread_; int host_dispatch_micros_; @@ -1056,7 +1057,7 @@ class MessageDispatchHelperThread: public Thread { Isolate* isolate_; Semaphore* const sem_; - Mutex* const mutex_; + Mutex mutex_; bool already_signalled_; DISALLOW_COPY_AND_ASSIGN(MessageDispatchHelperThread); diff --git a/src/heap.cc b/src/heap.cc index 692ec21..6a18fbb 100644 --- a/src/heap.cc +++ b/src/heap.cc @@ -6877,7 +6877,7 @@ bool Heap::SetUp() { store_buffer()->SetUp(); - if (FLAG_parallel_recompilation) relocation_mutex_ = OS::CreateMutex(); + if (FLAG_parallel_recompilation) relocation_mutex_ = new Mutex; #ifdef DEBUG relocation_mutex_locked_by_optimizer_thread_ = false; #endif // DEBUG diff --git a/src/isolate.cc b/src/isolate.cc index 61f1e2d..f1af6d3 100644 --- a/src/isolate.cc +++ b/src/isolate.cc @@ -343,7 +343,7 @@ Thread::LocalStorageKey Isolate::per_isolate_thread_data_key_; #ifdef DEBUG Thread::LocalStorageKey PerThreadAssertScopeBase::thread_local_key; #endif // DEBUG -Mutex* Isolate::process_wide_mutex_ = OS::CreateMutex(); +Mutex Isolate::process_wide_mutex_; Isolate::ThreadDataTable* Isolate::thread_data_table_ = NULL; Atomic32 Isolate::isolate_counter_ = 0; @@ -352,7 +352,7 @@ Isolate::PerIsolateThreadData* Isolate::AllocatePerIsolateThreadData( ASSERT(!thread_id.Equals(ThreadId::Invalid())); PerIsolateThreadData* per_thread = new PerIsolateThreadData(this, thread_id); { - ScopedLock lock(process_wide_mutex_); + ScopedLock lock(&process_wide_mutex_); ASSERT(thread_data_table_->Lookup(this, thread_id) == NULL); thread_data_table_->Insert(per_thread); ASSERT(thread_data_table_->Lookup(this, thread_id) == per_thread); @@ -366,11 +366,11 @@ Isolate::PerIsolateThreadData* ThreadId thread_id = ThreadId::Current(); PerIsolateThreadData* per_thread = NULL; { - ScopedLock lock(process_wide_mutex_); + ScopedLock lock(&process_wide_mutex_); per_thread = thread_data_table_->Lookup(this, thread_id); - if (per_thread == NULL) { - per_thread = AllocatePerIsolateThreadData(thread_id); - } + } + if (per_thread == NULL) { + per_thread = AllocatePerIsolateThreadData(thread_id); } return per_thread; } @@ -386,7 +386,7 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread( ThreadId thread_id) { PerIsolateThreadData* per_thread = NULL; { - ScopedLock lock(process_wide_mutex_); + ScopedLock lock(&process_wide_mutex_); per_thread = thread_data_table_->Lookup(this, thread_id); } return per_thread; @@ -394,7 +394,7 @@ Isolate::PerIsolateThreadData* Isolate::FindPerThreadDataForThread( void Isolate::EnsureDefaultIsolate() { - ScopedLock lock(process_wide_mutex_); + ScopedLock lock(&process_wide_mutex_); if (default_isolate_ == NULL) { isolate_key_ = Thread::CreateThreadLocalKey(); thread_id_key_ = Thread::CreateThreadLocalKey(); @@ -1749,10 +1749,8 @@ Isolate::Isolate() counters_(NULL), code_range_(NULL), // Must be initialized early to allow v8::SetResourceConstraints calls. - break_access_(OS::CreateMutex()), debugger_initialized_(false), // Must be initialized early to allow v8::Debug calls. - debugger_access_(OS::CreateMutex()), logger_(NULL), stats_table_(NULL), stub_cache_(NULL), @@ -1853,7 +1851,7 @@ void Isolate::TearDown() { Deinit(); - { ScopedLock lock(process_wide_mutex_); + { ScopedLock lock(&process_wide_mutex_); thread_data_table_->RemoveAllThreads(this); } @@ -2024,10 +2022,6 @@ Isolate::~Isolate() { delete handle_scope_implementer_; handle_scope_implementer_ = NULL; - delete break_access_; - break_access_ = NULL; - delete debugger_access_; - debugger_access_ = NULL; delete compilation_cache_; compilation_cache_ = NULL; @@ -2127,7 +2121,7 @@ void Isolate::InitializeLoggingAndCounters() { void Isolate::InitializeDebugger() { #ifdef ENABLE_DEBUGGER_SUPPORT - ScopedLock lock(debugger_access_); + ScopedLock lock(&debugger_access_); if (NoBarrier_Load(&debugger_initialized_)) return; InitializeLoggingAndCounters(); debug_ = new Debug(this); diff --git a/src/isolate.h b/src/isolate.h index c008317..009ff78 100644 --- a/src/isolate.h +++ b/src/isolate.h @@ -544,10 +544,10 @@ class Isolate { static void EnterDefaultIsolate(); // Mutex for serializing access to break control structures. - Mutex* break_access() { return break_access_; } + Mutex* break_access() { return &break_access_; } // Mutex for serializing access to debugger. - Mutex* debugger_access() { return debugger_access_; } + Mutex* debugger_access() { return &debugger_access_; } Address get_address_from_id(AddressId id); @@ -1200,7 +1200,7 @@ class Isolate { // This mutex protects highest_thread_id_, thread_data_table_ and // default_isolate_. - static Mutex* process_wide_mutex_; + static Mutex process_wide_mutex_; static Thread::LocalStorageKey per_isolate_thread_data_key_; static Thread::LocalStorageKey isolate_key_; @@ -1268,9 +1268,9 @@ class Isolate { CompilationCache* compilation_cache_; Counters* counters_; CodeRange* code_range_; - Mutex* break_access_; + Mutex break_access_; Atomic32 debugger_initialized_; - Mutex* debugger_access_; + Mutex debugger_access_; Logger* logger_; StackGuard stack_guard_; StatsTable* stats_table_; @@ -1462,11 +1462,11 @@ class ExecutionAccess BASE_EMBEDDED { } ~ExecutionAccess() { Unlock(isolate_); } - static void Lock(Isolate* isolate) { isolate->break_access_->Lock(); } - static void Unlock(Isolate* isolate) { isolate->break_access_->Unlock(); } + static void Lock(Isolate* isolate) { isolate->break_access()->Lock(); } + static void Unlock(Isolate* isolate) { isolate->break_access()->Unlock(); } static bool TryLock(Isolate* isolate) { - return isolate->break_access_->TryLock(); + return isolate->break_access()->TryLock(); } private: diff --git a/src/log-utils.cc b/src/log-utils.cc index 6bba882..0a94ca9 100644 --- a/src/log-utils.cc +++ b/src/log-utils.cc @@ -48,7 +48,7 @@ Log::Log(Logger* logger) void Log::Initialize(const char* log_file_name) { - mutex_ = OS::CreateMutex(); + mutex_ = new Mutex; message_buffer_ = NewArray(kMessageBufferSize); // --log-all enables all the log flags. diff --git a/src/mutex.cc b/src/mutex.cc new file mode 100644 index 0000000..e02ace5 --- /dev/null +++ b/src/mutex.cc @@ -0,0 +1,110 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#include "mutex.h" + +#include + +#include "checks.h" + +namespace v8 { +namespace internal { + +#if V8_OS_UNIX + +Mutex::Mutex() { + pthread_mutexattr_t attr; + int result = pthread_mutexattr_init(&attr); + ASSERT_EQ(0, result); + result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + ASSERT_EQ(0, result); + result = pthread_mutex_init(&mutex_, &attr); + ASSERT_EQ(0, result); + result = pthread_mutexattr_destroy(&attr); + ASSERT_EQ(0, result); + USE(result); +} + + +Mutex::~Mutex() { + pthread_mutex_destroy(&mutex_); +} + + +void Mutex::Lock() { + int result = pthread_mutex_lock(&mutex_); + ASSERT_EQ(0, result); + USE(result); +} + + +void Mutex::Unlock() { + int result = pthread_mutex_unlock(&mutex_); + ASSERT_EQ(0, result); + USE(result); +} + + +bool Mutex::TryLock() { + int result = pthread_mutex_trylock(&mutex_); + // Return false if the lock is busy and locking failed. + if (result == EBUSY) { + return false; + } + ASSERT_EQ(0, result); + return true; +} + +#elif V8_OS_WIN32 + +Mutex::Mutex() { + InitializeCriticalSection(&cs_); +} + + +Mutex::~Mutex() { + DeleteCriticalSection(&cs_); +} + + +void Mutex::Lock() { + EnterCriticalSection(&cs_); +} + + +void Mutex::Unlock() { + LeaveCriticalSection(&cs_); +} + + +bool Mutex::TryLock() { + return TryEnterCriticalSection(&cs_); +} + +#endif // V8_OS_WIN32 + +} } // namespace v8::internal diff --git a/src/mutex.h b/src/mutex.h new file mode 100644 index 0000000..94a202e --- /dev/null +++ b/src/mutex.h @@ -0,0 +1,130 @@ +// Copyright 2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +#ifndef V8_MUTEX_H_ +#define V8_MUTEX_H_ + +#include "globals.h" + +#if V8_OS_UNIX +#include // NOLINT +#elif V8_OS_WIN32 +#include "win32-headers.h" +#endif + +#include "checks.h" +#include "lazy-instance.h" + +namespace v8 { +namespace internal { + +// ---------------------------------------------------------------------------- +// Mutex +// +// Mutexes are used for serializing access to non-reentrant sections of code. +// The implementations of mutex should allow for nested/recursive locking. +// +class Mutex { + public: + Mutex(); + ~Mutex(); + + // Locks the given mutex. If the mutex is currently unlocked, it becomes + // locked and owned by the calling thread. If the mutex is already locked + // by another thread, suspends the calling thread until the mutex is + // unlocked. + void Lock(); + + // Unlocks the given mutex. The mutex is assumed to be locked and owned + // by the calling thread on entrance. + void Unlock(); + + // Tries to lock the given mutex. Returns true if the mutex was locked + // successfully. + bool TryLock(); + + private: +#if V8_OS_UNIX + pthread_mutex_t mutex_; +#elif V8_OS_WIN32 + CRITICAL_SECTION cs_; +#endif + + DISALLOW_COPY_AND_ASSIGN(Mutex); +}; + + +// ---------------------------------------------------------------------------- +// LazyMutex +// +// POD Mutex initialized lazily (i.e. the first time Pointer() is called). +// Usage: +// static LazyMutex my_mutex = LAZY_MUTEX_INITIALIZER; +// +// void my_function() { +// ScopedLock my_lock(&my_mutex); +// // Do something. +// } +// +typedef LazyDynamicInstance, + ThreadSafeInitOnceTrait>::type LazyMutex; + +#define LAZY_MUTEX_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER + + +// ---------------------------------------------------------------------------- +// ScopedLock +// +// Stack-allocated ScopedLocks provide block-scoped locking and +// unlocking of a mutex. +// +class ScopedLock { + public: + explicit ScopedLock(Mutex* mutex): mutex_(mutex) { + ASSERT(mutex_ != NULL); + mutex_->Lock(); + } + + explicit ScopedLock(LazyMutex* lazy_mutex) : mutex_(lazy_mutex->Pointer()) { + ASSERT(mutex_ != NULL); + mutex_->Lock(); + } + + ~ScopedLock() { + mutex_->Unlock(); + } + + private: + Mutex* mutex_; + + DISALLOW_COPY_AND_ASSIGN(ScopedLock); +}; + +} } // namespace v8::internal + +#endif // V8_MUTEX_H_ diff --git a/src/optimizing-compiler-thread.cc b/src/optimizing-compiler-thread.cc index 21ef237..39fc191 100644 --- a/src/optimizing-compiler-thread.cc +++ b/src/optimizing-compiler-thread.cc @@ -39,7 +39,7 @@ namespace internal { void OptimizingCompilerThread::Run() { #ifdef DEBUG - { ScopedLock lock(thread_id_mutex_); + { ScopedLock lock(&thread_id_mutex_); thread_id_ = ThreadId::Current().ToInteger(); } #endif @@ -93,7 +93,7 @@ void OptimizingCompilerThread::CompileNext() { // The function may have already been optimized by OSR. Simply continue. // Use a mutex to make sure that functions marked for install // are always also queued. - ScopedLock mark_and_queue(install_mutex_); + ScopedLock mark_and_queue(&install_mutex_); { Heap::RelocationLock relocation_lock(isolate_->heap()); AllowHandleDereference ahd; optimizing_compiler->info()->closure()->MarkForInstallingRecompiledCode(); @@ -141,7 +141,7 @@ void OptimizingCompilerThread::InstallOptimizedFunctions() { OptimizingCompiler* compiler; while (true) { { // Memory barrier to ensure marked functions are queued. - ScopedLock marked_and_queued(install_mutex_); + ScopedLock marked_and_queued(&install_mutex_); if (!output_queue_.Dequeue(&compiler)) return; } Compiler::InstallOptimizedCode(compiler); @@ -163,7 +163,7 @@ void OptimizingCompilerThread::QueueForOptimization( #ifdef DEBUG bool OptimizingCompilerThread::IsOptimizerThread() { if (!FLAG_parallel_recompilation) return false; - ScopedLock lock(thread_id_mutex_); + ScopedLock lock(&thread_id_mutex_); return ThreadId::Current().ToInteger() == thread_id_; } #endif diff --git a/src/optimizing-compiler-thread.h b/src/optimizing-compiler-thread.h index 275ceb4..336522f 100644 --- a/src/optimizing-compiler-thread.h +++ b/src/optimizing-compiler-thread.h @@ -46,12 +46,10 @@ class OptimizingCompilerThread : public Thread { Thread("OptimizingCompilerThread"), #ifdef DEBUG thread_id_(0), - thread_id_mutex_(OS::CreateMutex()), #endif isolate_(isolate), stop_semaphore_(OS::CreateSemaphore(0)), input_queue_semaphore_(OS::CreateSemaphore(0)), - install_mutex_(OS::CreateMutex()), time_spent_compiling_(0), time_spent_total_(0) { NoBarrier_Store(&stop_thread_, static_cast(false)); @@ -83,18 +81,14 @@ class OptimizingCompilerThread : public Thread { #endif ~OptimizingCompilerThread() { - delete install_mutex_; delete input_queue_semaphore_; delete stop_semaphore_; -#ifdef DEBUG - delete thread_id_mutex_; -#endif } private: #ifdef DEBUG int thread_id_; - Mutex* thread_id_mutex_; + Mutex thread_id_mutex_; #endif Isolate* isolate_; @@ -102,7 +96,7 @@ class OptimizingCompilerThread : public Thread { Semaphore* input_queue_semaphore_; UnboundQueue input_queue_; UnboundQueue output_queue_; - Mutex* install_mutex_; + Mutex install_mutex_; volatile AtomicWord stop_thread_; volatile Atomic32 queue_length_; int64_t time_spent_compiling_; diff --git a/src/platform-cygwin.cc b/src/platform-cygwin.cc index 4c7b017..f6412ae 100644 --- a/src/platform-cygwin.cc +++ b/src/platform-cygwin.cc @@ -471,7 +471,7 @@ void OS::SetUp() { // call this setup code within the same millisecond. uint64_t seed = static_cast(TimeCurrentMillis()); srandom(static_cast(seed)); - limit_mutex = CreateMutex(); + limit_mutex = new Mutex; } diff --git a/src/platform-freebsd.cc b/src/platform-freebsd.cc index e0917fa..5da6eca 100644 --- a/src/platform-freebsd.cc +++ b/src/platform-freebsd.cc @@ -436,7 +436,7 @@ void OS::SetUp() { // call this setup code within the same millisecond. uint64_t seed = static_cast(TimeCurrentMillis()); srandom(static_cast(seed)); - limit_mutex = CreateMutex(); + limit_mutex = new Mutex; } diff --git a/src/platform-linux.cc b/src/platform-linux.cc index 5c252bb..800c20a 100644 --- a/src/platform-linux.cc +++ b/src/platform-linux.cc @@ -757,7 +757,7 @@ void OS::SetUp() { // Seed the random number generator. We preserve microsecond resolution. uint64_t seed = Ticks() ^ (getpid() << 16); srandom(static_cast(seed)); - limit_mutex = CreateMutex(); + limit_mutex = new Mutex; } diff --git a/src/platform-macos.cc b/src/platform-macos.cc index 6135cd1..b2d92d5 100644 --- a/src/platform-macos.cc +++ b/src/platform-macos.cc @@ -443,7 +443,7 @@ void OS::SetUp() { // Seed the random number generator. We preserve microsecond resolution. uint64_t seed = Ticks() ^ (getpid() << 16); srandom(static_cast(seed)); - limit_mutex = CreateMutex(); + limit_mutex = new Mutex; } diff --git a/src/platform-nullos.cc b/src/platform-nullos.cc index dd5a3dd..eadb300 100644 --- a/src/platform-nullos.cc +++ b/src/platform-nullos.cc @@ -477,37 +477,6 @@ void Thread::YieldCPU() { } -class NullMutex : public Mutex { - public: - NullMutex() : data_(NULL) { - UNIMPLEMENTED(); - } - - virtual ~NullMutex() { - UNIMPLEMENTED(); - } - - virtual int Lock() { - UNIMPLEMENTED(); - return 0; - } - - virtual int Unlock() { - UNIMPLEMENTED(); - return 0; - } - - private: - void* data_; -}; - - -Mutex* OS::CreateMutex() { - UNIMPLEMENTED(); - return new NullMutex(); -} - - class NullSemaphore : public Semaphore { public: explicit NullSemaphore(int count) : data_(NULL) { diff --git a/src/platform-openbsd.cc b/src/platform-openbsd.cc index e591601..4771671 100644 --- a/src/platform-openbsd.cc +++ b/src/platform-openbsd.cc @@ -502,7 +502,7 @@ void OS::SetUp() { // Seed the random number generator. We preserve microsecond resolution. uint64_t seed = Ticks() ^ (getpid() << 16); srandom(static_cast(seed)); - limit_mutex = CreateMutex(); + limit_mutex = new Mutex; } diff --git a/src/platform-posix.cc b/src/platform-posix.cc index 13b819b..31fc7a6 100644 --- a/src/platform-posix.cc +++ b/src/platform-posix.cc @@ -756,48 +756,6 @@ void Thread::SetThreadLocal(LocalStorageKey key, void* value) { } -class POSIXMutex : public Mutex { - public: - POSIXMutex() { - pthread_mutexattr_t attr; - memset(&attr, 0, sizeof(attr)); - int result = pthread_mutexattr_init(&attr); - ASSERT(result == 0); - result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - ASSERT(result == 0); - result = pthread_mutex_init(&mutex_, &attr); - ASSERT(result == 0); - result = pthread_mutexattr_destroy(&attr); - ASSERT(result == 0); - USE(result); - } - - virtual ~POSIXMutex() { pthread_mutex_destroy(&mutex_); } - - virtual int Lock() { return pthread_mutex_lock(&mutex_); } - - virtual int Unlock() { return pthread_mutex_unlock(&mutex_); } - - virtual bool TryLock() { - int result = pthread_mutex_trylock(&mutex_); - // Return false if the lock is busy and locking failed. - if (result == EBUSY) { - return false; - } - ASSERT(result == 0); // Verify no other errors. - return true; - } - - private: - pthread_mutex_t mutex_; // Pthread mutex for POSIX platforms. -}; - - -Mutex* OS::CreateMutex() { - return new POSIXMutex(); -} - - // ---------------------------------------------------------------------------- // POSIX socket support. // diff --git a/src/platform-solaris.cc b/src/platform-solaris.cc index b1d88af..654d98b 100644 --- a/src/platform-solaris.cc +++ b/src/platform-solaris.cc @@ -479,7 +479,7 @@ void OS::SetUp() { // call this setup code within the same millisecond. uint64_t seed = static_cast(TimeCurrentMillis()); srandom(static_cast(seed)); - limit_mutex = CreateMutex(); + limit_mutex = new Mutex; } diff --git a/src/platform-win32.cc b/src/platform-win32.cc index 292c24a..c0f049c 100644 --- a/src/platform-win32.cc +++ b/src/platform-win32.cc @@ -1705,46 +1705,6 @@ void Thread::YieldCPU() { // ---------------------------------------------------------------------------- -// Win32 mutex support. -// -// On Win32 mutexes are implemented using CRITICAL_SECTION objects. These are -// faster than Win32 Mutex objects because they are implemented using user mode -// atomic instructions. Therefore we only do ring transitions if there is lock -// contention. - -class Win32Mutex : public Mutex { - public: - Win32Mutex() { InitializeCriticalSection(&cs_); } - - virtual ~Win32Mutex() { DeleteCriticalSection(&cs_); } - - virtual int Lock() { - EnterCriticalSection(&cs_); - return 0; - } - - virtual int Unlock() { - LeaveCriticalSection(&cs_); - return 0; - } - - - virtual bool TryLock() { - // Returns non-zero if critical section is entered successfully entered. - return TryEnterCriticalSection(&cs_); - } - - private: - CRITICAL_SECTION cs_; // Critical section used for mutex -}; - - -Mutex* OS::CreateMutex() { - return new Win32Mutex(); -} - - -// ---------------------------------------------------------------------------- // Win32 semaphore support. // // On Win32 semaphores are implemented using Win32 Semaphore objects. The @@ -1987,7 +1947,7 @@ void OS::SetUp() { // call this setup code within the same millisecond. uint64_t seed = static_cast(TimeCurrentMillis()); srand(static_cast(seed)); - limit_mutex = CreateMutex(); + limit_mutex = new Mutex; } diff --git a/src/platform.h b/src/platform.h index 8b27c19..51d5698 100644 --- a/src/platform.h +++ b/src/platform.h @@ -100,7 +100,7 @@ int random(); #endif // WIN32 -#include "lazy-instance.h" +#include "mutex.h" #include "utils.h" #include "v8globals.h" @@ -309,10 +309,6 @@ class OS { static int StackWalk(Vector frames); - // Factory method for creating platform dependent Mutex. - // Please use delete to reclaim the storage for the returned Mutex. - static Mutex* CreateMutex(); - // Factory method for creating platform dependent Semaphore. // Please use delete to reclaim the storage for the returned Semaphore. static Semaphore* CreateSemaphore(int count); @@ -716,72 +712,6 @@ class Thread { // ---------------------------------------------------------------------------- -// Mutex -// -// Mutexes are used for serializing access to non-reentrant sections of code. -// The implementations of mutex should allow for nested/recursive locking. - -class Mutex { - public: - virtual ~Mutex() {} - - // Locks the given mutex. If the mutex is currently unlocked, it becomes - // locked and owned by the calling thread, and immediately. If the mutex - // is already locked by another thread, suspends the calling thread until - // the mutex is unlocked. - virtual int Lock() = 0; - - // Unlocks the given mutex. The mutex is assumed to be locked and owned by - // the calling thread on entrance. - virtual int Unlock() = 0; - - // Tries to lock the given mutex. Returns whether the mutex was - // successfully locked. - virtual bool TryLock() = 0; -}; - -struct CreateMutexTrait { - static Mutex* Create() { - return OS::CreateMutex(); - } -}; - -// POD Mutex initialized lazily (i.e. the first time Pointer() is called). -// Usage: -// static LazyMutex my_mutex = LAZY_MUTEX_INITIALIZER; -// -// void my_function() { -// ScopedLock my_lock(my_mutex.Pointer()); -// // Do something. -// } -// -typedef LazyDynamicInstance< - Mutex, CreateMutexTrait, ThreadSafeInitOnceTrait>::type LazyMutex; - -#define LAZY_MUTEX_INITIALIZER LAZY_DYNAMIC_INSTANCE_INITIALIZER - -// ---------------------------------------------------------------------------- -// ScopedLock -// -// Stack-allocated ScopedLocks provide block-scoped locking and -// unlocking of a mutex. -class ScopedLock { - public: - explicit ScopedLock(Mutex* mutex): mutex_(mutex) { - ASSERT(mutex_ != NULL); - mutex_->Lock(); - } - ~ScopedLock() { - mutex_->Unlock(); - } - - private: - Mutex* mutex_; - DISALLOW_COPY_AND_ASSIGN(ScopedLock); -}; - - -// ---------------------------------------------------------------------------- // Socket // diff --git a/src/sampler.cc b/src/sampler.cc index d72ed1a..db7a54e 100644 --- a/src/sampler.cc +++ b/src/sampler.cc @@ -415,7 +415,7 @@ class SamplerThread : public Thread { : Thread(Thread::Options("SamplerThread", kSamplerThreadStackSize)), interval_(interval) {} - static void SetUp() { if (!mutex_) mutex_ = OS::CreateMutex(); } + static void SetUp() { if (!mutex_) mutex_ = new Mutex; } static void TearDown() { delete mutex_; } static void AddActiveSampler(Sampler* sampler) { diff --git a/src/spaces.cc b/src/spaces.cc index 5935c4a..539b77e 100644 --- a/src/spaces.cc +++ b/src/spaces.cc @@ -2043,7 +2043,7 @@ intptr_t FreeListCategory::Concatenate(FreeListCategory* category) { // This is safe (not going to deadlock) since Concatenate operations // are never performed on the same free lists at the same time in // reverse order. - ScopedLock lock_target(mutex_); + ScopedLock lock_target(mutex()); ScopedLock lock_source(category->mutex()); free_bytes = category->available(); if (end_ == NULL) { diff --git a/src/spaces.h b/src/spaces.h index b47452e..165a226 100644 --- a/src/spaces.h +++ b/src/spaces.h @@ -1444,12 +1444,9 @@ class FreeListCategory { FreeListCategory() : top_(NULL), end_(NULL), - mutex_(OS::CreateMutex()), available_(0) {} - ~FreeListCategory() { - delete mutex_; - } + ~FreeListCategory() {} intptr_t Concatenate(FreeListCategory* category); @@ -1476,7 +1473,7 @@ class FreeListCategory { int available() const { return available_; } void set_available(int available) { available_ = available; } - Mutex* mutex() { return mutex_; } + Mutex* mutex() { return &mutex_; } #ifdef DEBUG intptr_t SumFreeList(); @@ -1486,7 +1483,7 @@ class FreeListCategory { private: FreeListNode* top_; FreeListNode* end_; - Mutex* mutex_; + Mutex mutex_; // Total available bytes in all blocks of this free list category. int available_; diff --git a/src/v8threads.cc b/src/v8threads.cc index 2df187a..c1f20b1 100644 --- a/src/v8threads.cc +++ b/src/v8threads.cc @@ -214,7 +214,7 @@ bool ThreadManager::RestoreThread() { void ThreadManager::Lock() { - mutex_->Lock(); + mutex_.Lock(); mutex_owner_ = ThreadId::Current(); ASSERT(IsLockedByCurrentThread()); } @@ -222,7 +222,7 @@ void ThreadManager::Lock() { void ThreadManager::Unlock() { mutex_owner_ = ThreadId::Invalid(); - mutex_->Unlock(); + mutex_.Unlock(); } @@ -303,8 +303,7 @@ ThreadState* ThreadState::Next() { // be distinguished from not having a thread id at all (since NULL is // defined as 0.) ThreadManager::ThreadManager() - : mutex_(OS::CreateMutex()), - mutex_owner_(ThreadId::Invalid()), + : mutex_owner_(ThreadId::Invalid()), lazily_archived_thread_(ThreadId::Invalid()), lazily_archived_thread_state_(NULL), free_anchor_(NULL), @@ -315,7 +314,6 @@ ThreadManager::ThreadManager() ThreadManager::~ThreadManager() { - delete mutex_; DeleteThreadStateList(free_anchor_); DeleteThreadStateList(in_use_anchor_); } diff --git a/src/v8threads.h b/src/v8threads.h index 8dce860..b8ed817 100644 --- a/src/v8threads.h +++ b/src/v8threads.h @@ -119,7 +119,7 @@ class ThreadManager { void EagerlyArchiveThread(); - Mutex* mutex_; + Mutex mutex_; ThreadId mutex_owner_; ThreadId lazily_archived_thread_; ThreadState* lazily_archived_thread_state_; diff --git a/src/win32-headers.h b/src/win32-headers.h index 2b5d7d7..bf568b3 100644 --- a/src/win32-headers.h +++ b/src/win32-headers.h @@ -94,5 +94,4 @@ #undef ANY #undef IGNORE #undef GetObject -#undef CreateMutex #undef CreateSemaphore diff --git a/test/cctest/cctest.gyp b/test/cctest/cctest.gyp index 9df5c7b..1cdf9f4 100644 --- a/test/cctest/cctest.gyp +++ b/test/cctest/cctest.gyp @@ -79,10 +79,10 @@ 'test-heap-profiler.cc', 'test-list.cc', 'test-liveedit.cc', - 'test-lock.cc', 'test-lockers.cc', 'test-log.cc', 'test-mark-compact.cc', + 'test-mutex.cc', 'test-object-observe.cc', 'test-parsing.cc', 'test-platform.cc', @@ -91,6 +91,7 @@ 'test-random.cc', 'test-regexp.cc', 'test-reloc-info.cc', + 'test-semaphore.cc', 'test-serialize.cc', 'test-sockets.cc', 'test-spaces.cc', diff --git a/test/cctest/test-debug.cc b/test/cctest/test-debug.cc index 484eb8e..90453f7 100644 --- a/test/cctest/test-debug.cc +++ b/test/cctest/test-debug.cc @@ -4714,7 +4714,7 @@ class ThreadBarrier { ThreadBarrier::ThreadBarrier(int num_threads) : num_threads_(num_threads), num_blocked_(0) { - lock_ = OS::CreateMutex(); + lock_ = new v8::internal::Mutex; sem_ = OS::CreateSemaphore(0); invalid_ = false; // A barrier may only be used once. Then it is invalid. } diff --git a/test/cctest/test-mutex.cc b/test/cctest/test-mutex.cc new file mode 100644 index 0000000..935bacc --- /dev/null +++ b/test/cctest/test-mutex.cc @@ -0,0 +1,70 @@ +// Copyright 2006-2013 the V8 project authors. All rights reserved. +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions are +// met: +// +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above +// copyright notice, this list of conditions and the following +// disclaimer in the documentation and/or other materials provided +// with the distribution. +// * Neither the name of Google Inc. nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Tests of the Mutex class from mutex.h + +#include "v8.h" + +#include "mutex.h" +#include "cctest.h" + + +using namespace ::v8::internal; + + +TEST(Simple) { + Mutex mutex; + mutex.Lock(); + mutex.Unlock(); +} + + +TEST(Recursive) { + Mutex mutex; + mutex.Lock(); + mutex.Lock(); + mutex.Unlock(); + mutex.Unlock(); +} + + +TEST(SimpleScopedLock) { + Mutex mutex; + { + ScopedLock fst(&mutex); + } + { + ScopedLock snd(&mutex); + } +} + + +TEST(RecursiveScopedLock) { + Mutex mutex; + ScopedLock fst(&mutex); + ScopedLock snd(&mutex); +} diff --git a/test/cctest/test-platform-linux.cc b/test/cctest/test-platform-linux.cc index 6bb2902..5945241 100644 --- a/test/cctest/test-platform-linux.cc +++ b/test/cctest/test-platform-linux.cc @@ -52,18 +52,18 @@ static void LoopIncrement(Mutex* mutex, int rem) { int count = 0; int last_count = -1; do { - CHECK_EQ(0, mutex->Lock()); + mutex->Lock(); count = busy_lock_counter; - CHECK_EQ(0, mutex->Unlock()); + mutex->Unlock(); yield(); } while (count % 2 == rem && count < kLockCounterLimit); if (count >= kLockCounterLimit) break; - CHECK_EQ(0, mutex->Lock()); + mutex->Lock(); CHECK_EQ(count, busy_lock_counter); CHECK(last_count == -1 || count == last_count + 1); busy_lock_counter++; last_count = count; - CHECK_EQ(0, mutex->Unlock()); + mutex->Unlock(); yield(); } } @@ -79,15 +79,14 @@ static void* RunTestBusyLock(void* arg) { // increment a variable. TEST(BusyLock) { pthread_t other; - Mutex* mutex = OS::CreateMutex(); + Mutex mutex; int thread_created = pthread_create(&other, NULL, &RunTestBusyLock, - mutex); + &mutex); CHECK_EQ(0, thread_created); - LoopIncrement(mutex, 1); + LoopIncrement(&mutex, 1); pthread_join(other, NULL); - delete mutex; } diff --git a/test/cctest/test-platform-nullos.cc b/test/cctest/test-platform-nullos.cc index 3afbd90..0ad67be 100644 --- a/test/cctest/test-platform-nullos.cc +++ b/test/cctest/test-platform-nullos.cc @@ -52,18 +52,18 @@ static void LoopIncrement(Mutex* mutex, int rem) { int count = 0; int last_count = -1; do { - CHECK_EQ(0, mutex->Lock()); + mutex->Lock(); count = busy_lock_counter; - CHECK_EQ(0, mutex->Unlock()); + mutex->Unlock(); yield(); } while (count % 2 == rem && count < kLockCounterLimit); if (count >= kLockCounterLimit) break; - CHECK_EQ(0, mutex->Lock()); + mutex->Lock(); CHECK_EQ(count, busy_lock_counter); CHECK(last_count == -1 || count == last_count + 1); busy_lock_counter++; last_count = count; - CHECK_EQ(0, mutex->Unlock()); + mutex->Unlock(); yield(); } } diff --git a/test/cctest/test-lock.cc b/test/cctest/test-semaphore.cc similarity index 74% rename from test/cctest/test-lock.cc rename to test/cctest/test-semaphore.cc index d4387d0..e06d52d 100644 --- a/test/cctest/test-lock.cc +++ b/test/cctest/test-semaphore.cc @@ -1,4 +1,4 @@ -// Copyright 2006-2008 the V8 project authors. All rights reserved. +// Copyright 2006-2013 the V8 project authors. All rights reserved. // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions are // met: @@ -25,9 +25,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Tests of the TokenLock class from lock.h - -#include +// Tests of the Semaphore class from platform.h #include "v8.h" @@ -38,33 +36,6 @@ using namespace ::v8::internal; -// Simple test of locking logic -TEST(Simple) { - Mutex* mutex = OS::CreateMutex(); - CHECK_EQ(0, mutex->Lock()); // acquire the lock with the right token - CHECK_EQ(0, mutex->Unlock()); // can unlock with the right token - delete mutex; -} - - -TEST(MultiLock) { - Mutex* mutex = OS::CreateMutex(); - CHECK_EQ(0, mutex->Lock()); - CHECK_EQ(0, mutex->Unlock()); - delete mutex; -} - - -TEST(ShallowLock) { - Mutex* mutex = OS::CreateMutex(); - CHECK_EQ(0, mutex->Lock()); - CHECK_EQ(0, mutex->Unlock()); - CHECK_EQ(0, mutex->Lock()); - CHECK_EQ(0, mutex->Unlock()); - delete mutex; -} - - TEST(SemaphoreTimeout) { bool ok; Semaphore* sem = OS::CreateSemaphore(0); diff --git a/tools/gyp/v8.gyp b/tools/gyp/v8.gyp index bdbc716..8a7e06d 100644 --- a/tools/gyp/v8.gyp +++ b/tools/gyp/v8.gyp @@ -419,6 +419,8 @@ '../../src/marking-thread.cc', '../../src/messages.cc', '../../src/messages.h', + '../../src/mutex.cc', + '../../src/mutex.h', '../../src/natives.h', '../../src/objects-debug.cc', '../../src/objects-inl.h',