diff options
Diffstat (limited to 'lldb/tools/lldb-mi/MIUtilThreadBaseStd.cpp')
-rw-r--r-- | lldb/tools/lldb-mi/MIUtilThreadBaseStd.cpp | 342 |
1 files changed, 342 insertions, 0 deletions
diff --git a/lldb/tools/lldb-mi/MIUtilThreadBaseStd.cpp b/lldb/tools/lldb-mi/MIUtilThreadBaseStd.cpp new file mode 100644 index 00000000000..eb45d394cb0 --- /dev/null +++ b/lldb/tools/lldb-mi/MIUtilThreadBaseStd.cpp @@ -0,0 +1,342 @@ +//===-- MIUtilThreadBaseStd.cpp ---------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +//++ +// File: MIUtilThreadBaseStd.cpp +// +// Overview: CMIUtilThread implementation. +// CMIUtilThreadActiveObjBase implementation. +// CMIUtilThreadMutex implementation. +// +// Environment: Compilers: Visual C++ 12. +// gcc (Ubuntu/Linaro 4.8.1-10ubuntu9) 4.8.1 +// Libraries: See MIReadmetxt. +// +// Copyright: None. +//-- + +// Include compiler configuration +#include "MICmnConfig.h" + +// Third Party Headers: +#include <assert.h> + +// In-house headers: +#include "MIUtilThreadBaseStd.h" +#include "MICmnThreadMgrStd.h" + +//++ ------------------------------------------------------------------------------------ +// Details: Constructor. +// Type: None. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMIUtilThreadActiveObjBase::CMIUtilThreadActiveObjBase( void ) +: m_references( 0 ) +, m_bHasBeenKilled( false ) +{ +} + +//++ ------------------------------------------------------------------------------------ +// Details: Destructor. +// Type: None. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMIUtilThreadActiveObjBase::~CMIUtilThreadActiveObjBase( void ) +{ + // Make sure our thread is not alive before we die + m_thread.Join(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Check if an object is already running. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThreadActiveObjBase::ThreadIsActive( void ) +{ + // Create a new thread to occupy this threads Run() function + return m_thread.IsActive(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Set up *this thread. +// Type: Mrthod. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThreadActiveObjBase::ThreadExecute( void ) +{ + // Create a new thread to occupy this threads Run() function + return m_thread.Start( ThreadEntry, this ); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Aquire a reference to CMIUtilThreadActiveObjBase. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThreadActiveObjBase::Acquire( void ) +{ + // Access to this function is serial + CMIUtilThreadLock serial( m_mutex ); + + // >0 == *this thread is alive + m_references++; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Release a reference to CMIUtilThreadActiveObjBase. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThreadActiveObjBase::Release( void ) +{ + // Access to this function is serial + CMIUtilThreadLock serial( m_mutex ); + + // 0 == kill off *this thread + m_references--; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Force this thread to stop, regardless of references +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThreadActiveObjBase::ThreadKill( void ) +{ + // Access to this function is serial + CMIUtilThreadLock serial( m_mutex ); + + // Set this thread to killed status + m_bHasBeenKilled = true; + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Proxy to thread join. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThreadActiveObjBase::ThreadJoin( void ) +{ + return m_thread.Join(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: This function is the entry point of this object thread. +// It is a trampoline to an instances operation manager. +// Type: Static method. +// Args: vpThisClass - (R) From the system (our CMIUtilThreadActiveObjBase from the ctor). +// Return: MIuint - 0 = success. +// Throws: None. +//-- +MIuint CMIUtilThreadActiveObjBase::ThreadEntry( void * vpThisClass ) +{ + // The argument is a pointer to a CMIUtilThreadActiveObjBase class + // as passed from the initialize function, so we can safely cast it. + assert( vpThisClass != nullptr ); + CMIUtilThreadActiveObjBase * pActive = reinterpret_cast< CMIUtilThreadActiveObjBase * >( vpThisClass ); + + // Start the management routine of this object + pActive->ThreadManage(); + + // Thread death + return 0; +} + +//++ ------------------------------------------------------------------------------------ +// Details: This function forms a small management routine, to handle the thread's running. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +void CMIUtilThreadActiveObjBase::ThreadManage( void ) +{ + bool bAlive = true; + + // Infinite loop + while( bAlive ) + { + // Scope the lock while we access m_isDying + { + // Lock down access to the interface + CMIUtilThreadLock serial( m_mutex ); + + // Quit the run loop if we are dying + if( m_references == 0 ) + break; + } + // Execute the run routine + if( !ThreadRun( bAlive ) ) + // Thread's run function failed (MIstatus::failure) + break; + + // We will die if we have been signaled to die + bAlive &= !m_bHasBeenKilled; + } + + // Execute the finish routine just before we die + // to give the object a chance to clean up + ThreadFinish(); +} + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +// +CMIUtilThread::CMIUtilThread( void ) +: m_pThread( nullptr ) +{ +} + +//++ ------------------------------------------------------------------------------------ +// Details: CMIUtilThread destructor. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +CMIUtilThread::~CMIUtilThread( void ) +{ + Join(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Wait for thread to stop. +// Type: Method. +// Args: None. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThread::Join( void ) +{ + if( m_pThread != nullptr ) + { + // Wait for this thread to die + m_pThread->join(); + + // Scope the thread lock while we modify the pointer + { + CMIUtilThreadLock _lock( m_mutex ); + delete m_pThread; + m_pThread = nullptr; + } + } + + return MIstatus::success; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Is the thread doing work. +// Type: Method. +// Args: None. +// Return: bool - True = Yes active, false = not active. +// Throws: None. +//-- +bool CMIUtilThread::IsActive( void ) +{ + // Lock while we access the thread pointer + CMIUtilThreadLock _lock( m_mutex ); + if( m_pThread == nullptr ) + return false; + else + return true; +} + +//++ ------------------------------------------------------------------------------------ +// Details: Set up *this thread. +// Type: Method. +// Args: vpFn (R) - Function pointer to thread's main function. +// vpArg (R) - Pointer arguments to pass to the thread. +// Return: MIstatus::success - Functional succeeded. +// MIstatus::failure - Functional failed. +// Throws: None. +//-- +bool CMIUtilThread::Start( FnThreadProc vpFn, void * vpArg ) +{ + // Create the std thread, which starts immediately + m_pThread = new std::thread( vpFn, vpArg ); + + // We expect to always be able to create one + assert( m_pThread != nullptr ); + + return MIstatus::success; +} + +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- +//--------------------------------------------------------------------------------------- + +//++ ------------------------------------------------------------------------------------ +// Details: Take resource. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +void CMIUtilThreadMutex::Lock( void ) +{ + m_mutex.lock(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Release resource. +// Type: Method. +// Args: None. +// Return: None. +// Throws: None. +//-- +void CMIUtilThreadMutex::Unlock( void ) +{ + m_mutex.unlock(); +} + +//++ ------------------------------------------------------------------------------------ +// Details: Take resource if available. Immediately return in either case. +// Type: Method. +// Args: None. +// Return: True - mutex has been locked. +// False - mutex could not be locked. +// Throws: None. +//-- +bool CMIUtilThreadMutex::TryLock( void ) +{ + return m_mutex.try_lock(); +} + |