diff options
Diffstat (limited to 'include/lldb/Utility')
| -rw-r--r-- | include/lldb/Utility/Connection.h | 212 | ||||
| -rw-r--r-- | include/lldb/Utility/IOObject.h | 56 | ||||
| -rw-r--r-- | include/lldb/Utility/JSON.h | 2 | ||||
| -rw-r--r-- | include/lldb/Utility/StructuredData.h | 556 | ||||
| -rw-r--r-- | include/lldb/Utility/Timer.h | 79 | ||||
| -rw-r--r-- | include/lldb/Utility/TraceOptions.h | 61 |
6 files changed, 965 insertions, 1 deletions
diff --git a/include/lldb/Utility/Connection.h b/include/lldb/Utility/Connection.h new file mode 100644 index 0000000000000..be5641d5fa632 --- /dev/null +++ b/include/lldb/Utility/Connection.h @@ -0,0 +1,212 @@ +//===-- Connection.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_Connection_h_ +#define liblldb_Connection_h_ + +#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "lldb/lldb-enumerations.h" // for ConnectionStatus +#include "lldb/lldb-forward.h" // for IOObjectSP + +#include "llvm/ADT/StringRef.h" // for StringRef + +#include <ratio> // for micro +#include <string> + +#include <stddef.h> // for size_t + +namespace lldb_private { +class Status; +} +namespace lldb_private { +template <typename Ratio> class Timeout; +} + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class Connection Connection.h "lldb/Utility/Connection.h" +/// @brief A communication connection class. +/// +/// A class that implements that actual communication functions for +/// connecting/disconnecting, reading/writing, and waiting for bytes +/// to become available from a two way communication connection. +/// +/// This class is designed to only do very simple communication +/// functions. Instances can be instantiated and given to a +/// Communication class to perform communications where clients can +/// listen for broadcasts, and perform other higher level communications. +//---------------------------------------------------------------------- +class Connection { +public: + //------------------------------------------------------------------ + /// Default constructor + //------------------------------------------------------------------ + Connection() = default; + + //------------------------------------------------------------------ + /// Virtual destructor since this class gets subclassed and handed + /// to a Communication object. + //------------------------------------------------------------------ + virtual ~Connection(); + + //------------------------------------------------------------------ + /// Connect using the connect string \a url. + /// + /// @param[in] url + /// A string that contains all information needed by the + /// subclass to connect to another client. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// appropriate error value if this method returns false. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// \b True if the connect succeeded, \b false otherwise. The + /// internal error object should be filled in with an + /// appropriate value based on the result of this function. + /// + /// @see Status& Communication::GetError (); + //------------------------------------------------------------------ + virtual lldb::ConnectionStatus Connect(llvm::StringRef url, + Status *error_ptr) = 0; + + //------------------------------------------------------------------ + /// Disconnect the communications connection if one is currently + /// connected. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// appropriate error value if this method returns false. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// \b True if the disconnect succeeded, \b false otherwise. The + /// internal error object should be filled in with an + /// appropriate value based on the result of this function. + /// + /// @see Status& Communication::GetError (); + //------------------------------------------------------------------ + virtual lldb::ConnectionStatus Disconnect(Status *error_ptr) = 0; + + //------------------------------------------------------------------ + /// Check if the connection is valid. + /// + /// @return + /// \b True if this object is currently connected, \b false + /// otherwise. + //------------------------------------------------------------------ + virtual bool IsConnected() const = 0; + + //------------------------------------------------------------------ + /// The read function that attempts to read from the connection. + /// + /// @param[in] dst + /// A destination buffer that must be at least \a dst_len bytes + /// long. + /// + /// @param[in] dst_len + /// The number of bytes to attempt to read, and also the max + /// number of bytes that can be placed into \a dst. + /// + /// @param[in] timeout + /// The number of microseconds to wait for the data. + /// + /// @param[out] status + /// On return, indicates whether the call was successful or terminated + /// due to some error condition. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// appropriate error value if this method returns zero. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// The number of bytes actually read. + /// + /// @see size_t Communication::Read (void *, size_t, uint32_t); + //------------------------------------------------------------------ + virtual size_t Read(void *dst, size_t dst_len, + const Timeout<std::micro> &timeout, + lldb::ConnectionStatus &status, Status *error_ptr) = 0; + + //------------------------------------------------------------------ + /// The actual write function that attempts to write to the + /// communications protocol. + /// + /// Subclasses must override this function. + /// + /// @param[in] dst + /// A desination buffer that must be at least \a dst_len bytes + /// long. + /// + /// @param[in] dst_len + /// The number of bytes to attempt to write, and also the + /// number of bytes are currently available in \a dst. + /// + /// @param[out] error_ptr + /// A pointer to an error object that should be given an + /// appropriate error value if this method returns zero. This + /// value can be NULL if the error value should be ignored. + /// + /// @return + /// The number of bytes actually Written. + //------------------------------------------------------------------ + virtual size_t Write(const void *dst, size_t dst_len, + lldb::ConnectionStatus &status, Status *error_ptr) = 0; + + //------------------------------------------------------------------ + /// Returns a URI that describes this connection object + /// + /// Subclasses may override this function. + /// + /// @return + /// Returns URI or an empty string if disconnecteds + //------------------------------------------------------------------ + virtual std::string GetURI() = 0; + + //------------------------------------------------------------------ + /// Interrupts an ongoing Read() operation. + /// + /// If there is an ongoing read operation in another thread, this operation + /// return with status == eConnectionStatusInterrupted. Note that if there + /// data waiting to be read and an interrupt request is issued, the Read() + /// function will return the data immediately without processing the + /// interrupt request (which will remain queued for the next Read() + /// operation). + /// + /// @return + /// Returns true is the interrupt request was successful. + //------------------------------------------------------------------ + virtual bool InterruptRead() = 0; + + //------------------------------------------------------------------ + /// Returns the underlying IOObject used by the Connection. + /// + /// The IOObject can be used to wait for data to become available + /// on the connection. If the Connection does not use IOObjects (and + /// hence does not support waiting) this function should return a + /// null pointer. + /// + /// @return + /// The underlying IOObject used for reading. + //------------------------------------------------------------------ + virtual lldb::IOObjectSP GetReadObject() { return lldb::IOObjectSP(); } + +private: + //------------------------------------------------------------------ + // For Connection only + //------------------------------------------------------------------ + DISALLOW_COPY_AND_ASSIGN(Connection); +}; + +} // namespace lldb_private + +#endif // liblldb_Connection_h_ diff --git a/include/lldb/Utility/IOObject.h b/include/lldb/Utility/IOObject.h new file mode 100644 index 0000000000000..61f288183850b --- /dev/null +++ b/include/lldb/Utility/IOObject.h @@ -0,0 +1,56 @@ +//===-- IOObject.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_Host_Common_IOObject_h_ +#define liblldb_Host_Common_IOObject_h_ + +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> + +#include "lldb/lldb-private.h" + +namespace lldb_private { + +class IOObject { +public: + typedef enum { + eFDTypeFile, // Other FD requiring read/write + eFDTypeSocket, // Socket requiring send/recv + } FDType; + + // TODO: On Windows this should be a HANDLE, and wait should use + // WaitForMultipleObjects + typedef int WaitableHandle; + static const WaitableHandle kInvalidHandleValue; + + IOObject(FDType type, bool should_close) + : m_fd_type(type), m_should_close_fd(should_close) {} + virtual ~IOObject(); + + virtual Status Read(void *buf, size_t &num_bytes) = 0; + virtual Status Write(const void *buf, size_t &num_bytes) = 0; + virtual bool IsValid() const = 0; + virtual Status Close() = 0; + + FDType GetFdType() const { return m_fd_type; } + + virtual WaitableHandle GetWaitableHandle() = 0; + +protected: + FDType m_fd_type; + bool m_should_close_fd; // True if this class should close the file descriptor + // when it goes away. + +private: + DISALLOW_COPY_AND_ASSIGN(IOObject); +}; +} // namespace lldb_private + +#endif diff --git a/include/lldb/Utility/JSON.h b/include/lldb/Utility/JSON.h index bf8ed9afc008d..8bf9c4b37b023 100644 --- a/include/lldb/Utility/JSON.h +++ b/include/lldb/Utility/JSON.h @@ -269,7 +269,7 @@ public: EndOfFile }; - JSONParser(const char *cstr); + JSONParser(llvm::StringRef data); int GetEscapedChar(bool &was_escaped); diff --git a/include/lldb/Utility/StructuredData.h b/include/lldb/Utility/StructuredData.h new file mode 100644 index 0000000000000..2ea5fb98e0555 --- /dev/null +++ b/include/lldb/Utility/StructuredData.h @@ -0,0 +1,556 @@ +//===-- StructuredData.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_StructuredData_h_ +#define liblldb_StructuredData_h_ + +#include "llvm/ADT/StringRef.h" + +#include "lldb/Utility/ConstString.h" +#include "lldb/Utility/FileSpec.h" // for FileSpec +#include "lldb/lldb-enumerations.h" // for StructuredDataType + +#include <cassert> // for assert +#include <cstddef> // for size_t +#include <cstdint> // for uint64_t +#include <functional> +#include <map> +#include <memory> +#include <string> +#include <type_traits> // for move +#include <utility> +#include <vector> + +namespace lldb_private { +class Status; +} +namespace lldb_private { +class Stream; +} + +namespace lldb_private { + +//---------------------------------------------------------------------- +/// @class StructuredData StructuredData.h "lldb/Utility/StructuredData.h" +/// @brief A class which can hold structured data +/// +/// The StructuredData class is designed to hold the data from a JSON +/// or plist style file -- a serialized data structure with dictionaries +/// (maps, hashes), arrays, and concrete values like integers, floating +/// point numbers, strings, booleans. +/// +/// StructuredData does not presuppose any knowledge of the schema for +/// the data it is holding; it can parse JSON data, for instance, and +/// other parts of lldb can iterate through the parsed data set to find +/// keys and values that may be present. +//---------------------------------------------------------------------- + +class StructuredData { +public: + class Object; + class Array; + class Integer; + class Float; + class Boolean; + class String; + class Dictionary; + class Generic; + + typedef std::shared_ptr<Object> ObjectSP; + typedef std::shared_ptr<Array> ArraySP; + typedef std::shared_ptr<Integer> IntegerSP; + typedef std::shared_ptr<Float> FloatSP; + typedef std::shared_ptr<Boolean> BooleanSP; + typedef std::shared_ptr<String> StringSP; + typedef std::shared_ptr<Dictionary> DictionarySP; + typedef std::shared_ptr<Generic> GenericSP; + + class Object : public std::enable_shared_from_this<Object> { + public: + Object(lldb::StructuredDataType t = lldb::eStructuredDataTypeInvalid) + : m_type(t) {} + + virtual ~Object() = default; + + virtual bool IsValid() const { return true; } + + virtual void Clear() { m_type = lldb::eStructuredDataTypeInvalid; } + + lldb::StructuredDataType GetType() const { return m_type; } + + void SetType(lldb::StructuredDataType t) { m_type = t; } + + Array *GetAsArray() { + return ((m_type == lldb::eStructuredDataTypeArray) + ? static_cast<Array *>(this) + : nullptr); + } + + Dictionary *GetAsDictionary() { + return ((m_type == lldb::eStructuredDataTypeDictionary) + ? static_cast<Dictionary *>(this) + : nullptr); + } + + Integer *GetAsInteger() { + return ((m_type == lldb::eStructuredDataTypeInteger) + ? static_cast<Integer *>(this) + : nullptr); + } + + uint64_t GetIntegerValue(uint64_t fail_value = 0) { + Integer *integer = GetAsInteger(); + return ((integer != nullptr) ? integer->GetValue() : fail_value); + } + + Float *GetAsFloat() { + return ((m_type == lldb::eStructuredDataTypeFloat) + ? static_cast<Float *>(this) + : nullptr); + } + + double GetFloatValue(double fail_value = 0.0) { + Float *f = GetAsFloat(); + return ((f != nullptr) ? f->GetValue() : fail_value); + } + + Boolean *GetAsBoolean() { + return ((m_type == lldb::eStructuredDataTypeBoolean) + ? static_cast<Boolean *>(this) + : nullptr); + } + + bool GetBooleanValue(bool fail_value = false) { + Boolean *b = GetAsBoolean(); + return ((b != nullptr) ? b->GetValue() : fail_value); + } + + String *GetAsString() { + return ((m_type == lldb::eStructuredDataTypeString) + ? static_cast<String *>(this) + : nullptr); + } + + llvm::StringRef GetStringValue(const char *fail_value = nullptr) { + String *s = GetAsString(); + if (s) + return s->GetValue(); + + return fail_value; + } + + Generic *GetAsGeneric() { + return ((m_type == lldb::eStructuredDataTypeGeneric) + ? static_cast<Generic *>(this) + : nullptr); + } + + ObjectSP GetObjectForDotSeparatedPath(llvm::StringRef path); + + void DumpToStdout(bool pretty_print = true) const; + + virtual void Dump(Stream &s, bool pretty_print = true) const = 0; + + private: + lldb::StructuredDataType m_type; + }; + + class Array : public Object { + public: + Array() : Object(lldb::eStructuredDataTypeArray) {} + + ~Array() override = default; + + bool + ForEach(std::function<bool(Object *object)> const &foreach_callback) const { + for (const auto &object_sp : m_items) { + if (foreach_callback(object_sp.get()) == false) + return false; + } + return true; + } + + size_t GetSize() const { return m_items.size(); } + + ObjectSP operator[](size_t idx) { + if (idx < m_items.size()) + return m_items[idx]; + return ObjectSP(); + } + + ObjectSP GetItemAtIndex(size_t idx) const { + assert(idx < GetSize()); + if (idx < m_items.size()) + return m_items[idx]; + return ObjectSP(); + } + + template <class IntType> + bool GetItemAtIndexAsInteger(size_t idx, IntType &result) const { + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + if (auto int_value = value_sp->GetAsInteger()) { + result = static_cast<IntType>(int_value->GetValue()); + return true; + } + } + return false; + } + + template <class IntType> + bool GetItemAtIndexAsInteger(size_t idx, IntType &result, + IntType default_val) const { + bool success = GetItemAtIndexAsInteger(idx, result); + if (!success) + result = default_val; + return success; + } + + bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result) const { + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = string_value->GetValue(); + return true; + } + } + return false; + } + + bool GetItemAtIndexAsString(size_t idx, llvm::StringRef &result, + llvm::StringRef default_val) const { + bool success = GetItemAtIndexAsString(idx, result); + if (!success) + result = default_val; + return success; + } + + bool GetItemAtIndexAsString(size_t idx, ConstString &result) const { + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = ConstString(string_value->GetValue()); + return true; + } + } + return false; + } + + bool GetItemAtIndexAsString(size_t idx, ConstString &result, + const char *default_val) const { + bool success = GetItemAtIndexAsString(idx, result); + if (!success) + result.SetCString(default_val); + return success; + } + + bool GetItemAtIndexAsDictionary(size_t idx, Dictionary *&result) const { + result = nullptr; + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + result = value_sp->GetAsDictionary(); + return (result != nullptr); + } + return false; + } + + bool GetItemAtIndexAsArray(size_t idx, Array *&result) const { + result = nullptr; + ObjectSP value_sp = GetItemAtIndex(idx); + if (value_sp.get()) { + result = value_sp->GetAsArray(); + return (result != nullptr); + } + return false; + } + + void Push(ObjectSP item) { m_items.push_back(item); } + + void AddItem(ObjectSP item) { m_items.push_back(item); } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + typedef std::vector<ObjectSP> collection; + collection m_items; + }; + + class Integer : public Object { + public: + Integer(uint64_t i = 0) + : Object(lldb::eStructuredDataTypeInteger), m_value(i) {} + + ~Integer() override = default; + + void SetValue(uint64_t value) { m_value = value; } + + uint64_t GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + uint64_t m_value; + }; + + class Float : public Object { + public: + Float(double d = 0.0) + : Object(lldb::eStructuredDataTypeFloat), m_value(d) {} + + ~Float() override = default; + + void SetValue(double value) { m_value = value; } + + double GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + double m_value; + }; + + class Boolean : public Object { + public: + Boolean(bool b = false) + : Object(lldb::eStructuredDataTypeBoolean), m_value(b) {} + + ~Boolean() override = default; + + void SetValue(bool value) { m_value = value; } + + bool GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + bool m_value; + }; + + class String : public Object { + public: + String() : Object(lldb::eStructuredDataTypeString) {} + explicit String(llvm::StringRef S) + : Object(lldb::eStructuredDataTypeString), m_value(S) {} + + void SetValue(llvm::StringRef S) { m_value = S; } + + llvm::StringRef GetValue() { return m_value; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + std::string m_value; + }; + + class Dictionary : public Object { + public: + Dictionary() : Object(lldb::eStructuredDataTypeDictionary), m_dict() {} + + ~Dictionary() override = default; + + size_t GetSize() const { return m_dict.size(); } + + void ForEach(std::function<bool(ConstString key, Object *object)> const + &callback) const { + for (const auto &pair : m_dict) { + if (callback(pair.first, pair.second.get()) == false) + break; + } + } + + ObjectSP GetKeys() const { + auto object_sp = std::make_shared<Array>(); + collection::const_iterator iter; + for (iter = m_dict.begin(); iter != m_dict.end(); ++iter) { + auto key_object_sp = std::make_shared<String>(); + key_object_sp->SetValue(iter->first.AsCString()); + object_sp->Push(key_object_sp); + } + return object_sp; + } + + ObjectSP GetValueForKey(llvm::StringRef key) const { + ObjectSP value_sp; + if (!key.empty()) { + ConstString key_cs(key); + collection::const_iterator iter = m_dict.find(key_cs); + if (iter != m_dict.end()) + value_sp = iter->second; + } + return value_sp; + } + + bool GetValueForKeyAsBoolean(llvm::StringRef key, bool &result) const { + bool success = false; + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + Boolean *result_ptr = value_sp->GetAsBoolean(); + if (result_ptr) { + result = result_ptr->GetValue(); + success = true; + } + } + return success; + } + template <class IntType> + bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result) const { + ObjectSP value_sp = GetValueForKey(key); + if (value_sp) { + if (auto int_value = value_sp->GetAsInteger()) { + result = static_cast<IntType>(int_value->GetValue()); + return true; + } + } + return false; + } + + template <class IntType> + bool GetValueForKeyAsInteger(llvm::StringRef key, IntType &result, + IntType default_val) const { + bool success = GetValueForKeyAsInteger<IntType>(key, result); + if (!success) + result = default_val; + return success; + } + + bool GetValueForKeyAsString(llvm::StringRef key, + llvm::StringRef &result) const { + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = string_value->GetValue(); + return true; + } + } + return false; + } + + bool GetValueForKeyAsString(llvm::StringRef key, llvm::StringRef &result, + const char *default_val) const { + bool success = GetValueForKeyAsString(key, result); + if (!success) { + if (default_val) + result = default_val; + else + result = llvm::StringRef(); + } + return success; + } + + bool GetValueForKeyAsString(llvm::StringRef key, + ConstString &result) const { + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + if (auto string_value = value_sp->GetAsString()) { + result = ConstString(string_value->GetValue()); + return true; + } + } + return false; + } + + bool GetValueForKeyAsString(llvm::StringRef key, ConstString &result, + const char *default_val) const { + bool success = GetValueForKeyAsString(key, result); + if (!success) + result.SetCString(default_val); + return success; + } + + bool GetValueForKeyAsDictionary(llvm::StringRef key, + Dictionary *&result) const { + result = nullptr; + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + result = value_sp->GetAsDictionary(); + return (result != nullptr); + } + return false; + } + + bool GetValueForKeyAsArray(llvm::StringRef key, Array *&result) const { + result = nullptr; + ObjectSP value_sp = GetValueForKey(key); + if (value_sp.get()) { + result = value_sp->GetAsArray(); + return (result != nullptr); + } + return false; + } + + bool HasKey(llvm::StringRef key) const { + ConstString key_cs(key); + collection::const_iterator search = m_dict.find(key_cs); + return search != m_dict.end(); + } + + void AddItem(llvm::StringRef key, ObjectSP value_sp) { + ConstString key_cs(key); + m_dict[key_cs] = value_sp; + } + + void AddIntegerItem(llvm::StringRef key, uint64_t value) { + AddItem(key, std::make_shared<Integer>(value)); + } + + void AddFloatItem(llvm::StringRef key, double value) { + AddItem(key, std::make_shared<Float>(value)); + } + + void AddStringItem(llvm::StringRef key, llvm::StringRef value) { + AddItem(key, std::make_shared<String>(std::move(value))); + } + + void AddBooleanItem(llvm::StringRef key, bool value) { + AddItem(key, std::make_shared<Boolean>(value)); + } + + void Dump(Stream &s, bool pretty_print = true) const override; + + protected: + typedef std::map<ConstString, ObjectSP> collection; + collection m_dict; + }; + + class Null : public Object { + public: + Null() : Object(lldb::eStructuredDataTypeNull) {} + + ~Null() override = default; + + bool IsValid() const override { return false; } + + void Dump(Stream &s, bool pretty_print = true) const override; + }; + + class Generic : public Object { + public: + explicit Generic(void *object = nullptr) + : Object(lldb::eStructuredDataTypeGeneric), m_object(object) {} + + void SetValue(void *value) { m_object = value; } + + void *GetValue() const { return m_object; } + + bool IsValid() const override { return m_object != nullptr; } + + void Dump(Stream &s, bool pretty_print = true) const override; + + private: + void *m_object; + }; + + static ObjectSP ParseJSON(std::string json_text); + + static ObjectSP ParseJSONFromFile(const FileSpec &file, Status &error); +}; + +} // namespace lldb_private + +#endif // liblldb_StructuredData_h_ diff --git a/include/lldb/Utility/Timer.h b/include/lldb/Utility/Timer.h new file mode 100644 index 0000000000000..c06ac17d344de --- /dev/null +++ b/include/lldb/Utility/Timer.h @@ -0,0 +1,79 @@ +//===-- Timer.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_Timer_h_ +#define liblldb_Timer_h_ + +#include "lldb/lldb-defines.h" // for DISALLOW_COPY_AND_ASSIGN +#include "llvm/Support/Chrono.h" +#include <atomic> +#include <stdint.h> // for uint32_t + +namespace lldb_private { +class Stream; + +//---------------------------------------------------------------------- +/// @class Timer Timer.h "lldb/Utility/Timer.h" +/// @brief A timer class that simplifies common timing metrics. +//---------------------------------------------------------------------- + +class Timer { +public: + class Category { + public: + explicit Category(const char *category_name); + + private: + friend class Timer; + const char *m_name; + std::atomic<uint64_t> m_nanos; + std::atomic<Category *> m_next; + + DISALLOW_COPY_AND_ASSIGN(Category); + }; + + //-------------------------------------------------------------- + /// Default constructor. + //-------------------------------------------------------------- + Timer(Category &category, const char *format, ...) + __attribute__((format(printf, 3, 4))); + + //-------------------------------------------------------------- + /// Destructor + //-------------------------------------------------------------- + ~Timer(); + + void Dump(); + + static void SetDisplayDepth(uint32_t depth); + + static void SetQuiet(bool value); + + static void DumpCategoryTimes(Stream *s); + + static void ResetCategoryTimes(); + +protected: + using TimePoint = std::chrono::steady_clock::time_point; + void ChildDuration(TimePoint::duration dur) { m_child_duration += dur; } + + Category &m_category; + TimePoint m_total_start; + TimePoint::duration m_child_duration{0}; + + static std::atomic<bool> g_quiet; + static std::atomic<unsigned> g_display_depth; + +private: + DISALLOW_COPY_AND_ASSIGN(Timer); +}; + +} // namespace lldb_private + +#endif // liblldb_Timer_h_ diff --git a/include/lldb/Utility/TraceOptions.h b/include/lldb/Utility/TraceOptions.h new file mode 100644 index 0000000000000..325ff74e6f556 --- /dev/null +++ b/include/lldb/Utility/TraceOptions.h @@ -0,0 +1,61 @@ +//===-- TraceOptions.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_TraceOptions_h_ +#define liblldb_TraceOptions_h_ + +#include "lldb/lldb-defines.h" +#include "lldb/lldb-enumerations.h" + +#include "lldb/Utility/StructuredData.h" + +namespace lldb_private { +class TraceOptions { +public: + TraceOptions() : m_trace_params(new StructuredData::Dictionary()) {} + + const StructuredData::DictionarySP &getTraceParams() const { + return m_trace_params; + } + + lldb::TraceType getType() const { return m_type; } + + uint64_t getTraceBufferSize() const { return m_trace_buffer_size; } + + uint64_t getMetaDataBufferSize() const { return m_meta_data_buffer_size; } + + void setTraceParams(const StructuredData::DictionarySP &dict_obj) { + m_trace_params = dict_obj; + } + + void setType(lldb::TraceType type) { m_type = type; } + + void setTraceBufferSize(uint64_t size) { m_trace_buffer_size = size; } + + void setMetaDataBufferSize(uint64_t size) { m_meta_data_buffer_size = size; } + + void setThreadID(lldb::tid_t thread_id) { m_thread_id = thread_id; } + + lldb::tid_t getThreadID() const { return m_thread_id; } + +private: + lldb::TraceType m_type; + uint64_t m_trace_buffer_size; + uint64_t m_meta_data_buffer_size; + lldb::tid_t m_thread_id; + + /// m_trace_params is meant to hold any custom parameters + /// apart from meta buffer size and trace size. + /// The interpretation of such parameters is left to + /// the lldb-server. + StructuredData::DictionarySP m_trace_params; +}; +} + +#endif // liblldb_TraceOptions_h_ |
