blob: b19ed72543c2593293affd4dae28d72b4a177e94 [file] [log] [blame]
//===-- 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/API/SBQueueItem.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();
}