diff options
author | Sean Callanan <scallanan@apple.com> | 2013-11-06 19:28:40 +0000 |
---|---|---|
committer | Sean Callanan <scallanan@apple.com> | 2013-11-06 19:28:40 +0000 |
commit | 5c19eac1c8c95fa0e40fa71da664326d29dcaf18 (patch) | |
tree | a3620393bea2552d01d9014a2c1534cb4f644102 | |
parent | 5fb3a13ba7523d3a93290bcfa033b835151c19aa (diff) | |
download | bcm5719-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.h | 11 | ||||
-rw-r--r-- | lldb/include/lldb/Target/Process.h | 6 | ||||
-rw-r--r-- | lldb/include/lldb/Target/ThreadList.h | 11 | ||||
-rw-r--r-- | lldb/include/lldb/Utility/Iterable.h | 225 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectTarget.cpp | 4 | ||||
-rw-r--r-- | lldb/source/Commands/CommandObjectThread.cpp | 15 |
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 |