1 // Copyright 2017 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #pragma once 6 7 #include <trace-provider/handler.h> 8 9 #include <lib/async/cpp/wait.h> 10 #include <lib/zx/fifo.h> 11 #include <lib/zx/vmo.h> 12 #include <fbl/intrusive_hash_table.h> 13 #include <fbl/macros.h> 14 #include <fbl/string.h> 15 #include <fbl/unique_ptr.h> 16 #include <fbl/vector.h> 17 #include <lib/zircon-internal/fnv1hash.h> 18 19 namespace trace { 20 namespace internal { 21 22 class Session final : public trace::TraceHandler { 23 public: 24 static void StartEngine(async_dispatcher_t* dispatcher, 25 trace_buffering_mode_t buffering_mode, 26 zx::vmo buffer, zx::fifo fifo, 27 fbl::Vector<fbl::String> enabled_categories); 28 static void StopEngine(); 29 30 private: 31 Session(void* buffer, size_t buffer_num_bytes, zx::fifo fifo, 32 fbl::Vector<fbl::String> enabled_categories); 33 ~Session() override; 34 35 // |trace::TraceHandler| 36 bool IsCategoryEnabled(const char* category) override; 37 void TraceStarted() override; 38 void TraceStopped(async_dispatcher_t* dispatcher, 39 zx_status_t disposition, size_t buffer_bytes_written) override; 40 // This is called in streaming mode to notify the trace manager that 41 // buffer |buffer_number| is full and needs to be saved. 42 void NotifyBufferFull(uint32_t wrapped_count, uint64_t durable_data_end) 43 override; 44 45 void HandleFifo(async_dispatcher_t* dispatcher, async::WaitBase* wait, 46 zx_status_t status, 47 const zx_packet_signal_t* signal); 48 bool ReadFifoMessage(); 49 50 // This is called in streaming mode when TraceManager reports back that 51 // it has saved the buffer. 52 static zx_status_t MarkBufferSaved(uint32_t wrapped_count, 53 uint64_t durable_data_end); 54 55 void* buffer_; 56 size_t buffer_num_bytes_; 57 zx::fifo fifo_; 58 async::WaitMethod<Session, &Session::HandleFifo> fifo_wait_; 59 fbl::Vector<fbl::String> const enabled_categories_; 60 61 using CString = const char*; 62 63 // For faster implementation of IsCategoryEnabled(). 64 struct StringSetEntry : public fbl::SinglyLinkedListable< 65 fbl::unique_ptr<StringSetEntry>> { StringSetEntryStringSetEntry66 StringSetEntry(const CString& string) 67 : string(string) {} 68 69 const CString string; 70 71 // Used by the hash table. GetHashStringSetEntry72 static size_t GetHash(CString key) { 73 return fnv1a64str(key); 74 } 75 }; 76 77 // We want to work with C strings here, but the default implementation 78 // would just compare pointers. 79 struct CategoryStringKeyTraits { GetKeyCategoryStringKeyTraits80 static CString GetKey(const StringSetEntry& obj) { 81 return obj.string; 82 } EqualToCategoryStringKeyTraits83 static bool EqualTo(const CString& key1, const CString& key2) { 84 return strcmp(key1, key2) == 0; 85 } 86 }; 87 88 using StringSet = fbl::HashTable<const char*, 89 fbl::unique_ptr<StringSetEntry>, 90 fbl::SinglyLinkedList<fbl::unique_ptr<StringSetEntry>>, // default 91 size_t, // default 92 37, // default 93 CategoryStringKeyTraits>; 94 StringSet enabled_category_set_; 95 96 DISALLOW_COPY_ASSIGN_AND_MOVE(Session); 97 }; 98 99 } // namespace internal 100 } // namespace trace 101