Coverage Report

Created: 2023-11-11 10:31

/Users/buildslave/jenkins/workspace/coverage/llvm-project/lldb/source/API/SBQueue.cpp
Line
Count
Source (jump to first uncovered line)
1
//===-- SBQueue.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-exception
6
//
7
//===----------------------------------------------------------------------===//
8
9
#include <cinttypes>
10
11
#include "lldb/API/SBQueue.h"
12
#include "lldb/Utility/Instrumentation.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
23
using namespace lldb;
24
using namespace lldb_private;
25
26
namespace lldb_private {
27
28
class QueueImpl {
29
public:
30
154
  QueueImpl() = default;
31
32
0
  QueueImpl(const lldb::QueueSP &queue_sp) { m_queue_wp = queue_sp; }
33
34
0
  QueueImpl(const QueueImpl &rhs) {
35
0
    if (&rhs == this)
36
0
      return;
37
0
    m_queue_wp = rhs.m_queue_wp;
38
0
    m_threads = rhs.m_threads;
39
0
    m_thread_list_fetched = rhs.m_thread_list_fetched;
40
0
    m_pending_items = rhs.m_pending_items;
41
0
    m_pending_items_fetched = rhs.m_pending_items_fetched;
42
0
  }
43
44
154
  ~QueueImpl() = default;
45
46
18
  bool IsValid() { return m_queue_wp.lock() != nullptr; }
47
48
72
  void Clear() {
49
72
    m_queue_wp.reset();
50
72
    m_thread_list_fetched = false;
51
72
    m_threads.clear();
52
72
    m_pending_items_fetched = false;
53
72
    m_pending_items.clear();
54
72
  }
55
56
72
  void SetQueue(const lldb::QueueSP &queue_sp) {
57
72
    Clear();
58
72
    m_queue_wp = queue_sp;
59
72
  }
60
61
100
  lldb::queue_id_t GetQueueID() const {
62
100
    lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
63
100
    lldb::QueueSP queue_sp = m_queue_wp.lock();
64
100
    if (queue_sp) {
65
100
      result = queue_sp->GetID();
66
100
    }
67
100
    return result;
68
100
  }
69
70
0
  uint32_t GetIndexID() const {
71
0
    uint32_t result = LLDB_INVALID_INDEX32;
72
0
    lldb::QueueSP queue_sp = m_queue_wp.lock();
73
0
    if (queue_sp) {
74
0
      result = queue_sp->GetIndexID();
75
0
    }
76
0
    return result;
77
0
  }
78
79
206
  const char *GetName() const {
80
206
    lldb::QueueSP queue_sp = m_queue_wp.lock();
81
206
    if (!queue_sp)
82
0
      return nullptr;
83
206
    return ConstString(queue_sp->GetName()).GetCString();
84
206
  }
85
86
50
  void FetchThreads() {
87
50
    if (!m_thread_list_fetched) {
88
12
      lldb::QueueSP queue_sp = m_queue_wp.lock();
89
12
      if (queue_sp) {
90
12
        Process::StopLocker stop_locker;
91
12
        if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
92
12
          const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
93
12
          m_thread_list_fetched = true;
94
12
          const uint32_t num_threads = thread_list.size();
95
30
          for (uint32_t idx = 0; idx < num_threads; 
++idx18
) {
96
18
            ThreadSP thread_sp = thread_list[idx];
97
18
            if (thread_sp && thread_sp->IsValid()) {
98
18
              m_threads.push_back(thread_sp);
99
18
            }
100
18
          }
101
12
        }
102
12
      }
103
12
    }
104
50
  }
105
106
0
  void FetchItems() {
107
0
    if (!m_pending_items_fetched) {
108
0
      QueueSP queue_sp = m_queue_wp.lock();
109
0
      if (queue_sp) {
110
0
        Process::StopLocker stop_locker;
111
0
        if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
112
0
          const std::vector<QueueItemSP> queue_items(
113
0
              queue_sp->GetPendingItems());
114
0
          m_pending_items_fetched = true;
115
0
          const uint32_t num_pending_items = queue_items.size();
116
0
          for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
117
0
            QueueItemSP item = queue_items[idx];
118
0
            if (item && item->IsValid()) {
119
0
              m_pending_items.push_back(item);
120
0
            }
121
0
          }
122
0
        }
123
0
      }
124
0
    }
125
0
  }
126
127
32
  uint32_t GetNumThreads() {
128
32
    uint32_t result = 0;
129
130
32
    FetchThreads();
131
32
    if (m_thread_list_fetched) {
132
32
      result = m_threads.size();
133
32
    }
134
32
    return result;
135
32
  }
136
137
18
  lldb::SBThread GetThreadAtIndex(uint32_t idx) {
138
18
    FetchThreads();
139
140
18
    SBThread sb_thread;
141
18
    QueueSP queue_sp = m_queue_wp.lock();
142
18
    if (queue_sp && idx < m_threads.size()) {
143
18
      ProcessSP process_sp = queue_sp->GetProcess();
144
18
      if (process_sp) {
145
18
        ThreadSP thread_sp = m_threads[idx].lock();
146
18
        if (thread_sp) {
147
18
          sb_thread.SetThread(thread_sp);
148
18
        }
149
18
      }
150
18
    }
151
18
    return sb_thread;
152
18
  }
153
154
0
  uint32_t GetNumPendingItems() {
155
0
    uint32_t result = 0;
156
157
0
    QueueSP queue_sp = m_queue_wp.lock();
158
0
    if (!m_pending_items_fetched && queue_sp) {
159
0
      result = queue_sp->GetNumPendingWorkItems();
160
0
    } else {
161
0
      result = m_pending_items.size();
162
0
    }
163
0
    return result;
164
0
  }
