2015-12-15 09:33:19 +08:00
|
|
|
//===-- ThreadSpec.cpp ------------------------------------------*- C++ -*-===//
|
2010-06-16 10:00:15 +08:00
|
|
|
//
|
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// This file is distributed under the University of Illinois Open Source
|
|
|
|
// License. See LICENSE.TXT for details.
|
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2015-12-15 09:33:19 +08:00
|
|
|
// C Includes
|
|
|
|
// C++ Includes
|
|
|
|
// Other libraries and framework includes
|
|
|
|
// Project includes
|
2010-06-16 10:00:15 +08:00
|
|
|
#include "lldb/Target/ThreadSpec.h"
|
2017-06-27 18:45:31 +08:00
|
|
|
#include "lldb/Target/Thread.h"
|
|
|
|
#include "lldb/Utility/StructuredData.h"
|
2010-06-16 10:00:15 +08:00
|
|
|
|
|
|
|
using namespace lldb;
|
|
|
|
using namespace lldb_private;
|
|
|
|
|
2016-09-23 06:00:59 +08:00
|
|
|
const char *ThreadSpec::g_option_names[static_cast<uint32_t>(
|
|
|
|
ThreadSpec::OptionNames::LastOptionName)]{"Index", "ID", "Name",
|
|
|
|
"QueueName"};
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
ThreadSpec::ThreadSpec()
|
|
|
|
: m_index(UINT32_MAX), m_tid(LLDB_INVALID_THREAD_ID), m_name(),
|
|
|
|
m_queue_name() {}
|
2010-06-16 10:00:15 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
ThreadSpec::ThreadSpec(const ThreadSpec &rhs)
|
|
|
|
: m_index(rhs.m_index), m_tid(rhs.m_tid), m_name(rhs.m_name),
|
|
|
|
m_queue_name(rhs.m_queue_name) {}
|
2010-06-16 10:00:15 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
const ThreadSpec &ThreadSpec::operator=(const ThreadSpec &rhs) {
|
|
|
|
m_index = rhs.m_index;
|
|
|
|
m_tid = rhs.m_tid;
|
|
|
|
m_name = rhs.m_name;
|
|
|
|
m_queue_name = rhs.m_queue_name;
|
|
|
|
return *this;
|
2010-06-16 10:00:15 +08:00
|
|
|
}
|
|
|
|
|
2016-09-23 06:00:59 +08:00
|
|
|
std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData(
|
2017-05-12 12:51:55 +08:00
|
|
|
const StructuredData::Dictionary &spec_dict, Status &error) {
|
2016-09-23 06:00:59 +08:00
|
|
|
uint32_t index = UINT32_MAX;
|
|
|
|
lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
|
2017-05-12 13:49:54 +08:00
|
|
|
llvm::StringRef name;
|
|
|
|
llvm::StringRef queue_name;
|
2016-09-23 06:00:59 +08:00
|
|
|
|
|
|
|
std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec());
|
|
|
|
bool success = spec_dict.GetValueForKeyAsInteger(
|
|
|
|
GetKey(OptionNames::ThreadIndex), index);
|
|
|
|
if (success)
|
|
|
|
thread_spec_up->SetIndex(index);
|
|
|
|
|
|
|
|
success =
|
|
|
|
spec_dict.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID), tid);
|
|
|
|
if (success)
|
|
|
|
thread_spec_up->SetTID(tid);
|
|
|
|
|
|
|
|
success =
|
|
|
|
spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name);
|
|
|
|
if (success)
|
2017-05-12 13:49:54 +08:00
|
|
|
thread_spec_up->SetName(name);
|
2016-09-23 06:00:59 +08:00
|
|
|
|
|
|
|
success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName),
|
|
|
|
queue_name);
|
|
|
|
if (success)
|
2017-05-12 13:49:54 +08:00
|
|
|
thread_spec_up->SetQueueName(queue_name);
|
2016-09-23 06:00:59 +08:00
|
|
|
|
|
|
|
return thread_spec_up;
|
|
|
|
}
|
|
|
|
|
|
|
|
StructuredData::ObjectSP ThreadSpec::SerializeToStructuredData() {
|
|
|
|
StructuredData::DictionarySP data_dict_sp(new StructuredData::Dictionary());
|
|
|
|
|
|
|
|
if (m_index != UINT32_MAX)
|
|
|
|
data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadIndex), m_index);
|
|
|
|
if (m_tid != LLDB_INVALID_THREAD_ID)
|
|
|
|
data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadID), m_tid);
|
|
|
|
if (!m_name.empty())
|
|
|
|
data_dict_sp->AddStringItem(GetKey(OptionNames::ThreadName), m_name);
|
|
|
|
if (!m_queue_name.empty())
|
|
|
|
data_dict_sp->AddStringItem(GetKey(OptionNames::QueueName), m_queue_name);
|
|
|
|
|
|
|
|
return data_dict_sp;
|
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
const char *ThreadSpec::GetName() const {
|
|
|
|
return m_name.empty() ? nullptr : m_name.c_str();
|
2010-06-16 10:00:15 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
const char *ThreadSpec::GetQueueName() const {
|
|
|
|
return m_queue_name.empty() ? nullptr : m_queue_name.c_str();
|
2010-06-16 10:00:15 +08:00
|
|
|
}
|
2010-06-18 09:00:58 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadSpec::TIDMatches(Thread &thread) const {
|
|
|
|
if (m_tid == LLDB_INVALID_THREAD_ID)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
lldb::tid_t thread_id = thread.GetID();
|
|
|
|
return TIDMatches(thread_id);
|
2012-03-08 06:03:04 +08:00
|
|
|
}
|
2015-12-15 09:33:19 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadSpec::IndexMatches(Thread &thread) const {
|
|
|
|
if (m_index == UINT32_MAX)
|
|
|
|
return true;
|
|
|
|
uint32_t index = thread.GetIndexID();
|
|
|
|
return IndexMatches(index);
|
2012-03-08 06:03:04 +08:00
|
|
|
}
|
2015-12-15 09:33:19 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadSpec::NameMatches(Thread &thread) const {
|
|
|
|
if (m_name.empty())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
const char *name = thread.GetName();
|
|
|
|
return NameMatches(name);
|
2012-03-08 06:03:04 +08:00
|
|
|
}
|
2015-12-15 09:33:19 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadSpec::QueueNameMatches(Thread &thread) const {
|
|
|
|
if (m_queue_name.empty())
|
|
|
|
return true;
|
|
|
|
|
|
|
|
const char *queue_name = thread.GetQueueName();
|
|
|
|
return QueueNameMatches(queue_name);
|
2012-03-08 06:03:04 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadSpec::ThreadPassesBasicTests(Thread &thread) const {
|
|
|
|
if (!HasSpecification())
|
2010-06-18 09:00:58 +08:00
|
|
|
return true;
|
2016-09-07 04:57:50 +08:00
|
|
|
|
|
|
|
if (!TIDMatches(thread))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!IndexMatches(thread))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!NameMatches(thread))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
if (!QueueNameMatches(thread))
|
|
|
|
return false;
|
|
|
|
|
|
|
|
return true;
|
2010-06-18 09:00:58 +08:00
|
|
|
}
|
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
bool ThreadSpec::HasSpecification() const {
|
|
|
|
return (m_index != UINT32_MAX || m_tid != LLDB_INVALID_THREAD_ID ||
|
|
|
|
!m_name.empty() || !m_queue_name.empty());
|
2010-06-18 09:00:58 +08:00
|
|
|
}
|
2015-12-15 09:33:19 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
void ThreadSpec::GetDescription(Stream *s, lldb::DescriptionLevel level) const {
|
|
|
|
if (!HasSpecification()) {
|
|
|
|
if (level == eDescriptionLevelBrief) {
|
|
|
|
s->PutCString("thread spec: no ");
|
2010-06-18 09:00:58 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
} else {
|
|
|
|
if (level == eDescriptionLevelBrief) {
|
|
|
|
s->PutCString("thread spec: yes ");
|
|
|
|
} else {
|
|
|
|
if (GetTID() != LLDB_INVALID_THREAD_ID)
|
|
|
|
s->Printf("tid: 0x%" PRIx64 " ", GetTID());
|
|
|
|
|
|
|
|
if (GetIndex() != UINT32_MAX)
|
|
|
|
s->Printf("index: %d ", GetIndex());
|
|
|
|
|
|
|
|
const char *name = GetName();
|
|
|
|
if (name)
|
|
|
|
s->Printf("thread name: \"%s\" ", name);
|
2010-06-18 09:00:58 +08:00
|
|
|
|
2016-09-07 04:57:50 +08:00
|
|
|
const char *queue_name = GetQueueName();
|
|
|
|
if (queue_name)
|
|
|
|
s->Printf("queue name: \"%s\" ", queue_name);
|
2010-06-18 09:00:58 +08:00
|
|
|
}
|
2016-09-07 04:57:50 +08:00
|
|
|
}
|
2010-06-18 09:00:58 +08:00
|
|
|
}
|