]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/API/SBQueue.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / API / SBQueue.cpp
1 //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9
10 #include <inttypes.h>
11
12 #include "lldb/API/SBQueue.h"
13
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBQueueItem.h"
16 #include "lldb/API/SBThread.h"
17
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Queue.h"
20 #include "lldb/Target/QueueItem.h"
21 #include "lldb/Target/Thread.h"
22 #include "lldb/Utility/Log.h"
23
24 using namespace lldb;
25 using namespace lldb_private;
26
27 namespace lldb_private {
28
29 class QueueImpl {
30 public:
31   QueueImpl()
32       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
33         m_pending_items(), m_pending_items_fetched(false) {}
34
35   QueueImpl(const lldb::QueueSP &queue_sp)
36       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
37         m_pending_items(), m_pending_items_fetched(false) {
38     m_queue_wp = queue_sp;
39   }
40
41   QueueImpl(const QueueImpl &rhs) {
42     if (&rhs == this)
43       return;
44     m_queue_wp = rhs.m_queue_wp;
45     m_threads = rhs.m_threads;
46     m_thread_list_fetched = rhs.m_thread_list_fetched;
47     m_pending_items = rhs.m_pending_items;
48     m_pending_items_fetched = rhs.m_pending_items_fetched;
49   }
50
51   ~QueueImpl() {}
52
53   bool IsValid() { return m_queue_wp.lock() != NULL; }
54
55   void Clear() {
56     m_queue_wp.reset();
57     m_thread_list_fetched = false;
58     m_threads.clear();
59     m_pending_items_fetched = false;
60     m_pending_items.clear();
61   }
62
63   void SetQueue(const lldb::QueueSP &queue_sp) {
64     Clear();
65     m_queue_wp = queue_sp;
66   }
67
68   lldb::queue_id_t GetQueueID() const {
69     lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
70     lldb::QueueSP queue_sp = m_queue_wp.lock();
71     if (queue_sp) {
72       result = queue_sp->GetID();
73     }
74     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
75     if (log)
76       log->Printf("SBQueue(%p)::GetQueueID () => 0x%" PRIx64,
77                   static_cast<const void *>(this), result);
78     return result;
79   }
80
81   uint32_t GetIndexID() const {
82     uint32_t result = LLDB_INVALID_INDEX32;
83     lldb::QueueSP queue_sp = m_queue_wp.lock();
84     if (queue_sp) {
85       result = queue_sp->GetIndexID();
86     }
87     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
88     if (log)
89       log->Printf("SBQueueImpl(%p)::GetIndexID () => %d",
90                   static_cast<const void *>(this), result);
91     return result;
92   }
93
94   const char *GetName() const {
95     const char *name = NULL;
96     lldb::QueueSP queue_sp = m_queue_wp.lock();
97     if (queue_sp.get()) {
98       name = queue_sp->GetName();
99     }
100
101     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
102     if (log)
103       log->Printf("SBQueueImpl(%p)::GetName () => %s",
104                   static_cast<const void *>(this), name ? name : "NULL");
105
106     return name;
107   }
108
109   void FetchThreads() {
110     if (!m_thread_list_fetched) {
111       lldb::QueueSP queue_sp = m_queue_wp.lock();
112       if (queue_sp) {
113         Process::StopLocker stop_locker;
114         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
115           const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
116           m_thread_list_fetched = true;
117           const uint32_t num_threads = thread_list.size();
118           for (uint32_t idx = 0; idx < num_threads; ++idx) {
119             ThreadSP thread_sp = thread_list[idx];
120             if (thread_sp && thread_sp->IsValid()) {
121               m_threads.push_back(thread_sp);
122             }
123           }
124         }
125       }
126     }
127   }
128
129   void FetchItems() {
130     if (!m_pending_items_fetched) {
131       QueueSP queue_sp = m_queue_wp.lock();
132       if (queue_sp) {
133         Process::StopLocker stop_locker;
134         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
135           const std::vector<QueueItemSP> queue_items(
136               queue_sp->GetPendingItems());
137           m_pending_items_fetched = true;
138           const uint32_t num_pending_items = queue_items.size();
139           for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
140             QueueItemSP item = queue_items[idx];
141             if (item && item->IsValid()) {
142               m_pending_items.push_back(item);
143             }
144           }
145         }
146       }
147     }
148   }
149
150   uint32_t GetNumThreads() {
151     uint32_t result = 0;
152
153     FetchThreads();
154     if (m_thread_list_fetched) {
155       result = m_threads.size();
156     }
157     return result;
158   }
159
160   lldb::SBThread GetThreadAtIndex(uint32_t idx) {
161     FetchThreads();
162
163     SBThread sb_thread;
164     QueueSP queue_sp = m_queue_wp.lock();
165     if (queue_sp && idx < m_threads.size()) {
166       ProcessSP process_sp = queue_sp->GetProcess();
167       if (process_sp) {
168         ThreadSP thread_sp = m_threads[idx].lock();
169         if (thread_sp) {
170           sb_thread.SetThread(thread_sp);
171         }
172       }
173     }
174     return sb_thread;
175   }
176
177   uint32_t GetNumPendingItems() {
178     uint32_t result = 0;
179
180     QueueSP queue_sp = m_queue_wp.lock();
181     if (!m_pending_items_fetched && queue_sp) {
182       result = queue_sp->GetNumPendingWorkItems();
183     } else {
184       result = m_pending_items.size();
185     }
186     return result;
187   }
188
189   lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
190     SBQueueItem result;
191     FetchItems();
192     if (m_pending_items_fetched && idx < m_pending_items.size()) {
193       result.SetQueueItem(m_pending_items[idx]);
194     }
195     return result;
196   }
197
198   uint32_t GetNumRunningItems() {
199     uint32_t result = 0;
200     QueueSP queue_sp = m_queue_wp.lock();
201     if (queue_sp)
202       result = queue_sp->GetNumRunningWorkItems();
203     return result;
204   }
205
206   lldb::SBProcess GetProcess() {
207     SBProcess result;
208     QueueSP queue_sp = m_queue_wp.lock();
209     if (queue_sp) {
210       result.SetSP(queue_sp->GetProcess());
211     }
212     return result;
213   }
214
215   lldb::QueueKind GetKind() {
216     lldb::QueueKind kind = eQueueKindUnknown;
217     QueueSP queue_sp = m_queue_wp.lock();
218     if (queue_sp)
219       kind = queue_sp->GetKind();
220
221     return kind;
222   }
223
224 private:
225   lldb::QueueWP m_queue_wp;
226   std::vector<lldb::ThreadWP>
227       m_threads; // threads currently executing this queue's items
228   bool
229       m_thread_list_fetched; // have we tried to fetch the threads list already?
230   std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
231   bool m_pending_items_fetched; // have we tried to fetch the item list already?
232 };
233 }
234
235 SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {}
236
237 SBQueue::SBQueue(const QueueSP &queue_sp)
238     : m_opaque_sp(new QueueImpl(queue_sp)) {}
239
240 SBQueue::SBQueue(const SBQueue &rhs) {
241   if (&rhs == this)
242     return;
243
244   m_opaque_sp = rhs.m_opaque_sp;
245 }
246
247 const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
248   m_opaque_sp = rhs.m_opaque_sp;
249   return *this;
250 }
251
252 SBQueue::~SBQueue() {}
253
254 bool SBQueue::IsValid() const {
255   bool is_valid = m_opaque_sp->IsValid();
256   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
257   if (log)
258     log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s",
259                 m_opaque_sp->GetQueueID(), is_valid ? "true" : "false");
260   return is_valid;
261 }
262
263 void SBQueue::Clear() {
264   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
265   if (log)
266     log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID());
267   m_opaque_sp->Clear();
268 }
269
270 void SBQueue::SetQueue(const QueueSP &queue_sp) {
271   m_opaque_sp->SetQueue(queue_sp);
272 }
273
274 lldb::queue_id_t SBQueue::GetQueueID() const {
275   lldb::queue_id_t qid = m_opaque_sp->GetQueueID();
276   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
277   if (log)
278     log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64,
279                 m_opaque_sp->GetQueueID(), (uint64_t)qid);
280   return qid;
281 }
282
283 uint32_t SBQueue::GetIndexID() const {
284   uint32_t index_id = m_opaque_sp->GetIndexID();
285   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
286   if (log)
287     log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32,
288                 m_opaque_sp->GetQueueID(), index_id);
289   return index_id;
290 }
291
292 const char *SBQueue::GetName() const {
293   const char *name = m_opaque_sp->GetName();
294   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
295   if (log)
296     log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s",
297                 m_opaque_sp->GetQueueID(), name ? name : "");
298   return name;
299 }
300
301 uint32_t SBQueue::GetNumThreads() {
302   uint32_t numthreads = m_opaque_sp->GetNumThreads();
303   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
304   if (log)
305     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d",
306                 m_opaque_sp->GetQueueID(), numthreads);
307   return numthreads;
308 }
309
310 SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
311   SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
312   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
313   if (log)
314     log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)",
315                 m_opaque_sp->GetQueueID(), idx);
316   return th;
317 }
318
319 uint32_t SBQueue::GetNumPendingItems() {
320   uint32_t pending_items = m_opaque_sp->GetNumPendingItems();
321   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
322   if (log)
323     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d",
324                 m_opaque_sp->GetQueueID(), pending_items);
325   return pending_items;
326 }
327
328 SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
329   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
330   if (log)
331     log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)",
332                 m_opaque_sp->GetQueueID(), idx);
333   return m_opaque_sp->GetPendingItemAtIndex(idx);
334 }
335
336 uint32_t SBQueue::GetNumRunningItems() {
337   uint32_t running_items = m_opaque_sp->GetNumRunningItems();
338   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
339   if (log)
340     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d",
341                 m_opaque_sp->GetQueueID(), running_items);
342   return running_items;
343 }
344
345 SBProcess SBQueue::GetProcess() { return m_opaque_sp->GetProcess(); }
346
347 lldb::QueueKind SBQueue::GetKind() { return m_opaque_sp->GetKind(); }