165
166
0
  lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
167
0
    SBQueueItem result;
168
0
    FetchItems();
169
0
    if (m_pending_items_fetched && idx < m_pending_items.size()) {
170
0
      result.SetQueueItem(m_pending_items[idx]);
171
0
    }
172
0
    return result;
173
0
  }
174
175
0
  uint32_t GetNumRunningItems() {
176
0
    uint32_t result = 0;
177
0
    QueueSP queue_sp = m_queue_wp.lock();
178
0
    if (queue_sp)
179
0
      result = queue_sp->GetNumRunningWorkItems();
180
0
    return result;
181
0
  }
182
183
0
  lldb::SBProcess GetProcess() {
184
0
    SBProcess result;
185
0
    QueueSP queue_sp = m_queue_wp.lock();
186
0
    if (queue_sp) {
187
0
      result.SetSP(queue_sp->GetProcess());
188
0
    }
189
0
    return result;
190
0
  }
191
192
24
  lldb::QueueKind GetKind() {
193
24
    lldb::QueueKind kind = eQueueKindUnknown;
194
24
    QueueSP queue_sp = m_queue_wp.lock();
195
24
    if (queue_sp)
196
24
      kind = queue_sp->GetKind();
197
198
24
    return kind;
199
24
  }
200
201
private:
202
  lldb::QueueWP m_queue_wp;
203
  std::vector<lldb::ThreadWP>
204
      m_threads; // threads currently executing this queue's items
205
  bool m_thread_list_fetched =
206
      false; // have we tried to fetch the threads list already?
207
  std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
208
  bool m_pending_items_fetched =
209
      false; // have we tried to fetch the item list already?
210
};
211
}
212
213
154
SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { LLDB_INSTRUMENT_VA(this); }
214
215
SBQueue::SBQueue(const QueueSP &queue_sp)
216
0
    : m_opaque_sp(new QueueImpl(queue_sp)) {
217
0
  LLDB_INSTRUMENT_VA(this, queue_sp);
218
0
}
219
220
72
SBQueue::SBQueue(const SBQueue &rhs) {
221
72
  LLDB_INSTRUMENT_VA(this, rhs);
222
223
72
  if (&rhs == this)
224
0
    return;
225
226
72
  m_opaque_sp = rhs.m_opaque_sp;
227
72
}
228
229
72
const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
230
72
  LLDB_INSTRUMENT_VA(this, rhs);
231
232
72
  m_opaque_sp = rhs.m_opaque_sp;
233
72
  return *this;
234
72
}
235
236
226
SBQueue::~SBQueue() = default;
237
238
18
bool SBQueue::IsValid() const {
239
18
  LLDB_INSTRUMENT_VA(this);
240
18
  return this->operator bool();
241
18
}
242
18
SBQueue::operator bool() const {
243
18
  LLDB_INSTRUMENT_VA(this);
244
245
18
  return m_opaque_sp->IsValid();
246
18
}
247
248
0
void SBQueue::Clear() {
249
0
  LLDB_INSTRUMENT_VA(this);
250
251
0
  m_opaque_sp->Clear();
252
0
}
253
254
72
void SBQueue::SetQueue(const QueueSP &queue_sp) {
255
72
  m_opaque_sp->SetQueue(queue_sp);
256
72
}
257
258
100
lldb::queue_id_t SBQueue::GetQueueID() const {
259
100
  LLDB_INSTRUMENT_VA(this);
260
261
100
  return m_opaque_sp->GetQueueID();
262
100
}
263
264
0
uint32_t SBQueue::GetIndexID() const {
265
0
  LLDB_INSTRUMENT_VA(this);
266
267
0
  uint32_t index_id = m_opaque_sp->GetIndexID();
268
0
  return index_id;
269
0
}
270
271
206
const char *SBQueue::GetName() const {
272
206
  LLDB_INSTRUMENT_VA(this);
273
274
206
  return m_opaque_sp->GetName();
275
206
}
276
277
32
uint32_t SBQueue::GetNumThreads() {
278
32
  LLDB_INSTRUMENT_VA(this);
279
280
32
  return m_opaque_sp->GetNumThreads();
281
32
}
282
283
18
SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
284
18
  LLDB_INSTRUMENT_VA(this, idx);
285
286
18
  SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
287
18
  return th;
288
18
}
289
290
0
uint32_t SBQueue::GetNumPendingItems() {
291
0
  LLDB_INSTRUMENT_VA(this);
292
293
0
  return m_opaque_sp->GetNumPendingItems();
294
0
}
295
296
0
SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
297
0
  LLDB_INSTRUMENT_VA(this, idx);
298
299
0
  return m_opaque_sp->GetPendingItemAtIndex(idx);
300
0
}
301
302
0
uint32_t SBQueue::GetNumRunningItems() {
303
0
  LLDB_INSTRUMENT_VA(this);
304
305
0
  return m_opaque_sp->GetNumRunningItems();
306
0
}
307
308
0
SBProcess SBQueue::GetProcess() {
309
0
  LLDB_INSTRUMENT_VA(this);
310
311
0
  return m_opaque_sp->GetProcess();
312
0
}
313
314
24
lldb::QueueKind SBQueue::GetKind() {
315
24
  LLDB_INSTRUMENT_VA(this);
316
317
24
  return m_opaque_sp->GetKind();
318
24
}