summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSean Callanan <scallanan@apple.com>2013-11-06 19:28:40 +0000
committerSean Callanan <scallanan@apple.com>2013-11-06 19:28:40 +0000
commit5c19eac1c8c95fa0e40fa71da664326d29dcaf18 (patch)
treea3620393bea2552d01d9014a2c1534cb4f644102
parent5fb3a13ba7523d3a93290bcfa033b835151c19aa (diff)
downloadbcm5719-llvm-5c19eac1c8c95fa0e40fa71da664326d29dcaf18.tar.gz
bcm5719-llvm-5c19eac1c8c95fa0e40fa71da664326d29dcaf18.zip
Added Iterable, a class that vends standard C++
iterators for LLDB's container data structures. Iterable abstracts over the backing data structure, ignoring keys for maps for example. It also provides locking as a service so that the code for (ThreadSP thread_sp : process->Threads()) { // ... use thread_sp } takes the appropriate locks once, without having to do anything else. The salient advantages of this system are: - Much simpler and idiomatic loop code - Lock once instead of each time an element is fetched - Less boilerplate to produce the iterators The intent is that Iterable will replace Get...AtIndex in most places, and that ForEach(), which solves the same problem in a less-idiomatic way, be phased out in favor of this approach. I've added Iterables to ThreadList, TypeList, and Process (which is really just forwarding to ThreadList). llvm-svn: 194159
-rw-r--r--lldb/include/lldb/Symbol/TypeList.h11
-rw-r--r--lldb/include/lldb/Target/Process.h6
-rw-r--r--lldb/include/lldb/Target/ThreadList.h11
-rw-r--r--lldb/include/lldb/Utility/Iterable.h225
-rw-r--r--lldb/source/Commands/CommandObjectTarget.cpp4
-rw-r--r--lldb/source/Commands/CommandObjectThread.cpp15
6 files changed, 259 insertions, 13 deletions
diff --git a/lldb/include/lldb/Symbol/TypeList.h b/lldb/include/lldb/Symbol/TypeList.h
index be7d35482da..4f3f2c9bdbe 100644
--- a/lldb/include/lldb/Symbol/TypeList.h
+++ b/lldb/include/lldb/Symbol/TypeList.h
@@ -12,6 +12,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Symbol/Type.h"
+#include "lldb/Utility/Iterable.h"
#include <map>
#include <functional>
@@ -51,6 +52,15 @@ public:
lldb::TypeSP
GetTypeAtIndex(uint32_t idx);
+
+ typedef std::multimap<lldb::user_id_t, lldb::TypeSP> collection;
+ typedef AdaptedIterable<collection, lldb::TypeSP, map_adapter> TypeIterable;
+
+ TypeIterable
+ Types ()
+ {
+ return TypeIterable(m_types);
+ }
void
ForEach (std::function <bool(const lldb::TypeSP &type_sp)> const &callback) const;
@@ -75,7 +85,6 @@ public:
RemoveMismatchedTypes (lldb::TypeClass type_class);
private:
- typedef std::multimap<lldb::user_id_t, lldb::TypeSP> collection;
typedef collection::iterator iterator;
typedef collection::const_iterator const_iterator;
diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h
index aa7b5edc5af..b55b8da1352 100644
--- a/lldb/include/lldb/Target/Process.h
+++ b/lldb/include/lldb/Target/Process.h
@@ -3305,6 +3305,12 @@ public:
return m_thread_list;
}
+ ThreadList::ThreadIterable
+ Threads ()
+ {
+ return m_thread_list.Threads();
+ }
+
uint32_t
GetNextThreadIndexID (uint64_t thread_id);
diff --git a/lldb/include/lldb/Target/ThreadList.h b/lldb/include/lldb/Target/ThreadList.h
index ddf49b002ec..f4dfdb23ec0 100644
--- a/lldb/include/lldb/Target/ThreadList.h
+++ b/lldb/include/lldb/Target/ThreadList.h
@@ -14,6 +14,7 @@
#include "lldb/lldb-private.h"
#include "lldb/Core/UserID.h"
+#include "lldb/Utility/Iterable.h"
// FIXME: Currently this is a thread list with lots of functionality for use only by
@@ -69,6 +70,15 @@ public:
// is a unique index assigned
lldb::ThreadSP
GetThreadAtIndex (uint32_t idx, bool can_update = true);
+
+ typedef std::vector<lldb::ThreadSP> collection;
+ typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter> ThreadIterable;
+
+ ThreadIterable
+ Threads ()
+ {
+ return ThreadIterable(m_threads, GetMutex());
+ }
lldb::ThreadSP
FindThreadByID (lldb::tid_t tid, bool can_update = true);
@@ -145,7 +155,6 @@ protected:
void
NotifySelectedThreadChanged (lldb::tid_t tid);
- typedef std::vector<lldb::ThreadSP> collection;
//------------------------------------------------------------------
// Classes that inherit from Process can see and modify these
//------------------------------------------------------------------
diff --git a/lldb/include/lldb/Utility/Iterable.h b/lldb/include/lldb/Utility/Iterable.h
new file mode 100644
index 00000000000..9b91cae37ee
--- /dev/null
+++ b/lldb/include/lldb/Utility/Iterable.h
@@ -0,0 +1,225 @@
+//===-- Iterable.h ----------------------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_Iterable_h_
+#define liblldb_Iterable_h_
+
+#include "lldb/Host/Mutex.h"
+
+namespace lldb_private
+{
+
+template <typename I, typename E> E map_adapter(I &iter)
+{
+ return iter->second;
+}
+
+template <typename I, typename E> E vector_adapter(I &iter)
+{
+ return *iter;
+}
+
+template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedConstIterator
+{
+public:
+ typedef typename C::const_iterator BackingIterator;
+private:
+ BackingIterator m_iter;
+public:
+ // Wrapping constructor
+ AdaptedConstIterator (BackingIterator backing_iterator) :
+ m_iter(backing_iterator)
+ {
+ }
+
+ // Default-constructible
+ AdaptedConstIterator () :
+ m_iter()
+ {
+ }
+
+ // Copy-constructible
+ AdaptedConstIterator (const AdaptedConstIterator &rhs) :
+ m_iter(rhs.m_iter)
+ {
+ }
+
+ // Copy-assignable
+ AdaptedConstIterator &operator= (const AdaptedConstIterator &rhs)
+ {
+ m_iter = rhs.m_iter;
+ return *this;
+ }
+
+ // Destructible
+ ~AdaptedConstIterator () { }
+
+ // Comparable
+ bool operator== (const AdaptedConstIterator &rhs)
+ {
+ return m_iter == rhs.m_iter;
+ }
+
+ bool operator!= (const AdaptedConstIterator &rhs)
+ {
+ return m_iter != rhs.m_iter;
+ }
+
+ // Rvalue dereferenceable
+ E operator* ()
+ {
+ return (*A)(m_iter);
+ }
+
+ E operator-> ()
+ {
+ return (*A)(m_iter);
+ }
+
+ // Offset dereferenceable
+ E operator[] (typename BackingIterator::difference_type offset)
+ {
+ return AdaptedConstIterator(m_iter + offset);
+ }
+
+ // Incrementable
+ AdaptedConstIterator &operator++ ()
+ {
+ m_iter++;
+ return *this;
+ }
+
+ // Decrementable
+ AdaptedConstIterator &operator-- ()
+ {
+ m_iter--;
+ return *this;
+ }
+
+ // Compound assignment
+ AdaptedConstIterator &operator+= (typename BackingIterator::difference_type offset)
+ {
+ m_iter += offset;
+ return *this;
+ }
+
+ AdaptedConstIterator &operator-= (typename BackingIterator::difference_type offset)
+ {
+ m_iter -= offset;
+ return *this;
+ }
+
+ // Arithmetic
+ AdaptedConstIterator operator+ (typename BackingIterator::difference_type offset)
+ {
+ return AdaptedConstIterator(m_iter + offset);
+ }
+
+ AdaptedConstIterator operator- (typename BackingIterator::difference_type offset)
+ {
+ return AdaptedConstIterator(m_iter - offset);
+ }
+
+ // Comparable
+ bool operator< (AdaptedConstIterator &rhs)
+ {
+ return m_iter < rhs.m_iter;
+ }
+
+ bool operator<= (AdaptedConstIterator &rhs)
+ {
+ return m_iter <= rhs.m_iter;
+ }
+
+ bool operator> (AdaptedConstIterator &rhs)
+ {
+ return m_iter > rhs.m_iter;
+ }
+
+ bool operator>= (AdaptedConstIterator &rhs)
+ {
+ return m_iter >= rhs.m_iter;
+ }
+
+ friend AdaptedConstIterator operator+(typename BackingIterator::difference_type, AdaptedConstIterator &);
+ friend typename BackingIterator::difference_type operator-(AdaptedConstIterator &, AdaptedConstIterator &);
+ friend void swap(AdaptedConstIterator &, AdaptedConstIterator &);
+};
+
+template <typename C, typename E, E (*A)(typename C::const_iterator &)>
+AdaptedConstIterator<C, E, A> operator+ (typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type offset, AdaptedConstIterator<C, E, A> &rhs)
+{
+ return rhs.operator+(offset);
+}
+
+template <typename C, typename E, E (*A)(typename C::const_iterator &)>
+typename AdaptedConstIterator<C, E, A>::BackingIterator::difference_type operator- (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
+{
+ return(lhs.m_iter - rhs.m_iter);
+}
+
+template <typename C, typename E, E (*A)(typename C::const_iterator &)>
+void swap (AdaptedConstIterator<C, E, A> &lhs, AdaptedConstIterator<C, E, A> &rhs)
+{
+ std::swap(lhs.m_iter, rhs.m_iter);
+}
+
+template <typename C, typename E, E (*A)(typename C::const_iterator &)> class AdaptedIterable
+{
+private:
+ const C &m_container;
+public:
+ AdaptedIterable (const C &container) :
+ m_container(container)
+ {
+ }
+
+ AdaptedConstIterator<C, E, A> begin ()
+ {
+ return AdaptedConstIterator<C, E, A>(m_container.begin());
+ }
+
+ AdaptedConstIterator<C, E, A> end ()
+ {
+ return AdaptedConstIterator<C, E, A>(m_container.end());
+ }
+};
+
+template <typename C, typename E, E (*A)(typename C::const_iterator &)> class LockingAdaptedIterable : public AdaptedIterable<C, E, A>
+{
+private:
+ Mutex *m_mutex = nullptr;
+public:
+ LockingAdaptedIterable (C &container, Mutex &mutex) :
+ AdaptedIterable<C,E,A>(container),
+ m_mutex(&mutex)
+ {
+ m_mutex->Lock();
+ }
+
+ LockingAdaptedIterable (LockingAdaptedIterable &&rhs) :
+ AdaptedIterable<C,E,A>(rhs),
+ m_mutex(rhs.m_mutex)
+ {
+ rhs.m_mutex = NULL;
+ }
+
+ ~LockingAdaptedIterable ()
+ {
+ if (m_mutex)
+ m_mutex->Unlock();
+ }
+
+private:
+ DISALLOW_COPY_AND_ASSIGN(LockingAdaptedIterable);
+};
+
+}
+
+#endif
diff --git a/lldb/source/Commands/CommandObjectTarget.cpp b/lldb/source/Commands/CommandObjectTarget.cpp
index ef431e25c3d..8e7e68aad39 100644
--- a/lldb/source/Commands/CommandObjectTarget.cpp
+++ b/lldb/source/Commands/CommandObjectTarget.cpp
@@ -1796,10 +1796,8 @@ LookupTypeInModule (CommandInterpreter &interpreter,
strm.Printf("%zu match%s found in ", num_matches, num_matches > 1 ? "es" : "");
DumpFullpath (strm, &module->GetFileSpec(), 0);
strm.PutCString(":\n");
- const uint32_t num_types = type_list.GetSize();
- for (uint32_t i=0; i<num_types; ++i)
+ for (TypeSP type_sp : type_list.Types())
{
- TypeSP type_sp (type_list.GetTypeAtIndex(i));
if (type_sp)
{
// Resolve the clang type so that any forward references
diff --git a/lldb/source/Commands/CommandObjectThread.cpp b/lldb/source/Commands/CommandObjectThread.cpp
index f46a2219a50..3dce83c48d0 100644
--- a/lldb/source/Commands/CommandObjectThread.cpp
+++ b/lldb/source/Commands/CommandObjectThread.cpp
@@ -183,24 +183,23 @@ protected:
else if (command.GetArgumentCount() == 1 && ::strcmp (command.GetArgumentAtIndex(0), "all") == 0)
{
Process *process = m_exe_ctx.GetProcessPtr();
- Mutex::Locker locker (process->GetThreadList().GetMutex());
- uint32_t num_threads = process->GetThreadList().GetSize();
- for (uint32_t i = 0; i < num_threads; i++)
+ uint32_t idx = 0;
+ for (ThreadSP thread_sp : process->Threads())
{
- ThreadSP thread_sp = process->GetThreadList().GetThreadAtIndex(i);
+ if (idx != 0)
+ result.AppendMessage("");
+
if (!thread_sp->GetStatus (strm,
m_options.m_start,
m_options.m_count,
num_frames_with_source))
{
- result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", i);
+ result.AppendErrorWithFormat ("error displaying backtrace for thread: \"0x%4.4x\"\n", idx);
result.SetStatus (eReturnStatusFailed);
return false;
}
- if (i < num_threads - 1)
- result.AppendMessage("");
-
+ ++idx;
}
}
else
OpenPOWER on IntegriCloud