1 //===-- ThreadSpec.h --------------------------------------------*- C++ -*-===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #ifndef LLDB_TARGET_THREADSPEC_H
10 #define LLDB_TARGET_THREADSPEC_H
11 
12 #include "lldb/Utility/StructuredData.h"
13 #include "lldb/lldb-private.h"
14 #include <string>
15 
16 namespace lldb_private {
17 
18 // Note: For now the thread spec has only fixed elements -
19 //   Thread ID
20 //   Thread Index
21 //   Thread Name
22 //   Thread Queue Name
23 //
24 //  But if we need more generality, we can hang a key/value map off of this
25 //  structure.
26 //  That's why the thread matches spec test is done as a virtual method in
27 //  Thread::MatchesSpec,
28 //  since it is the native thread that would know how to interpret the keys.
29 //  I was going to do the Queue Name this way out of sheer orneriness, but that
30 //  seems a
31 //  sufficiently general concept, so I put it in here on its own.
32 
33 class ThreadSpec {
34 public:
35   ThreadSpec();
36 
37   static std::unique_ptr<ThreadSpec>
38   CreateFromStructuredData(const StructuredData::Dictionary &data_dict,
39                            Status &error);
40 
41   StructuredData::ObjectSP SerializeToStructuredData();
42 
43   static const char *GetSerializationKey() { return "ThreadSpec"; }
44 
45   void SetIndex(uint32_t index) { m_index = index; }
46 
47   void SetTID(lldb::tid_t tid) { m_tid = tid; }
48 
49   void SetName(llvm::StringRef name) { m_name = std::string(name); }
50 
51   void SetQueueName(llvm::StringRef queue_name) {
52     m_queue_name = std::string(queue_name);
53   }
54 
55   uint32_t GetIndex() const { return m_index; }
56 
57   lldb::tid_t GetTID() const { return m_tid; }
58 
59   const char *GetName() const;
60 
61   const char *GetQueueName() const;
62 
63   bool TIDMatches(lldb::tid_t thread_id) const {
64     if (m_tid == LLDB_INVALID_THREAD_ID || thread_id == LLDB_INVALID_THREAD_ID)
65       return true;
66     else
67       return thread_id == m_tid;
68   }
69 
70   bool TIDMatches(Thread &thread) const;
71 
72   bool IndexMatches(uint32_t index) const {
73     if (m_index == UINT32_MAX || index == UINT32_MAX)
74       return true;
75     else
76       return index == m_index;
77   }
78 
79   bool IndexMatches(Thread &thread) const;
80 
81   bool NameMatches(const char *name) const {
82     if (m_name.empty())
83       return true;
84     else if (name == nullptr)
85       return false;
86     else
87       return m_name == name;
88   }
89 
90   bool NameMatches(Thread &thread) const;
91 
92   bool QueueNameMatches(const char *queue_name) const {
93     if (m_queue_name.empty())
94       return true;
95     else if (queue_name == nullptr)
96       return false;
97     else
98       return m_queue_name == queue_name;
99   }
100 
101   bool QueueNameMatches(Thread &thread) const;
102 
103   bool ThreadPassesBasicTests(Thread &thread) const;
104 
105   bool HasSpecification() const;
106 
107   void GetDescription(Stream *s, lldb::DescriptionLevel level) const;
108 
109 private:
110   enum class OptionNames {
111     ThreadIndex = 0,
112     ThreadID,
113     ThreadName,
114     QueueName,
115     LastOptionName
116   };
117   static const char *g_option_names[(size_t)OptionNames::LastOptionName];
118 
119   static const char *GetKey(OptionNames enum_value) {
120     return g_option_names[(size_t) enum_value];
121   }
122 
123   uint32_t m_index = UINT32_MAX;
124   lldb::tid_t m_tid = LLDB_INVALID_THREAD_ID;
125   std::string m_name;
126   std::string m_queue_name;
127 };
128 
129 } // namespace lldb_private
130 
131 #endif // LLDB_TARGET_THREADSPEC_H
132