1 //===-- ThreadSpec.cpp ----------------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 #include "lldb/Target/ThreadSpec.h"
10 #include "lldb/Target/Thread.h"
11 #include "lldb/Utility/StructuredData.h"
14 using namespace lldb_private
;
16 const char *ThreadSpec::g_option_names
[static_cast<uint32_t>(
17 ThreadSpec::OptionNames::LastOptionName
)]{"Index", "ID", "Name",
20 ThreadSpec::ThreadSpec() : m_name(), m_queue_name() {}
22 std::unique_ptr
<ThreadSpec
> ThreadSpec::CreateFromStructuredData(
23 const StructuredData::Dictionary
&spec_dict
, Status
&error
) {
24 uint32_t index
= UINT32_MAX
;
25 lldb::tid_t tid
= LLDB_INVALID_THREAD_ID
;
27 llvm::StringRef queue_name
;
29 std::unique_ptr
<ThreadSpec
> thread_spec_up(new ThreadSpec());
30 bool success
= spec_dict
.GetValueForKeyAsInteger(
31 GetKey(OptionNames::ThreadIndex
), index
);
33 thread_spec_up
->SetIndex(index
);
36 spec_dict
.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID
), tid
);
38 thread_spec_up
->SetTID(tid
);
41 spec_dict
.GetValueForKeyAsString(GetKey(OptionNames::ThreadName
), name
);
43 thread_spec_up
->SetName(name
);
45 success
= spec_dict
.GetValueForKeyAsString(GetKey(OptionNames::ThreadName
),
48 thread_spec_up
->SetQueueName(queue_name
);
50 return thread_spec_up
;
53 StructuredData::ObjectSP
ThreadSpec::SerializeToStructuredData() {
54 StructuredData::DictionarySP
data_dict_sp(new StructuredData::Dictionary());
56 if (m_index
!= UINT32_MAX
)
57 data_dict_sp
->AddIntegerItem(GetKey(OptionNames::ThreadIndex
), m_index
);
58 if (m_tid
!= LLDB_INVALID_THREAD_ID
)
59 data_dict_sp
->AddIntegerItem(GetKey(OptionNames::ThreadID
), m_tid
);
61 data_dict_sp
->AddStringItem(GetKey(OptionNames::ThreadName
), m_name
);
62 if (!m_queue_name
.empty())
63 data_dict_sp
->AddStringItem(GetKey(OptionNames::QueueName
), m_queue_name
);
68 const char *ThreadSpec::GetName() const {
69 return m_name
.empty() ? nullptr : m_name
.c_str();
72 const char *ThreadSpec::GetQueueName() const {
73 return m_queue_name
.empty() ? nullptr : m_queue_name
.c_str();
76 bool ThreadSpec::TIDMatches(Thread
&thread
) const {
77 if (m_tid
== LLDB_INVALID_THREAD_ID
)
80 lldb::tid_t thread_id
= thread
.GetID();
81 return TIDMatches(thread_id
);
84 bool ThreadSpec::IndexMatches(Thread
&thread
) const {
85 if (m_index
== UINT32_MAX
)
87 uint32_t index
= thread
.GetIndexID();
88 return IndexMatches(index
);
91 bool ThreadSpec::NameMatches(Thread
&thread
) const {
95 const char *name
= thread
.GetName();
96 return NameMatches(name
);
99 bool ThreadSpec::QueueNameMatches(Thread
&thread
) const {
100 if (m_queue_name
.empty())
103 const char *queue_name
= thread
.GetQueueName();
104 return QueueNameMatches(queue_name
);
107 bool ThreadSpec::ThreadPassesBasicTests(Thread
&thread
) const {
108 if (!HasSpecification())
111 if (!TIDMatches(thread
))
114 if (!IndexMatches(thread
))
117 if (!NameMatches(thread
))
120 if (!QueueNameMatches(thread
))
126 bool ThreadSpec::HasSpecification() const {
127 return (m_index
!= UINT32_MAX
|| m_tid
!= LLDB_INVALID_THREAD_ID
||
128 !m_name
.empty() || !m_queue_name
.empty());
131 void ThreadSpec::GetDescription(Stream
*s
, lldb::DescriptionLevel level
) const {
132 if (!HasSpecification()) {
133 if (level
== eDescriptionLevelBrief
) {
134 s
->PutCString("thread spec: no ");
137 if (level
== eDescriptionLevelBrief
) {
138 s
->PutCString("thread spec: yes ");
140 if (GetTID() != LLDB_INVALID_THREAD_ID
)
141 s
->Printf("tid: 0x%" PRIx64
" ", GetTID());
143 if (GetIndex() != UINT32_MAX
)
144 s
->Printf("index: %d ", GetIndex());
146 const char *name
= GetName();
148 s
->Printf("thread name: \"%s\" ", name
);
150 const char *queue_name
= GetQueueName();
152 s
->Printf("queue name: \"%s\" ", queue_name
);