forked from OSchip/llvm-project
				
			
		
			
				
	
	
		
			451 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
			
		
		
	
	
			451 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			C++
		
	
	
	
| //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
 | |
| //
 | |
| //                     The LLVM Compiler Infrastructure
 | |
| //
 | |
| // This file is distributed under the University of Illinois Open Source
 | |
| // License. See LICENSE.TXT for details.
 | |
| //
 | |
| //===----------------------------------------------------------------------===//
 | |
| 
 | |
| #include "lldb/lldb-python.h"
 | |
| 
 | |
| #include <inttypes.h>
 | |
| 
 | |
| #include "lldb/API/SBQueue.h"
 | |
| 
 | |
| #include "lldb/API/SBProcess.h"
 | |
| #include "lldb/API/SBThread.h"
 | |
| #include "lldb/Core/Log.h"
 | |
| #include "lldb/Target/Process.h"
 | |
| #include "lldb/Target/Queue.h"
 | |
| #include "lldb/Target/QueueItem.h"
 | |
| #include "lldb/Target/Thread.h"
 | |
| 
 | |
| using namespace lldb;
 | |
| using namespace lldb_private;
 | |
| 
 | |
| namespace lldb_private
 | |
| {
 | |
| 
 | |
|     class QueueImpl
 | |
|     {
 | |
|     public:
 | |
|         QueueImpl () :
 | |
|             m_queue_wp(),
 | |
|             m_threads(),
 | |
|             m_thread_list_fetched(false),
 | |
|             m_pending_items(),
 | |
|             m_pending_items_fetched(false)
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         QueueImpl (const lldb::QueueSP &queue_sp) :
 | |
|             m_queue_wp(),
 | |
|             m_threads(),
 | |
|             m_thread_list_fetched(false),
 | |
|             m_pending_items(),
 | |
|             m_pending_items_fetched(false)
 | |
|         {
 | |
|             m_queue_wp = queue_sp;
 | |
|         }
 | |
| 
 | |
|         QueueImpl (const QueueImpl &rhs)
 | |
|         {
 | |
|             if (&rhs == this)
 | |
|                 return;
 | |
|             m_queue_wp = rhs.m_queue_wp;
 | |
|             m_threads = rhs.m_threads;
 | |
|             m_thread_list_fetched = rhs.m_thread_list_fetched;
 | |
|             m_pending_items = rhs.m_pending_items;
 | |
|             m_pending_items_fetched = rhs.m_pending_items_fetched;
 | |
|         }
 | |
| 
 | |
|         ~QueueImpl ()
 | |
|         {
 | |
|         }
 | |
| 
 | |
|         bool
 | |
|         IsValid ()
 | |
|         {
 | |
|             return m_queue_wp.lock() != NULL;
 | |
|         }
 | |
| 
 | |
|         void
 | |
|         Clear ()
 | |
|         {
 | |
|             m_queue_wp.reset();
 | |
|             m_thread_list_fetched = false;
 | |
|             m_threads.clear();
 | |
|             m_pending_items_fetched = false;
 | |
|             m_pending_items.clear();
 | |
|         }
 | |
| 
 | |
|         void
 | |
|         SetQueue (const lldb::QueueSP &queue_sp)
 | |
|         {
 | |
|             Clear();
 | |
|             m_queue_wp = queue_sp;
 | |
|         }
 | |
| 
 | |
|         lldb::queue_id_t
 | |
|         GetQueueID () const
 | |
|         {
 | |
|             lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
 | |
|             lldb::QueueSP queue_sp = m_queue_wp.lock();
 | |
|             if (queue_sp)
 | |
|             {
 | |
|                 result = queue_sp->GetID();
 | |
|             }
 | |
|             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|             if (log)
 | |
|                 log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64,
 | |
|                              static_cast<const void*>(this), result);
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         uint32_t
 | |
|         GetIndexID () const
 | |
|         {
 | |
|             uint32_t result = LLDB_INVALID_INDEX32;
 | |
|             lldb::QueueSP queue_sp = m_queue_wp.lock();
 | |
|             if (queue_sp)
 | |
|             {
 | |
|                 result = queue_sp->GetIndexID();
 | |
|             }
 | |
|             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|             if (log)
 | |
|                 log->Printf ("SBQueueImpl(%p)::GetIndexID () => %d",
 | |
|                              static_cast<const void*>(this), result);
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         const char *
 | |
|         GetName () const
 | |
|         {
 | |
|             const char *name = NULL;
 | |
|             lldb::QueueSP queue_sp = m_queue_wp.lock ();
 | |
|             if (queue_sp.get())
 | |
|             {
 | |
|                 name = queue_sp->GetName();
 | |
|             }
 | |
| 
 | |
|             Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|             if (log)
 | |
|                 log->Printf ("SBQueueImpl(%p)::GetName () => %s",
 | |
|                              static_cast<const void*>(this),
 | |
|                              name ? name : "NULL");
 | |
| 
 | |
|             return name;
 | |
|         }
 | |
| 
 | |
|         void
 | |
|         FetchThreads ()
 | |
|         {
 | |
|             if (m_thread_list_fetched == false)
 | |
|             {
 | |
|                 lldb::QueueSP queue_sp = m_queue_wp.lock();
 | |
|                 if (queue_sp)
 | |
|                 {
 | |
|                     Process::StopLocker stop_locker;
 | |
|                     if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
 | |
|                     {
 | |
|                         const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
 | |
|                         m_thread_list_fetched = true;
 | |
|                         const uint32_t num_threads = thread_list.size();
 | |
|                         for (uint32_t idx = 0; idx < num_threads; ++idx)
 | |
|                         {
 | |
|                             ThreadSP thread_sp = thread_list[idx];
 | |
|                             if (thread_sp && thread_sp->IsValid())
 | |
|                             {
 | |
|                                 m_threads.push_back (thread_sp);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         void
 | |
|         FetchItems ()
 | |
|         {
 | |
|             if (m_pending_items_fetched == false)
 | |
|             {
 | |
|                 QueueSP queue_sp = m_queue_wp.lock();
 | |
|                 if (queue_sp)
 | |
|                 {
 | |
|                     Process::StopLocker stop_locker;
 | |
|                     if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock()))
 | |
|                     {
 | |
|                         const std::vector<QueueItemSP> queue_items(queue_sp->GetPendingItems());
 | |
|                         m_pending_items_fetched = true;
 | |
|                         const uint32_t num_pending_items = queue_items.size();
 | |
|                         for (uint32_t idx = 0; idx < num_pending_items; ++idx)
 | |
|                         {
 | |
|                             QueueItemSP item = queue_items[idx];
 | |
|                             if (item && item->IsValid())
 | |
|                             {
 | |
|                                 m_pending_items.push_back (item);
 | |
|                             }
 | |
|                         }
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         uint32_t
 | |
|         GetNumThreads ()
 | |
|         {
 | |
|             uint32_t result = 0;
 | |
| 
 | |
|             FetchThreads();
 | |
|             if (m_thread_list_fetched)
 | |
|             {
 | |
|                 result = m_threads.size();
 | |
|             }
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         lldb::SBThread
 | |
|         GetThreadAtIndex (uint32_t idx)
 | |
|         {
 | |
|             FetchThreads();
 | |
| 
 | |
|             SBThread sb_thread;
 | |
|             QueueSP queue_sp = m_queue_wp.lock();
 | |
|             if (queue_sp && idx < m_threads.size())
 | |
|             {
 | |
|                 ProcessSP process_sp = queue_sp->GetProcess();
 | |
|                 if (process_sp)
 | |
|                 {
 | |
|                     ThreadSP thread_sp = m_threads[idx].lock();
 | |
|                     if (thread_sp)
 | |
|                     {
 | |
|                         sb_thread.SetThread (thread_sp);
 | |
|                     }
 | |
|                 }
 | |
|             }
 | |
|             return sb_thread;
 | |
|         }
 | |
| 
 | |
|         uint32_t
 | |
|         GetNumPendingItems ()
 | |
|         {
 | |
|             uint32_t result = 0;
 | |
| 
 | |
|             QueueSP queue_sp = m_queue_wp.lock();
 | |
|             if (m_pending_items_fetched == false && queue_sp)
 | |
|             {
 | |
|                 result = queue_sp->GetNumPendingWorkItems();
 | |
|             }
 | |
|             else
 | |
|             {
 | |
|                 result = m_pending_items.size();
 | |
|             }
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         lldb::SBQueueItem
 | |
|         GetPendingItemAtIndex (uint32_t idx)
 | |
|         {
 | |
|             SBQueueItem result;
 | |
|             FetchItems();
 | |
|             if (m_pending_items_fetched && idx < m_pending_items.size())
 | |
|             {
 | |
|                 result.SetQueueItem (m_pending_items[idx]);
 | |
|             }
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         uint32_t
 | |
|         GetNumRunningItems ()
 | |
|         {
 | |
|             uint32_t result = 0;
 | |
|             QueueSP queue_sp = m_queue_wp.lock();
 | |
|             if (queue_sp)
 | |
|                 result = queue_sp->GetNumRunningWorkItems();
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         lldb::SBProcess
 | |
|         GetProcess ()
 | |
|         {
 | |
|             SBProcess result;
 | |
|             QueueSP queue_sp = m_queue_wp.lock();
 | |
|             if (queue_sp)
 | |
|             {
 | |
|                 result.SetSP (queue_sp->GetProcess());
 | |
|             }
 | |
|             return result;
 | |
|         }
 | |
| 
 | |
|         lldb::QueueKind
 | |
|         GetKind ()
 | |
|         {
 | |
|             lldb::QueueKind kind = eQueueKindUnknown;
 | |
|             QueueSP queue_sp = m_queue_wp.lock();
 | |
|             if (queue_sp)
 | |
|                 kind = queue_sp->GetKind();
 | |
| 
 | |
|             return kind;
 | |
|         }
 | |
| 
 | |
|     private:
 | |
|         lldb::QueueWP                   m_queue_wp;
 | |
|         std::vector<lldb::ThreadWP>     m_threads;              // threads currently executing this queue's items
 | |
|         bool                            m_thread_list_fetched;  // have we tried to fetch the threads list already?
 | |
|         std::vector<lldb::QueueItemSP>  m_pending_items;       // items currently enqueued
 | |
|         bool                            m_pending_items_fetched;  // have we tried to fetch the item list already?
 | |
|     };
 | |
| 
 | |
| }
 | |
| 
 | |
| SBQueue::SBQueue () :
 | |
|     m_opaque_sp (new QueueImpl())
 | |
| {
 | |
| }
 | |
| 
 | |
| SBQueue::SBQueue (const QueueSP& queue_sp) :
 | |
|     m_opaque_sp (new QueueImpl (queue_sp))
 | |
| {
 | |
| }
 | |
| 
 | |
| SBQueue::SBQueue (const SBQueue &rhs)
 | |
| {
 | |
|     if (&rhs == this)
 | |
|         return;
 | |
| 
 | |
|     m_opaque_sp = rhs.m_opaque_sp;
 | |
| }
 | |
| 
 | |
| const lldb::SBQueue &
 | |
| SBQueue::operator = (const lldb::SBQueue &rhs)
 | |
| {
 | |
|     m_opaque_sp = rhs.m_opaque_sp;
 | |
|     return *this;
 | |
| }
 | |
| 
 | |
| SBQueue::~SBQueue()
 | |
| {
 | |
| }
 | |
| 
 | |
| bool
 | |
| SBQueue::IsValid() const
 | |
| {
 | |
|     bool is_valid = m_opaque_sp->IsValid ();
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s", m_opaque_sp->GetQueueID(),
 | |
|                     is_valid ? "true" : "false");
 | |
|     return is_valid;
 | |
| }
 | |
| 
 | |
| 
 | |
| void
 | |
| SBQueue::Clear ()
 | |
| {
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID());
 | |
|     m_opaque_sp->Clear();
 | |
| }
 | |
| 
 | |
| 
 | |
| void
 | |
| SBQueue::SetQueue (const QueueSP& queue_sp)
 | |
| {
 | |
|     m_opaque_sp->SetQueue (queue_sp);
 | |
| }
 | |
| 
 | |
| lldb::queue_id_t
 | |
| SBQueue::GetQueueID () const
 | |
| {
 | |
|     lldb::queue_id_t qid = m_opaque_sp->GetQueueID ();
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64, m_opaque_sp->GetQueueID(), (uint64_t) qid);
 | |
|     return qid;
 | |
| }
 | |
| 
 | |
| uint32_t
 | |
| SBQueue::GetIndexID () const
 | |
| {
 | |
|     uint32_t index_id = m_opaque_sp->GetIndexID ();
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32, m_opaque_sp->GetQueueID(), index_id);
 | |
|     return index_id;
 | |
| }
 | |
| 
 | |
| const char *
 | |
| SBQueue::GetName () const
 | |
| {
 | |
|     const char *name = m_opaque_sp->GetName ();
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s", m_opaque_sp->GetQueueID(), 
 | |
|                      name ? name : "");
 | |
|     return name;
 | |
| }
 | |
| 
 | |
| uint32_t
 | |
| SBQueue::GetNumThreads ()
 | |
| {
 | |
|     uint32_t numthreads = m_opaque_sp->GetNumThreads ();
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d", m_opaque_sp->GetQueueID(), numthreads);
 | |
|     return numthreads;
 | |
| }
 | |
| 
 | |
| SBThread
 | |
| SBQueue::GetThreadAtIndex (uint32_t idx)
 | |
| {
 | |
|     SBThread th = m_opaque_sp->GetThreadAtIndex (idx);
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)", m_opaque_sp->GetQueueID(), idx);
 | |
|     return th;
 | |
| }
 | |
| 
 | |
| 
 | |
| uint32_t
 | |
| SBQueue::GetNumPendingItems ()
 | |
| {
 | |
|     uint32_t pending_items = m_opaque_sp->GetNumPendingItems ();
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d", m_opaque_sp->GetQueueID(), pending_items);
 | |
|     return pending_items;
 | |
| }
 | |
| 
 | |
| SBQueueItem
 | |
| SBQueue::GetPendingItemAtIndex (uint32_t idx)
 | |
| {
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)", m_opaque_sp->GetQueueID(),  idx);
 | |
|     return m_opaque_sp->GetPendingItemAtIndex (idx);
 | |
| }
 | |
| 
 | |
| uint32_t
 | |
| SBQueue::GetNumRunningItems ()
 | |
| {
 | |
|     uint32_t running_items = m_opaque_sp->GetNumRunningItems ();
 | |
|     Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API));
 | |
|     if (log)
 | |
|         log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d", m_opaque_sp->GetQueueID(), running_items);
 | |
|     return running_items;
 | |
| }
 | |
| 
 | |
| SBProcess
 | |
| SBQueue::GetProcess ()
 | |
| {
 | |
|     return m_opaque_sp->GetProcess();
 | |
| }
 | |
| 
 | |
| lldb::QueueKind
 | |
| SBQueue::GetKind ()
 | |
| {
 | |
|     return m_opaque_sp->GetKind();
 | |
| }
 |