diff options
author | Jason Molenda <jmolenda@apple.com> | 2013-12-13 00:29:16 +0000 |
---|---|---|
committer | Jason Molenda <jmolenda@apple.com> | 2013-12-13 00:29:16 +0000 |
commit | 5e8dce4dbfd6f3e3366948ec22b82b952ae2b108 (patch) | |
tree | 4ddc8514061bc208d847e04497561e574527518e | |
parent | 2af6d73cdfba2768198ee502c12da14102bf7e55 (diff) | |
download | bcm5719-llvm-5e8dce4dbfd6f3e3366948ec22b82b952ae2b108.tar.gz bcm5719-llvm-5e8dce4dbfd6f3e3366948ec22b82b952ae2b108.zip |
Add new Queue, QueueItem, Queuelist, SBQueue, SBQueueItem classes to represent
libdispatch aka Grand Central Dispatch (GCD) queues. Still fleshing out the
documentation and testing of these but the overall API is settling down so it's
a good time to check it in.
<rdar://problem/15600370>
llvm-svn: 197190
30 files changed, 1533 insertions, 3 deletions
diff --git a/lldb/include/lldb/API/LLDB.h b/lldb/include/lldb/API/LLDB.h index 93bc3bc121e..e094b639659 100644 --- a/lldb/include/lldb/API/LLDB.h +++ b/lldb/include/lldb/API/LLDB.h @@ -40,6 +40,8 @@ #include "lldb/API/SBListener.h" #include "lldb/API/SBModule.h" #include "lldb/API/SBProcess.h" +#include "lldb/API/SBQueue.h" +#include "lldb/API/SBQueueItem.h" #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" #include "lldb/API/SBStringList.h" diff --git a/lldb/include/lldb/API/SBAddress.h b/lldb/include/lldb/API/SBAddress.h index c5e8cc685a4..58a7d2bfb1d 100644 --- a/lldb/include/lldb/API/SBAddress.h +++ b/lldb/include/lldb/API/SBAddress.h @@ -118,6 +118,7 @@ protected: friend class SBTarget; friend class SBThread; friend class SBValue; + friend class SBQueueItem; lldb_private::Address * operator->(); diff --git a/lldb/include/lldb/API/SBProcess.h b/lldb/include/lldb/API/SBProcess.h index 4ecaeaa4992..ccf63b44fa0 100644 --- a/lldb/include/lldb/API/SBProcess.h +++ b/lldb/include/lldb/API/SBProcess.h @@ -13,6 +13,7 @@ #include "lldb/API/SBDefines.h" #include "lldb/API/SBError.h" #include "lldb/API/SBTarget.h" +#include "lldb/API/SBQueue.h" #include <stdio.h> namespace lldb { @@ -142,6 +143,15 @@ public: SetSelectedThreadByIndexID (uint32_t index_id); //------------------------------------------------------------------ + // Queue related functions + //------------------------------------------------------------------ + uint32_t + GetNumQueues (); + + lldb::SBQueue + GetQueueAtIndex (size_t index); + + //------------------------------------------------------------------ // Stepping related functions //------------------------------------------------------------------ @@ -312,6 +322,7 @@ protected: friend class SBTarget; friend class SBThread; friend class SBValue; + friend class SBQueue; lldb::ProcessSP GetSP() const; diff --git a/lldb/include/lldb/API/SBQueue.h b/lldb/include/lldb/API/SBQueue.h new file mode 100644 index 00000000000..84b0f8cc300 --- /dev/null +++ b/lldb/include/lldb/API/SBQueue.h @@ -0,0 +1,83 @@ +//===-- SBQueue.h -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBQueue_h_ +#define LLDB_SBQueue_h_ + +#include <vector> + +#include "lldb/lldb-forward.h" +#include "lldb/Host/Mutex.h" +#include "lldb/API/SBDefines.h" +#include "lldb/API/SBQueueItem.h" + +namespace lldb { + +class SBQueue +{ +public: + SBQueue (); + + SBQueue (const QueueSP& queue_sp); + + ~SBQueue(); + + bool + IsValid() const; + + void + Clear (); + + lldb::SBProcess + GetProcess (); + + lldb::queue_id_t + GetQueueID () const; + + const char * + GetName () const; + + uint32_t + GetIndexID () const; + + uint32_t + GetNumThreads (); + + lldb::SBThread + GetThreadAtIndex (uint32_t); + + uint32_t + GetNumItems (); + + lldb::SBQueueItem + GetItemAtIndex (uint32_t); + +protected: + friend class SBProcess; + + void + SetQueue (const lldb::QueueSP& queue_sp); + + void + FetchThreads (); + + void + FetchItems (); + +private: + lldb::QueueWP m_queue_wp; + std::vector<lldb::ThreadWP> m_threads; // threads currently executing this queue's items + bool m_thread_list_fetched; // have we tried to fetch the threads list already? + std::vector<lldb::QueueItemSP> m_items; // items currently enqueued + bool m_queue_items_fetched; // have we tried to fetch the item list already? +}; + +} // namespace lldb + +#endif // LLDB_SBQueue_h_ diff --git a/lldb/include/lldb/API/SBQueueItem.h b/lldb/include/lldb/API/SBQueueItem.h new file mode 100644 index 00000000000..23d06e2ac9c --- /dev/null +++ b/lldb/include/lldb/API/SBQueueItem.h @@ -0,0 +1,58 @@ +//===-- SBQueueItem.h -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLDB_SBQueueItem_h_ +#define LLDB_SBQueueItem_h_ + +#include "lldb/API/SBDefines.h" +#include "lldb/Core/Address.h" +#include "lldb/API/SBAddress.h" + +namespace lldb { + +class SBQueueItem +{ +public: + SBQueueItem (); + + SBQueueItem (const lldb::QueueItemSP& queue_item_sp); + + ~SBQueueItem(); + + bool + IsValid() const; + + void + Clear (); + + lldb::QueueItemKind + GetKind () const; + + void + SetKind (lldb::QueueItemKind kind); + + lldb::SBAddress + GetAddress () const; + + void + SetAddress (lldb::SBAddress addr); + + void + SetQueueItem (const lldb::QueueItemSP& queue_item_sp); + + SBThread + GetExtendedBacktraceThread (const char *type); + +private: + lldb::QueueItemSP m_queue_item_sp; +}; + +} // namespace lldb + +#endif // LLDB_SBQueueItem_h_ diff --git a/lldb/include/lldb/API/SBThread.h b/lldb/include/lldb/API/SBThread.h index 6542dca1f95..c8c882bc2bb 100644 --- a/lldb/include/lldb/API/SBThread.h +++ b/lldb/include/lldb/API/SBThread.h @@ -214,6 +214,8 @@ protected: friend class SBProcess; friend class SBDebugger; friend class SBValue; + friend class SBQueue; + friend class SBQueueItem; void SetThread (const lldb::ThreadSP& lldb_object_sp); diff --git a/lldb/include/lldb/Target/Process.h b/lldb/include/lldb/Target/Process.h index 6ad6d7de79a..ce910944579 100644 --- a/lldb/include/lldb/Target/Process.h +++ b/lldb/include/lldb/Target/Process.h @@ -43,6 +43,7 @@ #include "lldb/Interpreter/Options.h" #include "lldb/Target/ExecutionContextScope.h" #include "lldb/Target/Memory.h" +#include "lldb/Target/QueueList.h" #include "lldb/Target/ThreadList.h" #include "lldb/Target/UnixSignals.h" #include "lldb/Utility/PseudoTerminal.h" @@ -3317,10 +3318,10 @@ public: { return m_thread_list.Threads(); } - + uint32_t GetNextThreadIndexID (uint64_t thread_id); - + lldb::ThreadSP CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context); @@ -3333,6 +3334,36 @@ public: uint32_t AssignIndexIDToThread(uint64_t thread_id); + // Returns true if an index id has been assigned to a queue. + bool + HasAssignedIndexIDToQueue(lldb::queue_id_t queue_id); + + // Given a queue_id, it will assign a more reasonable index id for display to the user. + // If the queue_id has previously been assigned, the same index id will be used. + uint32_t + AssignIndexIDToQueue(lldb::queue_id_t queue_id); + + //------------------------------------------------------------------ + // Queue Queries + //------------------------------------------------------------------ + + void + UpdateQueueListIfNeeded (); + + QueueList & + GetQueueList () + { + UpdateQueueListIfNeeded(); + return m_queue_list; + } + + QueueList::QueueIterable + Queues () + { + UpdateQueueListIfNeeded(); + return m_queue_list.Queues(); + } + //------------------------------------------------------------------ // Event Handling //------------------------------------------------------------------ @@ -3676,7 +3707,9 @@ protected: ProcessModID m_mod_id; ///< Tracks the state of the process over stops and other alterations. uint32_t m_process_unique_id; ///< Each lldb_private::Process class that is created gets a unique integer ID that increments with each new instance uint32_t m_thread_index_id; ///< Each thread is created with a 1 based index that won't get re-used. + uint32_t m_queue_index_id; ///< Each queue is created with a 1 based index that won't get re-used. std::map<uint64_t, uint32_t> m_thread_id_to_index_id_map; + std::map<uint64_t, uint32_t> m_queue_id_to_index_id_map; int m_exit_status; ///< The exit status of the process, or -1 if not set. std::string m_exit_string; ///< A textual description of why a process exited. Mutex m_thread_mutex; @@ -3685,6 +3718,8 @@ protected: ///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads ThreadList m_extended_thread_list; ///< Owner for extended threads that may be generated, cleared on natural stops uint32_t m_extended_thread_stop_id; ///< The natural stop id when extended_thread_list was last updated + QueueList m_queue_list; ///< The list of libdispatch queues at a given stop point + uint32_t m_queue_list_stop_id; ///< The natural stop id when queue list was last fetched std::vector<Notifications> m_notifications; ///< The list of notifications that this process can deliver. std::vector<lldb::addr_t> m_image_tokens; Listener &m_listener; diff --git a/lldb/include/lldb/Target/Queue.h b/lldb/include/lldb/Target/Queue.h new file mode 100644 index 00000000000..0d30613f733 --- /dev/null +++ b/lldb/include/lldb/Target/Queue.h @@ -0,0 +1,140 @@ +//===-- Queue.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_Queue_h_ +#define liblldb_Queue_h_ + +#include <vector> +#include <string> + +#include "lldb/lldb-forward.h" +#include "lldb/lldb-enumerations.h" +#include "lldb/lldb-private.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// Queue: +// This class represents a libdispatch aka Grand Central Dispatch +// queue in the process. +// +// A program using libdispatch will create queues, put work items +// (functions, blocks) on the queues. The system will create / +// reassign pthreads to execute the work items for the queues. A +// serial queue will be associated with a single thread (or possibly +// no thread, if it is not doing any work). A concurrent queue may +// be associated with multiple threads. +//------------------------------------------------------------------ + + +class Queue : + public std::enable_shared_from_this<Queue> +{ +public: + + Queue (lldb::ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue_name); + + ~Queue (); + + //------------------------------------------------------------------ + /// Get the QueueID for this Queue + /// + /// A 64-bit ID number that uniquely identifies a queue at this particular + /// stop_id. It is not guaranteed that the same QueueID will not be reused + /// for a different queue later in the process execution after this queue + /// has been deleted. + /// + /// @return + /// The QueueID for this Queue. + //------------------------------------------------------------------ + lldb::queue_id_t + GetID (); + + //------------------------------------------------------------------ + /// Get the name of this Queue + /// + /// @return + /// The name of the queue, if one is available. + /// A NULL pointer is returned if none is available. + //------------------------------------------------------------------ + const char * + GetName (); + + //------------------------------------------------------------------ + /// Get the IndexID for this Queue + /// + /// An IndexID is a small integer value (starting with 1) assigned to + /// each queue that is seen during a Process lifetime. Ideally an + /// IndexID will not be reused (although note that QueueID, which it is + /// based on, is not guaranteed to be unique across the run of a program + /// and IndexID depends on QueueID) - so if a Queue appears as IndexID 5, + /// it will continue to show up as IndexID 5 at every process stop while + /// that queue still exists. + /// + /// @return + /// The IndexID for this queue. + //------------------------------------------------------------------ + uint32_t + GetIndexID (); + + //------------------------------------------------------------------ + /// Return the threads currently associated with this queue + /// + /// Zero, one, or many threads may be executing code for a queue at + /// a given point in time. This call returns the list of threads + /// that are currently executing work for this queue. + /// + /// @return + /// The threads currently performing work for this queue + //------------------------------------------------------------------ + std::vector<lldb::ThreadSP> + GetThreads (); + + //------------------------------------------------------------------ + /// Return the items that are currently enqueued + /// + /// "Enqueued" means that the item has been added to the queue to + /// be done, but has not yet been done. When the item is going to + /// be processed it is "dequeued". + /// + /// @return + /// The vector of enqueued items for this queue + //------------------------------------------------------------------ + const std::vector<lldb::QueueItemSP> & + GetItems() const + { + return m_enqueued_items; + } + + lldb::ProcessSP + GetProcess() const + { + return m_process_wp.lock(); + } + +protected: + lldb::ProcessWP m_process_wp; + lldb::queue_id_t m_queue_id; + uint32_t m_index_id; + std::string m_queue_name; + std::vector<lldb::QueueItemSP> m_enqueued_items; + +private: + //------------------------------------------------------------------ + // For Queue only + //------------------------------------------------------------------ + + DISALLOW_COPY_AND_ASSIGN (Queue); + +}; + +} // namespace lldb_private + +#endif // liblldb_Queue_h_ diff --git a/lldb/include/lldb/Target/QueueItem.h b/lldb/include/lldb/Target/QueueItem.h new file mode 100644 index 00000000000..210f21afa1a --- /dev/null +++ b/lldb/include/lldb/Target/QueueItem.h @@ -0,0 +1,133 @@ +//===-- QueueItem.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_QueueItem_h_ +#define liblldb_QueueItem_h_ + +#include "lldb/lldb-private.h" +#include "lldb/lldb-enumerations.h" + +#include "lldb/Core/Address.h" +#include "lldb/Core/ConstString.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// QueueItem: +// This class represents a work item enqueued on a libdispatch aka +// Grand Central Dispatch (GCD) queue. Most often, this will be a +// function or block. +// "enqueued" here means that the work item has been added to a queue +// but it has not yet started executing. When it is "dequeued", +// execution of the item begins. +//------------------------------------------------------------------ + + +class QueueItem +{ +public: + + QueueItem (lldb::QueueSP queue_sp); + + ~QueueItem (); + + //------------------------------------------------------------------ + /// Get the kind of work item this is + /// + /// @return + /// The type of work item that this QueueItem object + /// represents. eQueueItemKindUnknown may be returned. + //------------------------------------------------------------------ + lldb::QueueItemKind + GetKind () const; + + //------------------------------------------------------------------ + /// Set the type of work item this is + /// + /// @param [in] item_kind + /// Set the kind of this work item object. + //------------------------------------------------------------------ + void + SetKind (lldb::QueueItemKind item_kind); + + //------------------------------------------------------------------ + /// Get the code address that will be executed when this work item + /// is executed. + /// + /// @return + /// The address that will be invoked when this work item is + /// executed. Not all types of QueueItems will have an + /// address associated with them; check that the returned + /// Address is valid, or check that the WorkItemKind is a + /// kind that involves an address, such as eQueueItemKindFunction + /// or eQueueItemKindBlock. + //------------------------------------------------------------------ + lldb_private::Address & + GetAddress (); + + //------------------------------------------------------------------ + /// Set the work item address for this object + /// + /// @param [in] addr + /// The address that will be invoked when this work item + /// is executed. + //------------------------------------------------------------------ + void + SetAddress (lldb_private::Address addr); + + //------------------------------------------------------------------ + /// Check if this QueueItem object is valid + /// + /// If the weak pointer to the parent Queue cannot be revivified, + /// it is invalid. + /// + /// @return + /// True if this object is valid. + //------------------------------------------------------------------ + bool + IsValid () + { + return m_queue_wp.lock() != NULL; + } + + //------------------------------------------------------------------ + /// Get an extended backtrace thread for this queue item, if available + /// + /// If the backtrace/thread information was collected when this item + /// was enqueued, this call will provide it. + /// + /// @param [in] type + /// The type of extended backtrace being requested, e.g. "libdispatch" + /// or "pthread". + /// + /// @return + /// A thread shared pointer which will have a reference to an extended + /// thread if one was available. + //------------------------------------------------------------------ + lldb::ThreadSP + GetExtendedBacktraceThread (ConstString type); + +protected: + lldb::QueueWP m_queue_wp; + lldb::QueueItemKind m_kind; + lldb_private::Address m_address; + +private: + //------------------------------------------------------------------ + // For QueueItem only + //------------------------------------------------------------------ + + DISALLOW_COPY_AND_ASSIGN (QueueItem); + +}; + +} // namespace lldb_private + +#endif // liblldb_QueueItem_h_ diff --git a/lldb/include/lldb/Target/QueueList.h b/lldb/include/lldb/Target/QueueList.h new file mode 100644 index 00000000000..964c1099233 --- /dev/null +++ b/lldb/include/lldb/Target/QueueList.h @@ -0,0 +1,141 @@ +//===-- QueueList.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_QueueList_h_ +#define liblldb_QueueList_h_ + +#include <vector> + +#include "lldb/lldb-private.h" +#include "lldb/Core/UserID.h" +#include "lldb/Utility/Iterable.h" + + +namespace lldb_private { + +//------------------------------------------------------------------ +// QueueList: +// This is the container for libdispatch aka Grand Central Dispatch +// Queue objects. +// +// Each Process will have a QueueList. When the process execution is +// paused, the QueueList may be populated with Queues by the +// SystemRuntime. +//------------------------------------------------------------------ + +class QueueList +{ +friend class Process; + +public: + + QueueList (Process *process); + + ~QueueList (); + + //------------------------------------------------------------------ + /// Get the number of libdispatch queues that are available + /// + /// @return + /// The number of queues that are stored in the QueueList. + //------------------------------------------------------------------ + uint32_t + GetSize(); + + //------------------------------------------------------------------ + /// Get the Queue at a given index number + /// + /// @param [in] idx + /// The index number (0-based) of the queue. + /// @return + /// The Queue at that index number. + //------------------------------------------------------------------ + lldb::QueueSP + GetQueueAtIndex (uint32_t idx); + + typedef std::vector<lldb::QueueSP> collection; + typedef LockingAdaptedIterable<collection, lldb::QueueSP, vector_adapter> QueueIterable; + + //------------------------------------------------------------------ + /// Iterate over the list of queues + /// + /// @return + /// An Iterable object which can be used to loop over the queues + /// that exist. + //------------------------------------------------------------------ + QueueIterable + Queues () + { + return QueueIterable(m_queues, m_mutex); + } + + //------------------------------------------------------------------ + /// Clear out the list of queues from the QueueList + //------------------------------------------------------------------ + void + Clear(); + + //------------------------------------------------------------------ + /// Add a Queue to the QueueList + /// + /// @param [in] queue + /// Used by the SystemRuntime to populate the QueueList + //------------------------------------------------------------------ + void + AddQueue (lldb::QueueSP queue); + + //------------------------------------------------------------------ + /// Find a queue in the QueueList by QueueID + /// + /// @param [in] qid + /// The QueueID (same as returned by Thread::GetQueueID()) to find. + /// + /// @return + /// A QueueSP to the queue requested, if it is present in the QueueList. + /// An empty QueueSP willbe returned if this queue was not found. + //------------------------------------------------------------------ + lldb::QueueSP + FindQueueByID (lldb::queue_id_t qid); + + //------------------------------------------------------------------ + /// Find a queue in the QueueList by IndexID + /// + /// @param [in] index_id + /// Find a queue by IndexID. This is an integer associated with each + /// unique queue seen during a debug session and will not be reused + /// for a different queue. Unlike the QueueID, a 64-bit value, this + /// will tend to be an integral value like 1 or 7. + /// + /// @return + /// A QueueSP to the queue requested, if it is present in the QueueList. + /// An empty QueueSP willbe returned if this queue was not found. + //------------------------------------------------------------------ + lldb::QueueSP + FindQueueByIndexID (uint32_t index_id); + + lldb_private::Mutex & + GetMutex (); + +protected: + + //------------------------------------------------------------------ + // Classes that inherit from Process can see and modify these + //------------------------------------------------------------------ + Process *m_process; ///< The process that manages this queue list. + uint32_t m_stop_id; ///< The process stop ID that this queue list is valid for. + collection m_queues; ///< The queues for this process. + Mutex m_mutex; + +private: + QueueList (); +}; + +} // namespace lldb_private + +#endif // liblldb_QueueList_h_ diff --git a/lldb/include/lldb/Target/SystemRuntime.h b/lldb/include/lldb/Target/SystemRuntime.h index 7a0703e6cc3..8dedb11cb66 100644 --- a/lldb/include/lldb/Target/SystemRuntime.h +++ b/lldb/include/lldb/Target/SystemRuntime.h @@ -20,6 +20,7 @@ #include "lldb/Core/ConstString.h" #include "lldb/Core/ModuleList.h" #include "lldb/Core/PluginInterface.h" +#include "lldb/Target/QueueList.h" #include "lldb/lldb-private.h" @@ -160,6 +161,23 @@ public: virtual lldb::ThreadSP GetExtendedBacktraceThread (lldb::ThreadSP thread, ConstString type); + //------------------------------------------------------------------ + /// Populate the Process' QueueList with libdispatch / GCD queues that exist. + /// + /// When process execution is paused, the SystemRuntime may be called to fill + /// in the list of Queues that currently exist. + /// + /// @param [out] queue_list + /// This QueueList will be cleared, and any queues that currently exist + /// will be added. An empty QueueList will be returned if no queues + /// exist or if this Systemruntime does not support libdispatch queues. + //------------------------------------------------------------------ + virtual void + PopulateQueueList (lldb_private::QueueList &queue_list) + { + } + + protected: //------------------------------------------------------------------ // Member variables. diff --git a/lldb/include/lldb/lldb-enumerations.h b/lldb/include/lldb/lldb-enumerations.h index 0b341575be4..c8294960a7b 100644 --- a/lldb/include/lldb/lldb-enumerations.h +++ b/lldb/include/lldb/lldb-enumerations.h @@ -726,6 +726,19 @@ namespace lldb { eFilePermissionsDirectoryDefault = eFilePermissionsUserRWX, } FilePermissions; + //---------------------------------------------------------------------- + // Queue work item types + // + // The different types of work that can be enqueued on a libdispatch + // aka Grand Central Dispatch (GCD) queue. + //---------------------------------------------------------------------- + typedef enum QueueItemKind + { + eQueueItemKindUnknown = 0, + eQueueItemKindFunction, + eQueueItemKindBlock + } QueueItemKind; + } // namespace lldb diff --git a/lldb/include/lldb/lldb-forward.h b/lldb/include/lldb/lldb-forward.h index 435960c2b3c..e3d609cf381 100644 --- a/lldb/include/lldb/lldb-forward.h +++ b/lldb/include/lldb/lldb-forward.h @@ -216,6 +216,8 @@ class TypeFilterImpl; #ifndef LLDB_DISABLE_PYTHON class ScriptedSyntheticChildren; #endif +class Queue; +class QueueItem; class Target; class TargetList; class Thread; @@ -336,6 +338,9 @@ namespace lldb { typedef std::shared_ptr<lldb_private::RegisterCheckpoint> RegisterCheckpointSP; typedef std::shared_ptr<lldb_private::RegisterContext> RegisterContextSP; typedef std::shared_ptr<lldb_private::RegularExpression> RegularExpressionSP; + typedef std::shared_ptr<lldb_private::Queue> QueueSP; + typedef std::weak_ptr<lldb_private::Queue> QueueWP; + typedef std::shared_ptr<lldb_private::QueueItem> QueueItemSP; typedef std::shared_ptr<lldb_private::ScriptInterpreterObject> ScriptInterpreterObjectSP; #ifndef LLDB_DISABLE_PYTHON typedef std::shared_ptr<lldb_private::ScriptSummaryFormat> ScriptSummaryFormatSP; diff --git a/lldb/lldb.xcodeproj/project.pbxproj b/lldb/lldb.xcodeproj/project.pbxproj index f336771729b..4de129549b6 100644 --- a/lldb/lldb.xcodeproj/project.pbxproj +++ b/lldb/lldb.xcodeproj/project.pbxproj @@ -608,10 +608,17 @@ AF061F88182C97ED00B6A19C /* RegisterContextHistory.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F86182C97ED00B6A19C /* RegisterContextHistory.h */; }; AF061F8B182C980000B6A19C /* HistoryThread.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F89182C980000B6A19C /* HistoryThread.h */; }; AF061F8C182C980000B6A19C /* HistoryUnwind.h in Headers */ = {isa = PBXBuildFile; fileRef = AF061F8A182C980000B6A19C /* HistoryUnwind.h */; }; + AF0C112818580CD800C4C45B /* QueueItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0C112718580CD800C4C45B /* QueueItem.cpp */; }; + AF0EBBE8185940FB0059E52F /* SBQueue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0EBBE6185940FB0059E52F /* SBQueue.cpp */; }; + AF0EBBE9185940FB0059E52F /* SBQueueItem.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF0EBBE7185940FB0059E52F /* SBQueueItem.cpp */; }; + AF0EBBEC185941360059E52F /* SBQueue.h in Headers */ = {isa = PBXBuildFile; fileRef = AF0EBBEA185941360059E52F /* SBQueue.h */; settings = {ATTRIBUTES = (Public, ); }; }; + AF0EBBED185941360059E52F /* SBQueueItem.h in Headers */ = {isa = PBXBuildFile; fileRef = AF0EBBEB185941360059E52F /* SBQueueItem.h */; settings = {ATTRIBUTES = (Public, ); }; }; AF1729D6182C907200E0AB97 /* HistoryThread.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D4182C907200E0AB97 /* HistoryThread.cpp */; }; AF1729D7182C907200E0AB97 /* HistoryUnwind.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */; }; AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */; }; AF254E32170CCC33007AE5C9 /* PlatformDarwinKernel.h in Headers */ = {isa = PBXBuildFile; fileRef = AF254E30170CCC33007AE5C9 /* PlatformDarwinKernel.h */; }; + AF26703A1852D01E00B6CC36 /* Queue.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670381852D01E00B6CC36 /* Queue.cpp */; }; + AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF2670391852D01E00B6CC36 /* QueueList.cpp */; }; AF37E10A17C861F20061E18E /* ProcessRunLock.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF37E10917C861F20061E18E /* ProcessRunLock.cpp */; }; AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */ = {isa = PBXBuildFile; fileRef = AF81DEF91828A23F0042CF19 /* SystemRuntime.cpp */; }; AF90106515AB7D3600FF120D /* lldb.1 in CopyFiles */ = {isa = PBXBuildFile; fileRef = AF90106315AB7C5700FF120D /* lldb.1 */; }; @@ -1777,10 +1784,19 @@ AF061F86182C97ED00B6A19C /* RegisterContextHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextHistory.h; path = Utility/RegisterContextHistory.h; sourceTree = "<group>"; }; AF061F89182C980000B6A19C /* HistoryThread.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryThread.h; path = Utility/HistoryThread.h; sourceTree = "<group>"; }; AF061F8A182C980000B6A19C /* HistoryUnwind.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HistoryUnwind.h; path = Utility/HistoryUnwind.h; sourceTree = "<group>"; }; + AF0C112718580CD800C4C45B /* QueueItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QueueItem.cpp; path = source/Target/QueueItem.cpp; sourceTree = "<group>"; }; + AF0EBBE6185940FB0059E52F /* SBQueue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBQueue.cpp; path = source/API/SBQueue.cpp; sourceTree = "<group>"; }; + AF0EBBE7185940FB0059E52F /* SBQueueItem.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SBQueueItem.cpp; path = source/API/SBQueueItem.cpp; sourceTree = "<group>"; }; + AF0EBBEA185941360059E52F /* SBQueue.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBQueue.h; path = include/lldb/API/SBQueue.h; sourceTree = "<group>"; }; + AF0EBBEB185941360059E52F /* SBQueueItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SBQueueItem.h; path = include/lldb/API/SBQueueItem.h; sourceTree = "<group>"; }; + AF0EBBEE1859419F0059E52F /* SBQueue.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBQueue.i; sourceTree = "<group>"; }; + AF0EBBEF1859419F0059E52F /* SBQueueItem.i */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c.preprocessed; path = SBQueueItem.i; sourceTree = "<group>"; }; AF1729D4182C907200E0AB97 /* HistoryThread.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryThread.cpp; path = Utility/HistoryThread.cpp; sourceTree = "<group>"; }; AF1729D5182C907200E0AB97 /* HistoryUnwind.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = HistoryUnwind.cpp; path = Utility/HistoryUnwind.cpp; sourceTree = "<group>"; }; AF254E2F170CCC33007AE5C9 /* PlatformDarwinKernel.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = PlatformDarwinKernel.cpp; sourceTree = "<group>"; }; AF254E30170CCC33007AE5C9 /* PlatformDarwinKernel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PlatformDarwinKernel.h; sourceTree = "<group>"; }; + AF2670381852D01E00B6CC36 /* Queue.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Queue.cpp; path = source/Target/Queue.cpp; sourceTree = "<group>"; }; + AF2670391852D01E00B6CC36 /* QueueList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = QueueList.cpp; path = source/Target/QueueList.cpp; sourceTree = "<group>"; }; AF37E10917C861F20061E18E /* ProcessRunLock.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProcessRunLock.cpp; sourceTree = "<group>"; }; AF68D2541255416E002FF25B /* RegisterContextLLDB.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = RegisterContextLLDB.cpp; path = Utility/RegisterContextLLDB.cpp; sourceTree = "<group>"; }; AF68D2551255416E002FF25B /* RegisterContextLLDB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RegisterContextLLDB.h; path = Utility/RegisterContextLLDB.h; sourceTree = "<group>"; }; @@ -2203,6 +2219,8 @@ 263C493B178B61CC0070F12D /* SBModuleSpec.i */, 262F12B8183546C900AEB384 /* SBPlatform.i */, 2611FF07142D83060017FEA3 /* SBProcess.i */, + AF0EBBEE1859419F0059E52F /* SBQueue.i */, + AF0EBBEF1859419F0059E52F /* SBQueueItem.i */, 2611FF08142D83060017FEA3 /* SBSection.i */, 2611FF09142D83060017FEA3 /* SBSourceManager.i */, 2611FF0A142D83060017FEA3 /* SBStream.i */, @@ -2304,6 +2322,10 @@ 263C4937178B50C40070F12D /* SBModuleSpec.cpp */, 262F12B61835469C00AEB384 /* SBPlatform.h */, 262F12B41835468600AEB384 /* SBPlatform.cpp */, + AF0EBBEA185941360059E52F /* SBQueue.h */, + AF0EBBE6185940FB0059E52F /* SBQueue.cpp */, + AF0EBBEB185941360059E52F /* SBQueueItem.h */, + AF0EBBE7185940FB0059E52F /* SBQueueItem.cpp */, 9A9831041125FC5800A56CB0 /* SBProcess.h */, 9A9831031125FC5800A56CB0 /* SBProcess.cpp */, 26B8283C142D01E9002DBC64 /* SBSection.h */, @@ -3160,6 +3182,9 @@ 264A43BD1320BCEB005B4096 /* Platform.cpp */, 26BC7DF310F1B81A00F91463 /* Process.h */, 26BC7F3610F1B90C00F91463 /* Process.cpp */, + AF2670381852D01E00B6CC36 /* Queue.cpp */, + AF2670391852D01E00B6CC36 /* QueueList.cpp */, + AF0C112718580CD800C4C45B /* QueueItem.cpp */, 26AB54111832DC3400EADFF3 /* RegisterCheckpoint.h */, 26BC7DF410F1B81A00F91463 /* RegisterContext.h */, 26BC7F3710F1B90C00F91463 /* RegisterContext.cpp */, @@ -3628,6 +3653,7 @@ 26680220115FD13D008E1FE4 /* SBDebugger.h in Headers */, 490A966B1628C3BF00F0002E /* SBDeclaration.h in Headers */, 26680221115FD13D008E1FE4 /* SBDefines.h in Headers */, + AF0EBBEC185941360059E52F /* SBQueue.h in Headers */, 26680222115FD13D008E1FE4 /* SBError.h in Headers */, 26680223115FD13D008E1FE4 /* SBEvent.h in Headers */, 26680224115FD13D008E1FE4 /* SBFileSpec.h in Headers */, @@ -3639,6 +3665,7 @@ 9AC7038E117674FB0086C050 /* SBInstruction.h in Headers */, 9AC70390117675270086C050 /* SBInstructionList.h in Headers */, 26DE205911618FE700A093E2 /* SBLineEntry.h in Headers */, + AF0EBBED185941360059E52F /* SBQueueItem.h in Headers */, 26680227115FD13D008E1FE4 /* SBListener.h in Headers */, 26DE204F11618E9800A093E2 /* SBModule.h in Headers */, 2668022A115FD13D008E1FE4 /* SBProcess.h in Headers */, @@ -4073,6 +4100,8 @@ 26DE204D11618E7A00A093E2 /* SBModule.cpp in Sources */, 26DE205D1161901400A093E2 /* SBFunction.cpp in Sources */, 26DE205F1161901B00A093E2 /* SBCompileUnit.cpp in Sources */, + AF0EBBE9185940FB0059E52F /* SBQueueItem.cpp in Sources */, + AF0EBBE8185940FB0059E52F /* SBQueue.cpp in Sources */, 26DE20611161902700A093E2 /* SBBlock.cpp in Sources */, 26DE20631161904200A093E2 /* SBLineEntry.cpp in Sources */, 26DE20651161904E00A093E2 /* SBSymbol.cpp in Sources */, @@ -4182,6 +4211,7 @@ 2689004513353E0400698AC0 /* ModuleChild.cpp in Sources */, 2689004613353E0400698AC0 /* ModuleList.cpp in Sources */, 2689004713353E0400698AC0 /* PluginManager.cpp in Sources */, + AF0C112818580CD800C4C45B /* QueueItem.cpp in Sources */, AF254E31170CCC33007AE5C9 /* PlatformDarwinKernel.cpp in Sources */, 2689004813353E0400698AC0 /* RegularExpression.cpp in Sources */, 2689004913353E0400698AC0 /* Scalar.cpp in Sources */, @@ -4313,6 +4343,7 @@ 268900DB13353E6F00698AC0 /* LineTable.cpp in Sources */, 268900DC13353E6F00698AC0 /* ObjectFile.cpp in Sources */, 268900DD13353E6F00698AC0 /* Symbol.cpp in Sources */, + AF26703A1852D01E00B6CC36 /* Queue.cpp in Sources */, 268900DE13353E6F00698AC0 /* SymbolContext.cpp in Sources */, 268900DF13353E6F00698AC0 /* SymbolFile.cpp in Sources */, 268900E013353E6F00698AC0 /* SymbolVendor.cpp in Sources */, @@ -4389,6 +4420,7 @@ 264D8D5013661BD7003A368F /* UnwindAssembly.cpp in Sources */, 26ECA04313665FED008D1F18 /* ARM_DWARF_Registers.cpp in Sources */, AF061F87182C97ED00B6A19C /* RegisterContextHistory.cpp in Sources */, + AF26703B1852D01E00B6CC36 /* QueueList.cpp in Sources */, 267C012B136880DF006E963E /* OptionGroupValueObjectDisplay.cpp in Sources */, 26BCFC521368AE38006DC050 /* OptionGroupFormat.cpp in Sources */, AF81DEFA1828A23F0042CF19 /* SystemRuntime.cpp in Sources */, diff --git a/lldb/scripts/Python/build-swig-Python.sh b/lldb/scripts/Python/build-swig-Python.sh index 5cbb9644ca0..c424c06f0ae 100755 --- a/lldb/scripts/Python/build-swig-Python.sh +++ b/lldb/scripts/Python/build-swig-Python.sh @@ -107,6 +107,8 @@ HEADER_FILES="${SRC_ROOT}/include/lldb/lldb.h"\ " ${SRC_ROOT}/include/lldb/API/SBModule.h"\ " ${SRC_ROOT}/include/lldb/API/SBModuleSpec.h"\ " ${SRC_ROOT}/include/lldb/API/SBProcess.h"\ +" ${SRC_ROOT}/include/lldb/API/SBQueue.h"\ +" ${SRC_ROOT}/include/lldb/API/SBQueueItem.h"\ " ${SRC_ROOT}/include/lldb/API/SBSourceManager.h"\ " ${SRC_ROOT}/include/lldb/API/SBStream.h"\ " ${SRC_ROOT}/include/lldb/API/SBStringList.h"\ @@ -154,6 +156,8 @@ INTERFACE_FILES="${SRC_ROOT}/scripts/Python/interface/SBAddress.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBModuleSpec.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBPlatform.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBProcess.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBQueue.i"\ +" ${SRC_ROOT}/scripts/Python/interface/SBQueueItem.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBSourceManager.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBStream.i"\ " ${SRC_ROOT}/scripts/Python/interface/SBStringList.i"\ diff --git a/lldb/scripts/Python/interface/SBProcess.i b/lldb/scripts/Python/interface/SBProcess.i index 9798f9aa4a4..7abbf919af2 100644 --- a/lldb/scripts/Python/interface/SBProcess.i +++ b/lldb/scripts/Python/interface/SBProcess.i @@ -180,6 +180,15 @@ public: SetSelectedThreadByIndexID (uint32_t index_id); //------------------------------------------------------------------ + // Queue related functions + //------------------------------------------------------------------ + uint32_t + GetNumQueues (); + + lldb::SBQueue + GetQueueAtIndex (uint32_t index); + + //------------------------------------------------------------------ // Stepping related functions //------------------------------------------------------------------ diff --git a/lldb/scripts/Python/interface/SBQueue.i b/lldb/scripts/Python/interface/SBQueue.i new file mode 100644 index 00000000000..09dbc190a6d --- /dev/null +++ b/lldb/scripts/Python/interface/SBQueue.i @@ -0,0 +1,54 @@ +//===-- SWIG Interface for SBQueue.h -----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class SBQueue +{ +public: + SBQueue (); + + SBQueue (const lldb::QueueSP& queue_sp); + + ~SBQueue(); + + bool + IsValid() const; + + void + Clear (); + + lldb::SBProcess + GetProcess (); + + lldb::queue_id_t + GetQueueID () const; + + const char * + GetName () const; + + uint32_t + GetIndexID () const; + + uint32_t + GetNumThreads (); + + lldb::SBThread + GetThreadAtIndex (uint32_t); + + uint32_t + GetNumItems (); + + lldb::SBQueueItem + GetItemAtIndex (uint32_t); + +}; + +} // namespace lldb + diff --git a/lldb/scripts/Python/interface/SBQueueItem.i b/lldb/scripts/Python/interface/SBQueueItem.i new file mode 100644 index 00000000000..ffa24150b67 --- /dev/null +++ b/lldb/scripts/Python/interface/SBQueueItem.i @@ -0,0 +1,46 @@ +//===-- SWIG Interface for SBQueueItem.h ------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +namespace lldb { + +class SBQueueItem +{ +public: + SBQueueItem (); + + SBQueueItem (const lldb::QueueItemSP& queue_item_sp); + + ~SBQueueItem(); + + bool + IsValid() const; + + void + Clear (); + + lldb::QueueItemKind + GetKind () const; + + void + SetKind (lldb::QueueItemKind kind); + + lldb::SBAddress + GetAddress () const; + + void + SetAddress (lldb::SBAddress addr); + + void + SetQueueItem (const lldb::QueueItemSP& queue_item_sp); + + lldb::SBThread + GetExtendedBacktraceThread (const char *type); +}; + +} // namespace lldb diff --git a/lldb/scripts/lldb.swig b/lldb/scripts/lldb.swig index acf8492bcee..d53ba8b1878 100644 --- a/lldb/scripts/lldb.swig +++ b/lldb/scripts/lldb.swig @@ -81,6 +81,8 @@ import os #include "lldb/API/SBModuleSpec.h" #include "lldb/API/SBPlatform.h" #include "lldb/API/SBProcess.h" +#include "lldb/API/SBQueue.h" +#include "lldb/API/SBQueueItem.h" #include "lldb/API/SBSection.h" #include "lldb/API/SBSourceManager.h" #include "lldb/API/SBStream.h" @@ -146,6 +148,8 @@ import os %include "./Python/interface/SBModuleSpec.i" %include "./Python/interface/SBPlatform.i" %include "./Python/interface/SBProcess.i" +%include "./Python/interface/SBQueue.i" +%include "./Python/interface/SBQueueItem.i" %include "./Python/interface/SBSection.i" %include "./Python/interface/SBSourceManager.i" %include "./Python/interface/SBStream.i" diff --git a/lldb/source/API/CMakeLists.txt b/lldb/source/API/CMakeLists.txt index ac7a484978f..560167e2853 100644 --- a/lldb/source/API/CMakeLists.txt +++ b/lldb/source/API/CMakeLists.txt @@ -30,6 +30,8 @@ add_lldb_library(lldbAPI SBModuleSpec.cpp SBPlatform.cpp SBProcess.cpp + SBQueue.cpp + SBQueueItem.cpp SBSection.cpp SBSourceManager.cpp SBStream.cpp diff --git a/lldb/source/API/SBProcess.cpp b/lldb/source/API/SBProcess.cpp index 557006f2434..235388b5f25 100644 --- a/lldb/source/API/SBProcess.cpp +++ b/lldb/source/API/SBProcess.cpp @@ -535,6 +535,53 @@ SBProcess::GetThreadAtIndex (size_t index) } uint32_t +SBProcess::GetNumQueues () +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + uint32_t num_queues = 0; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + num_queues = process_sp->GetQueueList().GetSize(); + } + + if (log) + log->Printf ("SBProcess(%p)::GetNumQueues () => %d", process_sp.get(), num_queues); + + return num_queues; +} + +SBQueue +SBProcess::GetQueueAtIndex (size_t index) +{ + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + + SBQueue sb_queue; + QueueSP queue_sp; + ProcessSP process_sp(GetSP()); + if (process_sp) + { + Process::StopLocker stop_locker; + Mutex::Locker api_locker (process_sp->GetTarget().GetAPIMutex()); + queue_sp = process_sp->GetQueueList().GetQueueAtIndex(index); + sb_queue.SetQueue (queue_sp); + } + + if (log) + { + log->Printf ("SBProcess(%p)::GetQueueAtIndex (index=%d) => SBQueue(%p)", + process_sp.get(), (uint32_t) index, queue_sp.get()); + } + + return sb_queue; +} + + +uint32_t SBProcess::GetStopID(bool include_expression_stops) { ProcessSP process_sp(GetSP()); diff --git a/lldb/source/API/SBQueue.cpp b/lldb/source/API/SBQueue.cpp new file mode 100644 index 00000000000..58e3fcc495f --- /dev/null +++ b/lldb/source/API/SBQueue.cpp @@ -0,0 +1,256 @@ +//===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" + +#include "lldb/API/SBQueue.h" + +#include "lldb/API/SBProcess.h" +#include "lldb/API/SBThread.h" +#include "lldb/Core/Log.h" +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueItem.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// Constructors +//---------------------------------------------------------------------- +SBQueue::SBQueue () : + m_queue_wp(), + m_threads(), + m_thread_list_fetched(false), + m_items(), + m_queue_items_fetched(false) +{ +} + +SBQueue::SBQueue (const QueueSP& queue_sp) : + m_queue_wp(queue_sp), + m_threads(), + m_thread_list_fetched(false), + m_items(), + m_queue_items_fetched(false) +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBQueue::~SBQueue() +{ + m_threads.clear(); + m_items.clear(); +} + +bool +SBQueue::IsValid() const +{ + QueueSP queue_sp = m_queue_wp.lock(); + return queue_sp.get() != NULL; +} + + +void +SBQueue::Clear () +{ + m_queue_wp.reset(); + m_thread_list_fetched = false; + m_threads.clear(); + m_queue_items_fetched = false; + m_items.clear(); +} + + +void +SBQueue::SetQueue (const QueueSP& queue_sp) +{ + m_queue_wp = queue_sp; + m_thread_list_fetched = false; + m_threads.clear(); + m_queue_items_fetched = false; + m_items.clear(); +} + +lldb::queue_id_t +SBQueue::GetQueueID () const +{ + queue_id_t result = LLDB_INVALID_QUEUE_ID; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result = queue_sp->GetID(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, this, result); + return result; +} + +uint32_t +SBQueue::GetIndexID () const +{ + uint32_t result = LLDB_INVALID_INDEX32; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result = queue_sp->GetIndexID(); + } + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueue(%p)::GetIndexID () => %d", this, result); + return result; +} + +const char * +SBQueue::GetName () const +{ + const char *name = NULL; + QueueSP queue_sp = m_queue_wp.lock (); + if (queue_sp.get()) + { + name = queue_sp->GetName(); + } + + Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_API)); + if (log) + log->Printf ("SBQueue(%p)::GetName () => %s", this, name ? name : "NULL"); + + return name; +} + +void +SBQueue::FetchThreads () +{ + if (m_thread_list_fetched == false) + { + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock())) + { + const std::vector<ThreadSP> thread_list(queue_sp->GetThreads()); + m_thread_list_fetched = true; + const uint32_t num_threads = thread_list.size(); + for (uint32_t idx = 0; idx < num_threads; ++idx) + { + ThreadSP thread_sp = thread_list[idx]; + if (thread_sp && thread_sp->IsValid()) + { + m_threads.push_back (thread_sp); + } + } + } + } + } +} + +void +SBQueue::FetchItems () +{ + if (m_queue_items_fetched == false) + { + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + Process::StopLocker stop_locker; + if (stop_locker.TryLock (&queue_sp->GetProcess()->GetRunLock())) + { + const std::vector<QueueItemSP> queue_items(queue_sp->GetItems()); + m_queue_items_fetched = true; + const uint32_t num_items = queue_items.size(); + for (uint32_t idx = 0; idx < num_items; ++idx) + { + QueueItemSP item = queue_items[idx]; + if (item && item->IsValid()) + { + m_items.push_back (item); + } + } + } + } + } +} + +uint32_t +SBQueue::GetNumThreads () +{ + uint32_t result = 0; + + FetchThreads(); + if (m_thread_list_fetched) + { + result = m_threads.size(); + } + return result; +} + +SBThread +SBQueue::GetThreadAtIndex (uint32_t idx) +{ + FetchThreads(); + + SBThread sb_thread; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp && idx < m_threads.size()) + { + ProcessSP process_sp = queue_sp->GetProcess(); + if (process_sp) + { + ThreadSP thread_sp = m_threads[idx].lock(); + if (thread_sp) + { + sb_thread.SetThread (thread_sp); + } + } + } + return sb_thread; +} + + +uint32_t +SBQueue::GetNumItems () +{ + uint32_t result = 0; + FetchItems(); + + if (m_queue_items_fetched) + { + result = m_items.size(); + } + return result; +} + +SBQueueItem +SBQueue::GetItemAtIndex (uint32_t idx) +{ + SBQueueItem result; + FetchItems(); + if (m_queue_items_fetched && idx < m_items.size()) + { + result.SetQueueItem (m_items[idx]); + } + return result; +} + +SBProcess +SBQueue::GetProcess () +{ + SBProcess result; + QueueSP queue_sp = m_queue_wp.lock(); + if (queue_sp) + { + result.SetSP (queue_sp->GetProcess()); + } + return result; +} diff --git a/lldb/source/API/SBQueueItem.cpp b/lldb/source/API/SBQueueItem.cpp new file mode 100644 index 00000000000..b68c40b3e02 --- /dev/null +++ b/lldb/source/API/SBQueueItem.cpp @@ -0,0 +1,119 @@ +//===-- SBQueueItem.cpp -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/lldb-python.h" +#include "lldb/lldb-forward.h" + +#include "lldb/API/SBAddress.h" +#include "lldb/API/SBQueueItem.h" +#include "lldb/API/SBThread.h" +#include "lldb/Core/Address.h" +#include "lldb/Target/QueueItem.h" + +using namespace lldb; +using namespace lldb_private; + +//---------------------------------------------------------------------- +// Constructors +//---------------------------------------------------------------------- +SBQueueItem::SBQueueItem () : + m_queue_item_sp() +{ +} + +SBQueueItem::SBQueueItem (const QueueItemSP& queue_item_sp) : + m_queue_item_sp (queue_item_sp) +{ +} + +//---------------------------------------------------------------------- +// Destructor +//---------------------------------------------------------------------- +SBQueueItem::~SBQueueItem() +{ + m_queue_item_sp.reset(); +} + +bool +SBQueueItem::IsValid() const +{ + return m_queue_item_sp.get() != NULL; +} + + +void +SBQueueItem::Clear () +{ + m_queue_item_sp.reset(); +} + + +void +SBQueueItem::SetQueueItem (const QueueItemSP& queue_item_sp) +{ + m_queue_item_sp = queue_item_sp; +} + + +lldb::QueueItemKind +SBQueueItem::GetKind () const +{ + QueueItemKind result = eQueueItemKindUnknown; + if (m_queue_item_sp) + { + result = m_queue_item_sp->GetKind (); + } + return result; +} + +void +SBQueueItem::SetKind (lldb::QueueItemKind kind) +{ + if (m_queue_item_sp) + { + m_queue_item_sp->SetKind (kind); + } +} + +SBAddress +SBQueueItem::GetAddress () const +{ + SBAddress result; + if (m_queue_item_sp) + { + result.SetAddress (&m_queue_item_sp->GetAddress()); + } + return result; +} + +void +SBQueueItem::SetAddress (SBAddress addr) +{ + if (m_queue_item_sp) + { + m_queue_item_sp->SetAddress (addr.ref()); + } +} + +SBThread +SBQueueItem::GetExtendedBacktraceThread (const char *type) +{ + SBThread result; + if (m_queue_item_sp) + { + ThreadSP thread_sp; + ConstString type_const (type); + thread_sp = m_queue_item_sp->GetExtendedBacktraceThread (type_const); + if (thread_sp) + { + result.SetThread (thread_sp); + } + } + return result; +} diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp index 388264a2d95..5756e7071d7 100644 --- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp +++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.cpp @@ -22,10 +22,11 @@ #include "lldb/Symbol/ObjectFile.h" #include "lldb/Symbol/SymbolContext.h" #include "Plugins/Process/Utility/HistoryThread.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueList.h" #include "lldb/Target/Target.h" #include "lldb/Target/Thread.h" - #include "SystemRuntimeMacOSX.h" using namespace lldb; @@ -443,6 +444,26 @@ SystemRuntimeMacOSX::GetExtendedBacktraceThread (ThreadSP original_thread_sp, Co return new_extended_thread_sp; } +void +SystemRuntimeMacOSX::PopulateQueueList (lldb_private::QueueList &queue_list) +{ + // For now, iterate over the threads and see what queue each thread is associated with. + // If we haven't already added this queue, add it to the QueueList. + // (a single libdispatch queue may be using multiple threads simultaneously.) + + for (ThreadSP thread_sp : m_process->Threads()) + { + if (thread_sp->GetQueueID() != LLDB_INVALID_QUEUE_ID) + { + if (queue_list.FindQueueByID (thread_sp->GetQueueID()).get() == NULL) + { + QueueSP queue_sp (new Queue(m_process->shared_from_this(), thread_sp->GetQueueID(), thread_sp->GetQueueName())); + queue_list.AddQueue (queue_sp); + } + } + } +} + void SystemRuntimeMacOSX::Initialize() diff --git a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h index c472bee8572..4c684fee7b2 100644 --- a/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h +++ b/lldb/source/Plugins/SystemRuntime/MacOSX/SystemRuntimeMacOSX.h @@ -104,6 +104,9 @@ private: SystemRuntimeMacOSX::ArchivedBacktrace GetLibdispatchExtendedBacktrace (lldb::ThreadSP thread); + void + PopulateQueueList (lldb_private::QueueList &queue_list); + protected: lldb::user_id_t m_break_id; mutable lldb_private::Mutex m_mutex; diff --git a/lldb/source/Target/CMakeLists.txt b/lldb/source/Target/CMakeLists.txt index 1ba01ea1dc7..fb7badbae26 100644 --- a/lldb/source/Target/CMakeLists.txt +++ b/lldb/source/Target/CMakeLists.txt @@ -13,6 +13,9 @@ add_lldb_library(lldbTarget PathMappingList.cpp Platform.cpp Process.cpp + Queue.cpp + QueueItem.cpp + QueueList.cpp RegisterContext.cpp SectionLoadHistory.cpp SectionLoadList.cpp diff --git a/lldb/source/Target/Process.cpp b/lldb/source/Target/Process.cpp index 1de322aee14..81e12a3b2f7 100644 --- a/lldb/source/Target/Process.cpp +++ b/lldb/source/Target/Process.cpp @@ -1017,7 +1017,9 @@ Process::Process(Target &target, Listener &listener) : m_mod_id (), m_process_unique_id(0), m_thread_index_id (0), + m_queue_index_id (0), m_thread_id_to_index_id_map (), + m_queue_id_to_index_id_map (), m_exit_status (-1), m_exit_string (), m_thread_mutex (Mutex::eMutexTypeRecursive), @@ -1025,6 +1027,8 @@ Process::Process(Target &target, Listener &listener) : m_thread_list (this), m_extended_thread_list (this), m_extended_thread_stop_id (0), + m_queue_list (this), + m_queue_list_stop_id (0), m_notifications (), m_image_tokens (), m_listener (listener), @@ -1151,6 +1155,8 @@ Process::Finalize() m_thread_list_real.Destroy(); m_thread_list.Destroy(); m_extended_thread_list.Destroy(); + m_queue_list.Clear(); + m_queue_list_stop_id = 0; std::vector<Notifications> empty_notifications; m_notifications.swap(empty_notifications); m_image_tokens.clear(); @@ -1600,12 +1606,32 @@ Process::UpdateThreadListIfNeeded () // Clear any extended threads that we may have accumulated previously m_extended_thread_list.Clear(); m_extended_thread_stop_id = GetLastNaturalStopID (); + + m_queue_list.Clear(); + m_queue_list_stop_id = GetLastNaturalStopID (); } } } } } +void +Process::UpdateQueueListIfNeeded () +{ + if (m_system_runtime_ap.get()) + { + if (m_queue_list.GetSize() == 0 || m_queue_list_stop_id != GetLastNaturalStopID()) + { + const StateType state = GetPrivateState(); + if (StateIsStoppedState (state, true)) + { + m_system_runtime_ap->PopulateQueueList (m_queue_list); + m_queue_list_stop_id = GetLastNaturalStopID(); + } + } + } +} + ThreadSP Process::CreateOSPluginThread (lldb::tid_t tid, lldb::addr_t context) { @@ -1653,6 +1679,39 @@ Process::AssignIndexIDToThread(uint64_t thread_id) return result; } +bool +Process::HasAssignedIndexIDToQueue(queue_id_t queue_id) +{ + std::map<uint64_t, uint32_t>::iterator iterator = m_queue_id_to_index_id_map.find(queue_id); + if (iterator == m_queue_id_to_index_id_map.end()) + { + return false; + } + else + { + return true; + } +} + +uint32_t +Process::AssignIndexIDToQueue(queue_id_t queue_id) +{ + uint32_t result = 0; + std::map<uint64_t, uint32_t>::iterator iterator = m_queue_id_to_index_id_map.find(queue_id); + if (iterator == m_queue_id_to_index_id_map.end()) + { + result = ++m_queue_index_id; + m_queue_id_to_index_id_map[queue_id] = result; + } + else + { + result = iterator->second; + } + + return result; +} + + StateType Process::GetState() { @@ -5680,6 +5739,10 @@ void Process::Flush () { m_thread_list.Flush(); + m_extended_thread_list.Flush(); + m_extended_thread_stop_id = 0; + m_queue_list.Clear(); + m_queue_list_stop_id = 0; } void diff --git a/lldb/source/Target/Queue.cpp b/lldb/source/Target/Queue.cpp new file mode 100644 index 00000000000..27f01975e47 --- /dev/null +++ b/lldb/source/Target/Queue.cpp @@ -0,0 +1,68 @@ +//===-- Queue.cpp -----------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueList.h" +#include "lldb/Target/Thread.h" + +using namespace lldb; +using namespace lldb_private; + +Queue::Queue (ProcessSP process_sp, lldb::queue_id_t queue_id, const char *queue_name) : + m_process_wp (process_sp), + m_queue_id (queue_id), + m_queue_name (queue_name), + m_enqueued_items() +{ + m_index_id = process_sp->AssignIndexIDToQueue (queue_id); +} + +Queue::~Queue () +{ +} + +queue_id_t +Queue::GetID () +{ + return m_queue_id; +} + +const char * +Queue::GetName () +{ + const char *result = NULL; + if (m_queue_name.size() > 0) + result = m_queue_name.c_str(); + return result; +} + +uint32_t +Queue::GetIndexID () +{ + return m_index_id; +} + +std::vector<lldb::ThreadSP> +Queue::GetThreads () +{ + std::vector<ThreadSP> result; + ProcessSP process_sp = m_process_wp.lock(); + if (process_sp.get ()) + { + for (ThreadSP thread_sp : process_sp->Threads()) + { + if (thread_sp->GetQueueID() == m_queue_id) + { + result.push_back (thread_sp); + } + } + } + return result; +} diff --git a/lldb/source/Target/QueueItem.cpp b/lldb/source/Target/QueueItem.cpp new file mode 100644 index 00000000000..3b8d3a5d9c2 --- /dev/null +++ b/lldb/source/Target/QueueItem.cpp @@ -0,0 +1,55 @@ +//===-- QueueItem.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueItem.h" + +using namespace lldb; +using namespace lldb_private; + +QueueItem::QueueItem (QueueSP queue_sp) : + m_queue_wp (queue_sp), + m_kind (eQueueItemKindUnknown), + m_address () +{ +} + +QueueItem::~QueueItem () +{ +} + +QueueItemKind +QueueItem::GetKind() const +{ + return m_kind; +} + +void +QueueItem::SetKind (QueueItemKind item_kind) +{ + m_kind = item_kind; +} + +Address & +QueueItem::GetAddress () +{ + return m_address; +} + +void +QueueItem::SetAddress (Address addr) +{ + m_address = addr; +} + +ThreadSP +QueueItem::GetExtendedBacktraceThread (ConstString type) +{ + return ThreadSP(); +} diff --git a/lldb/source/Target/QueueList.cpp b/lldb/source/Target/QueueList.cpp new file mode 100644 index 00000000000..6134f5cc0b2 --- /dev/null +++ b/lldb/source/Target/QueueList.cpp @@ -0,0 +1,102 @@ +//===-- QueueList.cpp -------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "lldb/Target/Process.h" +#include "lldb/Target/Queue.h" +#include "lldb/Target/QueueList.h" + +using namespace lldb; +using namespace lldb_private; + +QueueList::QueueList (Process *process) : + m_process (process), + m_stop_id (0), + m_queues (), + m_mutex () +{ +} + +QueueList::~QueueList () +{ + Clear(); +} + +uint32_t +QueueList::GetSize () +{ + Mutex::Locker locker (m_mutex); + return m_queues.size(); +} + +lldb::QueueSP +QueueList::GetQueueAtIndex (uint32_t idx) +{ + Mutex::Locker locker (m_mutex); + if (idx < m_queues.size()) + { + return m_queues[idx]; + } + else + { + return QueueSP(); + } +} + +void +QueueList::Clear () +{ + Mutex::Locker locker (m_mutex); + m_queues.clear(); +} + +void +QueueList::AddQueue (QueueSP queue_sp) +{ + Mutex::Locker locker (m_mutex); + if (queue_sp.get ()) + { + m_queues.push_back (queue_sp); + } +} + +lldb::QueueSP +QueueList::FindQueueByID (lldb::queue_id_t qid) +{ + QueueSP ret; + for (QueueSP queue_sp : Queues()) + { + if (queue_sp->GetID() == qid) + { + ret = queue_sp; + break; + } + } + return ret; +} + +lldb::QueueSP +QueueList::FindQueueByIndexID (uint32_t index_id) +{ + QueueSP ret; + for (QueueSP queue_sp : Queues()) + { + if (queue_sp->GetIndexID() == index_id) + { + ret = queue_sp; + break; + } + } + return ret; +} + +lldb_private::Mutex & +QueueList::GetMutex () +{ + return m_mutex; +} |