1e65b2cf2SEugene Zelenko //===-- ThreadSpec.cpp ------------------------------------------*- C++ -*-===// 21b54c88cSJim Ingham // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61b54c88cSJim Ingham // 71b54c88cSJim Ingham //===----------------------------------------------------------------------===// 81b54c88cSJim Ingham 91b54c88cSJim Ingham #include "lldb/Target/ThreadSpec.h" 10f2a8bccfSPavel Labath #include "lldb/Target/Thread.h" 11f2a8bccfSPavel Labath #include "lldb/Utility/StructuredData.h" 121b54c88cSJim Ingham 131b54c88cSJim Ingham using namespace lldb; 141b54c88cSJim Ingham using namespace lldb_private; 151b54c88cSJim Ingham 16778ef392SJim Ingham const char *ThreadSpec::g_option_names[static_cast<uint32_t>( 17778ef392SJim Ingham ThreadSpec::OptionNames::LastOptionName)]{"Index", "ID", "Name", 18778ef392SJim Ingham "QueueName"}; 19778ef392SJim Ingham 20b9c1b51eSKate Stone ThreadSpec::ThreadSpec() 21b9c1b51eSKate Stone : m_index(UINT32_MAX), m_tid(LLDB_INVALID_THREAD_ID), m_name(), 22b9c1b51eSKate Stone m_queue_name() {} 231b54c88cSJim Ingham 24b9c1b51eSKate Stone ThreadSpec::ThreadSpec(const ThreadSpec &rhs) 25b9c1b51eSKate Stone : m_index(rhs.m_index), m_tid(rhs.m_tid), m_name(rhs.m_name), 26b9c1b51eSKate Stone m_queue_name(rhs.m_queue_name) {} 271b54c88cSJim Ingham 28b9c1b51eSKate Stone const ThreadSpec &ThreadSpec::operator=(const ThreadSpec &rhs) { 291b54c88cSJim Ingham m_index = rhs.m_index; 301b54c88cSJim Ingham m_tid = rhs.m_tid; 311b54c88cSJim Ingham m_name = rhs.m_name; 321b54c88cSJim Ingham m_queue_name = rhs.m_queue_name; 331b54c88cSJim Ingham return *this; 341b54c88cSJim Ingham } 351b54c88cSJim Ingham 36778ef392SJim Ingham std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData( 3797206d57SZachary Turner const StructuredData::Dictionary &spec_dict, Status &error) { 38778ef392SJim Ingham uint32_t index = UINT32_MAX; 39778ef392SJim Ingham lldb::tid_t tid = LLDB_INVALID_THREAD_ID; 402833321fSZachary Turner llvm::StringRef name; 412833321fSZachary Turner llvm::StringRef queue_name; 42778ef392SJim Ingham 43778ef392SJim Ingham std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec()); 44778ef392SJim Ingham bool success = spec_dict.GetValueForKeyAsInteger( 45778ef392SJim Ingham GetKey(OptionNames::ThreadIndex), index); 46778ef392SJim Ingham if (success) 47778ef392SJim Ingham thread_spec_up->SetIndex(index); 48778ef392SJim Ingham 49778ef392SJim Ingham success = 50778ef392SJim Ingham spec_dict.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID), tid); 51778ef392SJim Ingham if (success) 52778ef392SJim Ingham thread_spec_up->SetTID(tid); 53778ef392SJim Ingham 54778ef392SJim Ingham success = 55778ef392SJim Ingham spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name); 56778ef392SJim Ingham if (success) 572833321fSZachary Turner thread_spec_up->SetName(name); 58778ef392SJim Ingham 59778ef392SJim Ingham success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), 60778ef392SJim Ingham queue_name); 61778ef392SJim Ingham if (success) 622833321fSZachary Turner thread_spec_up->SetQueueName(queue_name); 63778ef392SJim Ingham 64778ef392SJim Ingham return thread_spec_up; 65778ef392SJim Ingham } 66778ef392SJim Ingham 67778ef392SJim Ingham StructuredData::ObjectSP ThreadSpec::SerializeToStructuredData() { 68778ef392SJim Ingham StructuredData::DictionarySP data_dict_sp(new StructuredData::Dictionary()); 69778ef392SJim Ingham 70778ef392SJim Ingham if (m_index != UINT32_MAX) 71778ef392SJim Ingham data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadIndex), m_index); 72778ef392SJim Ingham if (m_tid != LLDB_INVALID_THREAD_ID) 73778ef392SJim Ingham data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadID), m_tid); 74778ef392SJim Ingham if (!m_name.empty()) 75778ef392SJim Ingham data_dict_sp->AddStringItem(GetKey(OptionNames::ThreadName), m_name); 76778ef392SJim Ingham if (!m_queue_name.empty()) 77778ef392SJim Ingham data_dict_sp->AddStringItem(GetKey(OptionNames::QueueName), m_queue_name); 78778ef392SJim Ingham 79778ef392SJim Ingham return data_dict_sp; 80778ef392SJim Ingham } 81778ef392SJim Ingham 82b9c1b51eSKate Stone const char *ThreadSpec::GetName() const { 83e65b2cf2SEugene Zelenko return m_name.empty() ? nullptr : m_name.c_str(); 841b54c88cSJim Ingham } 851b54c88cSJim Ingham 86b9c1b51eSKate Stone const char *ThreadSpec::GetQueueName() const { 87e65b2cf2SEugene Zelenko return m_queue_name.empty() ? nullptr : m_queue_name.c_str(); 881b54c88cSJim Ingham } 890136309fSJim Ingham 90b9c1b51eSKate Stone bool ThreadSpec::TIDMatches(Thread &thread) const { 913d902922SJim Ingham if (m_tid == LLDB_INVALID_THREAD_ID) 923d902922SJim Ingham return true; 933d902922SJim Ingham 943d902922SJim Ingham lldb::tid_t thread_id = thread.GetID(); 953d902922SJim Ingham return TIDMatches(thread_id); 963d902922SJim Ingham } 97e65b2cf2SEugene Zelenko 98b9c1b51eSKate Stone bool ThreadSpec::IndexMatches(Thread &thread) const { 993d902922SJim Ingham if (m_index == UINT32_MAX) 1003d902922SJim Ingham return true; 1013d902922SJim Ingham uint32_t index = thread.GetIndexID(); 1023d902922SJim Ingham return IndexMatches(index); 1033d902922SJim Ingham } 104e65b2cf2SEugene Zelenko 105b9c1b51eSKate Stone bool ThreadSpec::NameMatches(Thread &thread) const { 1063d902922SJim Ingham if (m_name.empty()) 1073d902922SJim Ingham return true; 1083d902922SJim Ingham 1093d902922SJim Ingham const char *name = thread.GetName(); 1103d902922SJim Ingham return NameMatches(name); 1113d902922SJim Ingham } 112e65b2cf2SEugene Zelenko 113b9c1b51eSKate Stone bool ThreadSpec::QueueNameMatches(Thread &thread) const { 1143d902922SJim Ingham if (m_queue_name.empty()) 1153d902922SJim Ingham return true; 1163d902922SJim Ingham 1173d902922SJim Ingham const char *queue_name = thread.GetQueueName(); 1183d902922SJim Ingham return QueueNameMatches(queue_name); 1193d902922SJim Ingham } 1203d902922SJim Ingham 121b9c1b51eSKate Stone bool ThreadSpec::ThreadPassesBasicTests(Thread &thread) const { 1220136309fSJim Ingham if (!HasSpecification()) 1230136309fSJim Ingham return true; 1240136309fSJim Ingham 1253d902922SJim Ingham if (!TIDMatches(thread)) 1260136309fSJim Ingham return false; 1270136309fSJim Ingham 1283d902922SJim Ingham if (!IndexMatches(thread)) 1290136309fSJim Ingham return false; 1300136309fSJim Ingham 1313d902922SJim Ingham if (!NameMatches(thread)) 1320136309fSJim Ingham return false; 1330136309fSJim Ingham 1343d902922SJim Ingham if (!QueueNameMatches(thread)) 1350136309fSJim Ingham return false; 1360136309fSJim Ingham 1370136309fSJim Ingham return true; 1380136309fSJim Ingham } 1390136309fSJim Ingham 140b9c1b51eSKate Stone bool ThreadSpec::HasSpecification() const { 141b9c1b51eSKate Stone return (m_index != UINT32_MAX || m_tid != LLDB_INVALID_THREAD_ID || 142b9c1b51eSKate Stone !m_name.empty() || !m_queue_name.empty()); 1430136309fSJim Ingham } 144e65b2cf2SEugene Zelenko 145b9c1b51eSKate Stone void ThreadSpec::GetDescription(Stream *s, lldb::DescriptionLevel level) const { 146b9c1b51eSKate Stone if (!HasSpecification()) { 147b9c1b51eSKate Stone if (level == eDescriptionLevelBrief) { 1480136309fSJim Ingham s->PutCString("thread spec: no "); 1490136309fSJim Ingham } 150b9c1b51eSKate Stone } else { 151b9c1b51eSKate Stone if (level == eDescriptionLevelBrief) { 1520136309fSJim Ingham s->PutCString("thread spec: yes "); 153b9c1b51eSKate Stone } else { 1540136309fSJim Ingham if (GetTID() != LLDB_INVALID_THREAD_ID) 155d01b2953SDaniel Malea s->Printf("tid: 0x%" PRIx64 " ", GetTID()); 1560136309fSJim Ingham 157bdf4c6acSGreg Clayton if (GetIndex() != UINT32_MAX) 1580136309fSJim Ingham s->Printf("index: %d ", GetIndex()); 1590136309fSJim Ingham 1600136309fSJim Ingham const char *name = GetName(); 1610136309fSJim Ingham if (name) 1620136309fSJim Ingham s->Printf("thread name: \"%s\" ", name); 1630136309fSJim Ingham 1640136309fSJim Ingham const char *queue_name = GetQueueName(); 1650136309fSJim Ingham if (queue_name) 1660136309fSJim Ingham s->Printf("queue name: \"%s\" ", queue_name); 1670136309fSJim Ingham } 1680136309fSJim Ingham } 1690136309fSJim Ingham } 170