156 lines · cpp
1//===-- ThreadSpec.cpp ----------------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8 9#include "lldb/Target/ThreadSpec.h"10#include "lldb/Target/Thread.h"11#include "lldb/Utility/StructuredData.h"12 13using namespace lldb;14using namespace lldb_private;15 16const char *ThreadSpec::g_option_names[static_cast<uint32_t>(17 ThreadSpec::OptionNames::LastOptionName)]{"Index", "ID", "Name",18 "QueueName"};19 20ThreadSpec::ThreadSpec() : m_name(), m_queue_name() {}21 22std::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;26 llvm::StringRef name;27 llvm::StringRef queue_name;28 29 std::unique_ptr<ThreadSpec> thread_spec_up(new ThreadSpec());30 bool success = spec_dict.GetValueForKeyAsInteger(31 GetKey(OptionNames::ThreadIndex), index);32 if (success)33 thread_spec_up->SetIndex(index);34 35 success =36 spec_dict.GetValueForKeyAsInteger(GetKey(OptionNames::ThreadID), tid);37 if (success)38 thread_spec_up->SetTID(tid);39 40 success =41 spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName), name);42 if (success)43 thread_spec_up->SetName(name);44 45 success = spec_dict.GetValueForKeyAsString(GetKey(OptionNames::ThreadName),46 queue_name);47 if (success)48 thread_spec_up->SetQueueName(queue_name);49 50 return thread_spec_up;51}52 53StructuredData::ObjectSP ThreadSpec::SerializeToStructuredData() {54 StructuredData::DictionarySP data_dict_sp(new StructuredData::Dictionary());55 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);60 if (!m_name.empty())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);64 65 return data_dict_sp;66}67 68const char *ThreadSpec::GetName() const {69 return m_name.empty() ? nullptr : m_name.c_str();70}71 72const char *ThreadSpec::GetQueueName() const {73 return m_queue_name.empty() ? nullptr : m_queue_name.c_str();74}75 76bool ThreadSpec::TIDMatches(Thread &thread) const {77 if (m_tid == LLDB_INVALID_THREAD_ID)78 return true;79 80 lldb::tid_t thread_id = thread.GetID();81 return TIDMatches(thread_id);82}83 84bool ThreadSpec::IndexMatches(Thread &thread) const {85 if (m_index == UINT32_MAX)86 return true;87 uint32_t index = thread.GetIndexID();88 return IndexMatches(index);89}90 91bool ThreadSpec::NameMatches(Thread &thread) const {92 if (m_name.empty())93 return true;94 95 const char *name = thread.GetName();96 return NameMatches(name);97}98 99bool ThreadSpec::QueueNameMatches(Thread &thread) const {100 if (m_queue_name.empty())101 return true;102 103 const char *queue_name = thread.GetQueueName();104 return QueueNameMatches(queue_name);105}106 107bool ThreadSpec::ThreadPassesBasicTests(Thread &thread) const {108 if (!HasSpecification())109 return true;110 111 if (!TIDMatches(thread))112 return false;113 114 if (!IndexMatches(thread))115 return false;116 117 if (!NameMatches(thread))118 return false;119 120 if (!QueueNameMatches(thread))121 return false;122 123 return true;124}125 126bool ThreadSpec::HasSpecification() const {127 return (m_index != UINT32_MAX || m_tid != LLDB_INVALID_THREAD_ID ||128 !m_name.empty() || !m_queue_name.empty());129}130 131void ThreadSpec::GetDescription(Stream *s, lldb::DescriptionLevel level) const {132 if (!HasSpecification()) {133 if (level == eDescriptionLevelBrief) {134 s->PutCString("thread spec: no ");135 }136 } else {137 if (level == eDescriptionLevelBrief) {138 s->PutCString("thread spec: yes ");139 } else {140 if (GetTID() != LLDB_INVALID_THREAD_ID)141 s->Printf("tid: 0x%" PRIx64 " ", GetTID());142 143 if (GetIndex() != UINT32_MAX)144 s->Printf("index: %d ", GetIndex());145 146 const char *name = GetName();147 if (name)148 s->Printf("thread name: \"%s\" ", name);149 150 const char *queue_name = GetQueueName();151 if (queue_name)152 s->Printf("queue name: \"%s\" ", queue_name);153 }154 }155}156