| // Copyright 2017 The Fuchsia Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #pragma once |
| |
| #include <trace-provider/handler.h> |
| |
| #include <lib/async/cpp/wait.h> |
| #include <lib/zx/fifo.h> |
| #include <lib/zx/vmo.h> |
| #include <fbl/intrusive_hash_table.h> |
| #include <fbl/macros.h> |
| #include <fbl/string.h> |
| #include <fbl/unique_ptr.h> |
| #include <fbl/vector.h> |
| #include <lib/zircon-internal/fnv1hash.h> |
| |
| namespace trace { |
| namespace internal { |
| |
| class Session final : public trace::TraceHandler { |
| public: |
| static void StartEngine(async_dispatcher_t* dispatcher, |
| trace_buffering_mode_t buffering_mode, |
| zx::vmo buffer, zx::fifo fifo, |
| fbl::Vector<fbl::String> enabled_categories); |
| static void StopEngine(); |
| |
| private: |
| Session(void* buffer, size_t buffer_num_bytes, zx::fifo fifo, |
| fbl::Vector<fbl::String> enabled_categories); |
| ~Session() override; |
| |
| // |trace::TraceHandler| |
| bool IsCategoryEnabled(const char* category) override; |
| void TraceStarted() override; |
| void TraceStopped(async_dispatcher_t* dispatcher, |
| zx_status_t disposition, size_t buffer_bytes_written) override; |
| // This is called in streaming mode to notify the trace manager that |
| // buffer |buffer_number| is full and needs to be saved. |
| void NotifyBufferFull(uint32_t wrapped_count, uint64_t durable_data_end) |
| override; |
| |
| void HandleFifo(async_dispatcher_t* dispatcher, async::WaitBase* wait, |
| zx_status_t status, |
| const zx_packet_signal_t* signal); |
| bool ReadFifoMessage(); |
| |
| // This is called in streaming mode when TraceManager reports back that |
| // it has saved the buffer. |
| static zx_status_t MarkBufferSaved(uint32_t wrapped_count, |
| uint64_t durable_data_end); |
| |
| void* buffer_; |
| size_t buffer_num_bytes_; |
| zx::fifo fifo_; |
| async::WaitMethod<Session, &Session::HandleFifo> fifo_wait_; |
| fbl::Vector<fbl::String> const enabled_categories_; |
| |
| using CString = const char*; |
| |
| // For faster implementation of IsCategoryEnabled(). |
| struct StringSetEntry : public fbl::SinglyLinkedListable< |
| fbl::unique_ptr<StringSetEntry>> { |
| StringSetEntry(const CString& string) |
| : string(string) {} |
| |
| const CString string; |
| |
| // Used by the hash table. |
| static size_t GetHash(CString key) { |
| return fnv1a64str(key); |
| } |
| }; |
| |
| // We want to work with C strings here, but the default implementation |
| // would just compare pointers. |
| struct CategoryStringKeyTraits { |
| static CString GetKey(const StringSetEntry& obj) { |
| return obj.string; |
| } |
| static bool EqualTo(const CString& key1, const CString& key2) { |
| return strcmp(key1, key2) == 0; |
| } |
| }; |
| |
| using StringSet = fbl::HashTable<const char*, |
| fbl::unique_ptr<StringSetEntry>, |
| fbl::SinglyLinkedList<fbl::unique_ptr<StringSetEntry>>, // default |
| size_t, // default |
| 37, // default |
| CategoryStringKeyTraits>; |
| StringSet enabled_category_set_; |
| |
| DISALLOW_COPY_ASSIGN_AND_MOVE(Session); |
| }; |
| |
| } // namespace internal |
| } // namespace trace |