1*80814287SRaphael Isemann //===-- ThreadSpec.cpp ----------------------------------------------------===// 21b54c88cSJim Ingham // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler 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 24778ef392SJim Ingham std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData( 2597206d57SZachary Turner const StructuredData::Dictionary &spec_dict, Status &error) { 26778ef392SJim Ingham uint32_t index = UINT32_MAX; 27778ef392SJim Ingham lldb::tid_t tid = LLDB_INVALID_THREAD_ID; 282833321fSZachary Turner llvm::StringRef name; 292833321fSZachary Turner llvm::StringRef queue_name; 30778ef392SJim Ingham 31778ef392SJim Ingham std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec()); 32778ef392SJim Ingham bool success = spec_dict.GetValueForKeyAsInteger( 33778ef392SJim Ingham GetKey(OptionNames::ThreadIndex), index); 34778ef392SJim Ingham if (success) 35778ef392SJim Ingham thread_spec_up->SetIndex(index); 36778ef392SJim Ingham 37778ef392SJim Ingham success = 38778ef392SJim Ingham spec_dict.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID), tid); 39778ef392SJim Ingham if (success) 40778ef392SJim Ingham thread_spec_up->SetTID(tid); 41778ef392SJim Ingham 42778ef392SJim Ingham success = 43778ef392SJim Ingham spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name); 44778ef392SJim Ingham if (success) 452833321fSZachary Turner thread_spec_up->SetName(name); 46778ef392SJim Ingham 47778ef392SJim Ingham success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), 48778ef392SJim Ingham queue_name); 49778ef392SJim Ingham if (success) 502833321fSZachary Turner thread_spec_up->SetQueueName(queue_name); 51778ef392SJim Ingham 52778ef392SJim Ingham return thread_spec_up; 53778ef392SJim Ingham } 54778ef392SJim Ingham 55778ef392SJim Ingham StructuredData::ObjectSP ThreadSpec::SerializeToStructuredData() { 56778ef392SJim Ingham StructuredData::DictionarySP data_dict_sp(new StructuredData::Dictionary()); 57778ef392SJim Ingham 58778ef392SJim Ingham if (m_index != UINT32_MAX) 59778ef392SJim Ingham data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadIndex), m_index); 60778ef392SJim Ingham if (m_tid != LLDB_INVALID_THREAD_ID) 61778ef392SJim Ingham data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadID), m_tid); 62778ef392SJim Ingham if (!m_name.empty()) 63778ef392SJim Ingham data_dict_sp->AddStringItem(GetKey(OptionNames::ThreadName), m_name); 64778ef392SJim Ingham if (!m_queue_name.empty()) 65778ef392SJim Ingham data_dict_sp->AddStringItem(GetKey(OptionNames::QueueName), m_queue_name); 66778ef392SJim Ingham 67778ef392SJim Ingham return data_dict_sp; 68778ef392SJim Ingham } 69778ef392SJim Ingham 70b9c1b51eSKate Stone const char *ThreadSpec::GetName() const { 71e65b2cf2SEugene Zelenko return m_name.empty() ? nullptr : m_name.c_str(); 721b54c88cSJim Ingham } 731b54c88cSJim Ingham 74b9c1b51eSKate Stone const char *ThreadSpec::GetQueueName() const { 75e65b2cf2SEugene Zelenko return m_queue_name.empty() ? nullptr : m_queue_name.c_str(); 761b54c88cSJim Ingham } 770136309fSJim Ingham 78b9c1b51eSKate Stone bool ThreadSpec::TIDMatches(Thread &thread) const { 793d902922SJim Ingham if (m_tid == LLDB_INVALID_THREAD_ID) 803d902922SJim Ingham return true; 813d902922SJim Ingham 823d902922SJim Ingham lldb::tid_t thread_id = thread.GetID(); 833d902922SJim Ingham return TIDMatches(thread_id); 843d902922SJim Ingham } 85e65b2cf2SEugene Zelenko 86b9c1b51eSKate Stone bool ThreadSpec::IndexMatches(Thread &thread) const { 873d902922SJim Ingham if (m_index == UINT32_MAX) 883d902922SJim Ingham return true; 893d902922SJim Ingham uint32_t index = thread.GetIndexID(); 903d902922SJim Ingham return IndexMatches(index); 913d902922SJim Ingham } 92e65b2cf2SEugene Zelenko 93b9c1b51eSKate Stone bool ThreadSpec::NameMatches(Thread &thread) const { 943d902922SJim Ingham if (m_name.empty()) 953d902922SJim Ingham return true; 963d902922SJim Ingham 973d902922SJim Ingham const char *name = thread.GetName(); 983d902922SJim Ingham return NameMatches(name); 993d902922SJim Ingham } 100e65b2cf2SEugene Zelenko 101b9c1b51eSKate Stone bool ThreadSpec::QueueNameMatches(Thread &thread) const { 1023d902922SJim Ingham if (m_queue_name.empty()) 1033d902922SJim Ingham return true; 1043d902922SJim Ingham 1053d902922SJim Ingham const char *queue_name = thread.GetQueueName(); 1063d902922SJim Ingham return QueueNameMatches(queue_name); 1073d902922SJim Ingham } 1083d902922SJim Ingham 109b9c1b51eSKate Stone bool ThreadSpec::ThreadPassesBasicTests(Thread &thread) const { 1100136309fSJim Ingham if (!HasSpecification()) 1110136309fSJim Ingham return true; 1120136309fSJim Ingham 1133d902922SJim Ingham if (!TIDMatches(thread)) 1140136309fSJim Ingham return false; 1150136309fSJim Ingham 1163d902922SJim Ingham if (!IndexMatches(thread)) 1170136309fSJim Ingham return false; 1180136309fSJim Ingham 1193d902922SJim Ingham if (!NameMatches(thread)) 1200136309fSJim Ingham return false; 1210136309fSJim Ingham 1223d902922SJim Ingham if (!QueueNameMatches(thread)) 1230136309fSJim Ingham return false; 1240136309fSJim Ingham 1250136309fSJim Ingham return true; 1260136309fSJim Ingham } 1270136309fSJim Ingham 128b9c1b51eSKate Stone bool ThreadSpec::HasSpecification() const { 129b9c1b51eSKate Stone return (m_index != UINT32_MAX || m_tid != LLDB_INVALID_THREAD_ID || 130b9c1b51eSKate Stone !m_name.empty() || !m_queue_name.empty()); 1310136309fSJim Ingham } 132e65b2cf2SEugene Zelenko 133b9c1b51eSKate Stone void ThreadSpec::GetDescription(Stream *s, lldb::DescriptionLevel level) const { 134b9c1b51eSKate Stone if (!HasSpecification()) { 135b9c1b51eSKate Stone if (level == eDescriptionLevelBrief) { 1360136309fSJim Ingham s->PutCString("thread spec: no "); 1370136309fSJim Ingham } 138b9c1b51eSKate Stone } else { 139b9c1b51eSKate Stone if (level == eDescriptionLevelBrief) { 1400136309fSJim Ingham s->PutCString("thread spec: yes "); 141b9c1b51eSKate Stone } else { 1420136309fSJim Ingham if (GetTID() != LLDB_INVALID_THREAD_ID) 143d01b2953SDaniel Malea s->Printf("tid: 0x%" PRIx64 " ", GetTID()); 1440136309fSJim Ingham 145bdf4c6acSGreg Clayton if (GetIndex() != UINT32_MAX) 1460136309fSJim Ingham s->Printf("index: %d ", GetIndex()); 1470136309fSJim Ingham 1480136309fSJim Ingham const char *name = GetName(); 1490136309fSJim Ingham if (name) 1500136309fSJim Ingham s->Printf("thread name: \"%s\" ", name); 1510136309fSJim Ingham 1520136309fSJim Ingham const char *queue_name = GetQueueName(); 1530136309fSJim Ingham if (queue_name) 1540136309fSJim Ingham s->Printf("queue name: \"%s\" ", queue_name); 1550136309fSJim Ingham } 1560136309fSJim Ingham } 1570136309fSJim Ingham } 158