xref: /src/contrib/llvm-project/lldb/source/Target/ThreadSpec.cpp (revision fe6060f10f634930ff71b7c50291ddc610da2475)
1cfca06d7SDimitry Andric //===-- ThreadSpec.cpp ----------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8f034231aSEd Maste 
9f034231aSEd Maste #include "lldb/Target/ThreadSpec.h"
101b306c26SDimitry Andric #include "lldb/Target/Thread.h"
111b306c26SDimitry Andric #include "lldb/Utility/StructuredData.h"
12f034231aSEd Maste 
13f034231aSEd Maste using namespace lldb;
14f034231aSEd Maste using namespace lldb_private;
15f034231aSEd Maste 
1614f1b3e8SDimitry Andric const char *ThreadSpec::g_option_names[static_cast<uint32_t>(
1714f1b3e8SDimitry Andric     ThreadSpec::OptionNames::LastOptionName)]{"Index", "ID", "Name",
1814f1b3e8SDimitry Andric                                               "QueueName"};
19f034231aSEd Maste 
ThreadSpec()20344a3780SDimitry Andric ThreadSpec::ThreadSpec() : m_name(), m_queue_name() {}
21f034231aSEd Maste 
CreateFromStructuredData(const StructuredData::Dictionary & spec_dict,Status & error)2214f1b3e8SDimitry Andric std::unique_ptr<ThreadSpec> ThreadSpec::CreateFromStructuredData(
23b76161e4SDimitry Andric     const StructuredData::Dictionary &spec_dict, Status &error) {
2414f1b3e8SDimitry Andric   uint32_t index = UINT32_MAX;
2514f1b3e8SDimitry Andric   lldb::tid_t tid = LLDB_INVALID_THREAD_ID;
26b76161e4SDimitry Andric   llvm::StringRef name;
27b76161e4SDimitry Andric   llvm::StringRef queue_name;
2814f1b3e8SDimitry Andric 
2914f1b3e8SDimitry Andric   std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec());
3014f1b3e8SDimitry Andric   bool success = spec_dict.GetValueForKeyAsInteger(
3114f1b3e8SDimitry Andric       GetKey(OptionNames::ThreadIndex), index);
3214f1b3e8SDimitry Andric   if (success)
3314f1b3e8SDimitry Andric     thread_spec_up->SetIndex(index);
3414f1b3e8SDimitry Andric 
3514f1b3e8SDimitry Andric   success =
3614f1b3e8SDimitry Andric       spec_dict.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID), tid);
3714f1b3e8SDimitry Andric   if (success)
3814f1b3e8SDimitry Andric     thread_spec_up->SetTID(tid);
3914f1b3e8SDimitry Andric 
4014f1b3e8SDimitry Andric   success =
4114f1b3e8SDimitry Andric       spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name);
4214f1b3e8SDimitry Andric   if (success)
43b76161e4SDimitry Andric     thread_spec_up->SetName(name);
4414f1b3e8SDimitry Andric 
4514f1b3e8SDimitry Andric   success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName),
4614f1b3e8SDimitry Andric                                              queue_name);
4714f1b3e8SDimitry Andric   if (success)
48b76161e4SDimitry Andric     thread_spec_up->SetQueueName(queue_name);
4914f1b3e8SDimitry Andric 
5014f1b3e8SDimitry Andric   return thread_spec_up;
5114f1b3e8SDimitry Andric }
5214f1b3e8SDimitry Andric 
SerializeToStructuredData()5314f1b3e8SDimitry Andric StructuredData::ObjectSP ThreadSpec::SerializeToStructuredData() {
5414f1b3e8SDimitry Andric   StructuredData::DictionarySP data_dict_sp(new StructuredData::Dictionary());
5514f1b3e8SDimitry Andric 
5614f1b3e8SDimitry Andric   if (m_index != UINT32_MAX)
5714f1b3e8SDimitry Andric     data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadIndex), m_index);
5814f1b3e8SDimitry Andric   if (m_tid != LLDB_INVALID_THREAD_ID)
5914f1b3e8SDimitry Andric     data_dict_sp->AddIntegerItem(GetKey(OptionNames::ThreadID), m_tid);
6014f1b3e8SDimitry Andric   if (!m_name.empty())
6114f1b3e8SDimitry Andric     data_dict_sp->AddStringItem(GetKey(OptionNames::ThreadName), m_name);
6214f1b3e8SDimitry Andric   if (!m_queue_name.empty())
6314f1b3e8SDimitry Andric     data_dict_sp->AddStringItem(GetKey(OptionNames::QueueName), m_queue_name);
6414f1b3e8SDimitry Andric 
6514f1b3e8SDimitry Andric   return data_dict_sp;
6614f1b3e8SDimitry Andric }
6714f1b3e8SDimitry Andric 
GetName() const6814f1b3e8SDimitry Andric const char *ThreadSpec::GetName() const {
69e81d9d49SDimitry Andric   return m_name.empty() ? nullptr : m_name.c_str();
70f034231aSEd Maste }
71f034231aSEd Maste 
GetQueueName() const7214f1b3e8SDimitry Andric const char *ThreadSpec::GetQueueName() const {
73e81d9d49SDimitry Andric   return m_queue_name.empty() ? nullptr : m_queue_name.c_str();
74f034231aSEd Maste }
75f034231aSEd Maste 
TIDMatches(Thread & thread) const7614f1b3e8SDimitry Andric bool ThreadSpec::TIDMatches(Thread &thread) const {
77f034231aSEd Maste   if (m_tid == LLDB_INVALID_THREAD_ID)
78f034231aSEd Maste     return true;
79f034231aSEd Maste 
80f034231aSEd Maste   lldb::tid_t thread_id = thread.GetID();
81f034231aSEd Maste   return TIDMatches(thread_id);
82f034231aSEd Maste }
83e81d9d49SDimitry Andric 
IndexMatches(Thread & thread) const8414f1b3e8SDimitry Andric bool ThreadSpec::IndexMatches(Thread &thread) const {
85f034231aSEd Maste   if (m_index == UINT32_MAX)
86f034231aSEd Maste     return true;
87f034231aSEd Maste   uint32_t index = thread.GetIndexID();
88f034231aSEd Maste   return IndexMatches(index);
89f034231aSEd Maste }
90e81d9d49SDimitry Andric 
NameMatches(Thread & thread) const9114f1b3e8SDimitry Andric bool ThreadSpec::NameMatches(Thread &thread) const {
92f034231aSEd Maste   if (m_name.empty())
93f034231aSEd Maste     return true;
94f034231aSEd Maste 
95f034231aSEd Maste   const char *name = thread.GetName();
96f034231aSEd Maste   return NameMatches(name);
97f034231aSEd Maste }
98e81d9d49SDimitry Andric 
QueueNameMatches(Thread & thread) const9914f1b3e8SDimitry Andric bool ThreadSpec::QueueNameMatches(Thread &thread) const {
100f034231aSEd Maste   if (m_queue_name.empty())
101f034231aSEd Maste     return true;
102f034231aSEd Maste 
103f034231aSEd Maste   const char *queue_name = thread.GetQueueName();
104f034231aSEd Maste   return QueueNameMatches(queue_name);
105f034231aSEd Maste }
106f034231aSEd Maste 
ThreadPassesBasicTests(Thread & thread) const10714f1b3e8SDimitry Andric bool ThreadSpec::ThreadPassesBasicTests(Thread &thread) const {
108f034231aSEd Maste   if (!HasSpecification())
109f034231aSEd Maste     return true;
110f034231aSEd Maste 
111f034231aSEd Maste   if (!TIDMatches(thread))
112f034231aSEd Maste     return false;
113f034231aSEd Maste 
114f034231aSEd Maste   if (!IndexMatches(thread))
115f034231aSEd Maste     return false;
116f034231aSEd Maste 
117f034231aSEd Maste   if (!NameMatches(thread))
118f034231aSEd Maste     return false;
119f034231aSEd Maste 
120f034231aSEd Maste   if (!QueueNameMatches(thread))
121f034231aSEd Maste     return false;
122f034231aSEd Maste 
123f034231aSEd Maste   return true;
124f034231aSEd Maste }
125f034231aSEd Maste 
HasSpecification() const12614f1b3e8SDimitry Andric bool ThreadSpec::HasSpecification() const {
12714f1b3e8SDimitry Andric   return (m_index != UINT32_MAX || m_tid != LLDB_INVALID_THREAD_ID ||
12814f1b3e8SDimitry Andric           !m_name.empty() || !m_queue_name.empty());
129f034231aSEd Maste }
130e81d9d49SDimitry Andric 
GetDescription(Stream * s,lldb::DescriptionLevel level) const13114f1b3e8SDimitry Andric void ThreadSpec::GetDescription(Stream *s, lldb::DescriptionLevel level) const {
13214f1b3e8SDimitry Andric   if (!HasSpecification()) {
13314f1b3e8SDimitry Andric     if (level == eDescriptionLevelBrief) {
134f034231aSEd Maste       s->PutCString("thread spec: no ");
135f034231aSEd Maste     }
13614f1b3e8SDimitry Andric   } else {
13714f1b3e8SDimitry Andric     if (level == eDescriptionLevelBrief) {
138f034231aSEd Maste       s->PutCString("thread spec: yes ");
13914f1b3e8SDimitry Andric     } else {
140f034231aSEd Maste       if (GetTID() != LLDB_INVALID_THREAD_ID)
141f034231aSEd Maste         s->Printf("tid: 0x%" PRIx64 " ", GetTID());
142f034231aSEd Maste 
143f034231aSEd Maste       if (GetIndex() != UINT32_MAX)
144f034231aSEd Maste         s->Printf("index: %d ", GetIndex());
145f034231aSEd Maste 
146f034231aSEd Maste       const char *name = GetName();
147f034231aSEd Maste       if (name)
148f034231aSEd Maste         s->Printf("thread name: \"%s\" ", name);
149f034231aSEd Maste 
150f034231aSEd Maste       const char *queue_name = GetQueueName();
151f034231aSEd Maste       if (queue_name)
152f034231aSEd Maste         s->Printf("queue name: \"%s\" ", queue_name);
153f034231aSEd Maste     }
154f034231aSEd Maste   }
155f034231aSEd Maste }
156