1e65b2cf2SEugene Zelenko //===-- ThreadSpec.cpp ------------------------------------------*- C++ -*-===// 21b54c88cSJim Ingham // 31b54c88cSJim Ingham // The LLVM Compiler Infrastructure 41b54c88cSJim Ingham // 51b54c88cSJim Ingham // This file is distributed under the University of Illinois Open Source 61b54c88cSJim Ingham // License. See LICENSE.TXT for details. 71b54c88cSJim Ingham // 81b54c88cSJim Ingham //===----------------------------------------------------------------------===// 91b54c88cSJim Ingham 10e65b2cf2SEugene Zelenko // C Includes 11e65b2cf2SEugene Zelenko // C++ Includes 12e65b2cf2SEugene Zelenko // Other libraries and framework includes 13e65b2cf2SEugene Zelenko // Project includes 141b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 15*f2a8bccfSPavel Labath #include "lldb/Target/Thread.h" 16*f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h" 171b54c88cSJim Ingham 181b54c88cSJim Ingham using namespace lldb; 191b54c88cSJim Ingham using namespace lldb_private; 201b54c88cSJim Ingham 21778ef392SJim Ingham const char *ThreadSpec::g_option_names[static_cast<uint32_t>( 22778ef392SJim Ingham ThreadSpec::OptionNames::LastOptionName)]{"Index", "ID", "Name", 23778ef392SJim Ingham "QueueName"}; 24778ef392SJim Ingham 25b9c1b51eSKate Stone ThreadSpec::ThreadSpec() 26b9c1b51eSKate Stone : m_index(UINT32_MAX), m_tid(LLDB_INVALID_THREAD_ID), m_name(), 27b9c1b51eSKate Stone m_queue_name() {} 281b54c88cSJim Ingham 29b9c1b51eSKate Stone ThreadSpec::ThreadSpec(const ThreadSpec &rhs) 30b9c1b51eSKate Stone : m_index(rhs.m_index), m_tid(rhs.m_tid), m_name(rhs.m_name), 31b9c1b51eSKate Stone m_queue_name(rhs.m_queue_name) {} 321b54c88cSJim Ingham 33b9c1b51eSKate Stone const ThreadSpec &ThreadSpec::operator=(const ThreadSpec &rhs) { 341b54c88cSJim Ingham m_index = rhs.m_index; 351b54c88cSJim Ingham m_tid = rhs.m_tid; 361b54c88cSJim Ingham m_name = rhs.m_name; 371b54c88cSJim Ingham m_queue_name = rhs.m_queue_name; 381b54c88cSJim Ingham return *this; 391b54c88cSJim Ingham } 401b54c88cSJim Ingham 41778ef392SJim Ingham std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData( 4297206d57SZachary Turner const StructuredData::Dictionary &spec_dict, Status &error) { 43778ef392SJim Ingham uint32_t index = UINT32_MAX; 44778ef392SJim Ingham lldb::tid_t tid = LLDB_INVALID_THREAD_ID; 452833321fSZachary Turner llvm::StringRef name; 462833321fSZachary Turner llvm::StringRef queue_name; 47778ef392SJim Ingham 48778ef392SJim Ingham std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec()); 49778ef392SJim Ingham bool success = spec_dict.GetValueForKeyAsInteger( 50778ef392SJim Ingham GetKey(OptionNames::ThreadIndex), index); 51778ef392SJim Ingham if (success) 52778ef392SJim Ingham thread_spec_up->SetIndex(index); 53778ef392SJim Ingham 54778ef392SJim Ingham success = 55778ef392SJim Ingham spec_dict.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID), tid); 56778ef392SJim Ingham if (success) 57778ef392SJim Ingham thread_spec_up->SetTID(tid); 58778ef392SJim Ingham 59778ef392SJim Ingham success = 60778ef392SJim Ingham spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name); 61778ef392SJim Ingham if (success) 622833321fSZachary Turner thread_spec_up->SetName(name); 63778ef392SJim Ingham 64778ef392SJim Ingham success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), 65778ef392SJim Ingham queue_name); 66778ef392SJim Ingham if (success) 672833321fSZachary Turner thread_spec_up->SetQueueName(queue_name); 68778ef392SJim Ingham 69778ef392SJim Ingham return thread_spec_up; 70778ef392SJim Ingham } 71778ef392SJim Ingham 72778ef392SJim Ingham StructuredData::ObjectSP ThreadSpec::SerializeToStructuredData() { 73778ef392SJim Ingham StructuredData::DictionarySP data_dict_sp(new StructuredData::Dictionary()); 74778ef392SJim Ingham 75778ef392SJim Ingham if (m_index != UINT32_MAX) 76778ef392SJim Ingham data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadIndex), m_index); 77778ef392SJim Ingham if (m_tid != LLDB_INVALID_THREAD_ID) 78778ef392SJim Ingham data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadID), m_tid); 79778ef392SJim Ingham if (!m_name.empty()) 80778ef392SJim Ingham data_dict_sp->AddStringItem(GetKey(OptionNames::ThreadName), m_name); 81778ef392SJim Ingham if (!m_queue_name.empty()) 82778ef392SJim Ingham data_dict_sp->AddStringItem(GetKey(OptionNames::QueueName), m_queue_name); 83778ef392SJim Ingham 84778ef392SJim Ingham return data_dict_sp; 85778ef392SJim Ingham } 86778ef392SJim Ingham 87b9c1b51eSKate Stone const char *ThreadSpec::GetName() const { 88e65b2cf2SEugene Zelenko return m_name.empty() ? nullptr : m_name.c_str(); 891b54c88cSJim Ingham } 901b54c88cSJim Ingham 91b9c1b51eSKate Stone const char *ThreadSpec::GetQueueName() const { 92e65b2cf2SEugene Zelenko return m_queue_name.empty() ? nullptr : m_queue_name.c_str(); 931b54c88cSJim Ingham } 940136309fSJim Ingham 95b9c1b51eSKate Stone bool ThreadSpec::TIDMatches(Thread &thread) const { 963d902922SJim Ingham if (m_tid == LLDB_INVALID_THREAD_ID) 973d902922SJim Ingham return true; 983d902922SJim Ingham 993d902922SJim Ingham lldb::tid_t thread_id = thread.GetID(); 1003d902922SJim Ingham return TIDMatches(thread_id); 1013d902922SJim Ingham } 102e65b2cf2SEugene Zelenko 103b9c1b51eSKate Stone bool ThreadSpec::IndexMatches(Thread &thread) const { 1043d902922SJim Ingham if (m_index == UINT32_MAX) 1053d902922SJim Ingham return true; 1063d902922SJim Ingham uint32_t index = thread.GetIndexID(); 1073d902922SJim Ingham return IndexMatches(index); 1083d902922SJim Ingham } 109e65b2cf2SEugene Zelenko 110b9c1b51eSKate Stone bool ThreadSpec::NameMatches(Thread &thread) const { 1113d902922SJim Ingham if (m_name.empty()) 1123d902922SJim Ingham return true; 1133d902922SJim Ingham 1143d902922SJim Ingham const char *name = thread.GetName(); 1153d902922SJim Ingham return NameMatches(name); 1163d902922SJim Ingham } 117e65b2cf2SEugene Zelenko 118b9c1b51eSKate Stone bool ThreadSpec::QueueNameMatches(Thread &thread) const { 1193d902922SJim Ingham if (m_queue_name.empty()) 1203d902922SJim Ingham return true; 1213d902922SJim Ingham 1223d902922SJim Ingham const char *queue_name = thread.GetQueueName(); 1233d902922SJim Ingham return QueueNameMatches(queue_name); 1243d902922SJim Ingham } 1253d902922SJim Ingham 126b9c1b51eSKate Stone bool ThreadSpec::ThreadPassesBasicTests(Thread &thread) const { 1270136309fSJim Ingham if (!HasSpecification()) 1280136309fSJim Ingham return true; 1290136309fSJim Ingham 1303d902922SJim Ingham if (!TIDMatches(thread)) 1310136309fSJim Ingham return false; 1320136309fSJim Ingham 1333d902922SJim Ingham if (!IndexMatches(thread)) 1340136309fSJim Ingham return false; 1350136309fSJim Ingham 1363d902922SJim Ingham if (!NameMatches(thread)) 1370136309fSJim Ingham return false; 1380136309fSJim Ingham 1393d902922SJim Ingham if (!QueueNameMatches(thread)) 1400136309fSJim Ingham return false; 1410136309fSJim Ingham 1420136309fSJim Ingham return true; 1430136309fSJim Ingham } 1440136309fSJim Ingham 145b9c1b51eSKate Stone bool ThreadSpec::HasSpecification() const { 146b9c1b51eSKate Stone return (m_index != UINT32_MAX || m_tid != LLDB_INVALID_THREAD_ID || 147b9c1b51eSKate Stone !m_name.empty() || !m_queue_name.empty()); 1480136309fSJim Ingham } 149e65b2cf2SEugene Zelenko 150b9c1b51eSKate Stone void ThreadSpec::GetDescription(Stream *s, lldb::DescriptionLevel level) const { 151b9c1b51eSKate Stone if (!HasSpecification()) { 152b9c1b51eSKate Stone if (level == eDescriptionLevelBrief) { 1530136309fSJim Ingham s->PutCString("thread spec: no "); 1540136309fSJim Ingham } 155b9c1b51eSKate Stone } else { 156b9c1b51eSKate Stone if (level == eDescriptionLevelBrief) { 1570136309fSJim Ingham s->PutCString("thread spec: yes "); 158b9c1b51eSKate Stone } else { 1590136309fSJim Ingham if (GetTID() != LLDB_INVALID_THREAD_ID) 160d01b2953SDaniel Malea s->Printf("tid: 0x%" PRIx64 " ", GetTID()); 1610136309fSJim Ingham 162bdf4c6acSGreg Clayton if (GetIndex() != UINT32_MAX) 1630136309fSJim Ingham s->Printf("index: %d ", GetIndex()); 1640136309fSJim Ingham 1650136309fSJim Ingham const char *name = GetName(); 1660136309fSJim Ingham if (name) 1670136309fSJim Ingham s->Printf("thread name: \"%s\" ", name); 1680136309fSJim Ingham 1690136309fSJim Ingham const char *queue_name = GetQueueName(); 1700136309fSJim Ingham if (queue_name) 1710136309fSJim Ingham s->Printf("queue name: \"%s\" ", queue_name); 1720136309fSJim Ingham } 1730136309fSJim Ingham } 1740136309fSJim Ingham } 175