003 File Manager
Current Path:
/usr/src/contrib/llvm-project/compiler-rt/lib/xray
usr
/
src
/
contrib
/
llvm-project
/
compiler-rt
/
lib
/
xray
/
📁
..
📄
weak_symbols.txt
(88 B)
📄
xray_AArch64.cpp
(4.62 KB)
📄
xray_allocator.h
(9.33 KB)
📄
xray_always_instrument.txt
(255 B)
📄
xray_arm.cpp
(5.87 KB)
📄
xray_basic_flags.cpp
(1.52 KB)
📄
xray_basic_flags.h
(1.18 KB)
📄
xray_basic_flags.inc
(1011 B)
📄
xray_basic_logging.cpp
(17.59 KB)
📄
xray_basic_logging.h
(1.68 KB)
📄
xray_buffer_queue.cpp
(7.35 KB)
📄
xray_buffer_queue.h
(8.79 KB)
📄
xray_defs.h
(967 B)
📄
xray_fdr_controller.h
(11.79 KB)
📄
xray_fdr_flags.cpp
(1.47 KB)
📄
xray_fdr_flags.h
(1.2 KB)
📄
xray_fdr_flags.inc
(1.28 KB)
📄
xray_fdr_log_records.h
(2.5 KB)
📄
xray_fdr_log_writer.h
(8.72 KB)
📄
xray_fdr_logging.cpp
(27.62 KB)
📄
xray_fdr_logging.h
(1.53 KB)
📄
xray_flags.cpp
(2.76 KB)
📄
xray_flags.h
(1.12 KB)
📄
xray_flags.inc
(2.29 KB)
📄
xray_function_call_trie.h
(22.36 KB)
📄
xray_init.cpp
(4.6 KB)
📄
xray_interface.cpp
(16.43 KB)
📄
xray_interface_internal.h
(3.2 KB)
📄
xray_log_interface.cpp
(7.53 KB)
📄
xray_mips.cpp
(7.16 KB)
📄
xray_mips64.cpp
(7.66 KB)
📄
xray_never_instrument.txt
(282 B)
📄
xray_powerpc64.cpp
(3.63 KB)
📄
xray_powerpc64.inc
(1019 B)
📄
xray_profile_collector.cpp
(14.06 KB)
📄
xray_profile_collector.h
(2.73 KB)
📄
xray_profiling.cpp
(17.55 KB)
📄
xray_profiling_flags.cpp
(1.34 KB)
📄
xray_profiling_flags.h
(1.17 KB)
📄
xray_profiling_flags.inc
(1.4 KB)
📄
xray_recursion_guard.h
(1.8 KB)
📄
xray_segmented_array.h
(21.22 KB)
📄
xray_trampoline_AArch64.S
(6.1 KB)
📄
xray_trampoline_arm.S
(3.85 KB)
📄
xray_trampoline_mips.S
(2.67 KB)
📄
xray_trampoline_mips64.S
(3.47 KB)
📄
xray_trampoline_powerpc64.cpp
(420 B)
📄
xray_trampoline_powerpc64_asm.S
(3.91 KB)
📄
xray_trampoline_x86_64.S
(7.06 KB)
📄
xray_tsc.h
(2.75 KB)
📄
xray_utils.cpp
(6.04 KB)
📄
xray_utils.h
(2.18 KB)
📄
xray_x86_64.cpp
(11.73 KB)
📄
xray_x86_64.inc
(997 B)
Editing: xray_fdr_log_writer.h
//===-- xray_fdr_log_writer.h ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This file is a part of XRay, a function call tracing system. // //===----------------------------------------------------------------------===// #ifndef COMPILER_RT_LIB_XRAY_XRAY_FDR_LOG_WRITER_H_ #define COMPILER_RT_LIB_XRAY_XRAY_FDR_LOG_WRITER_H_ #include "xray_buffer_queue.h" #include "xray_fdr_log_records.h" #include <functional> #include <tuple> #include <type_traits> #include <utility> namespace __xray { template <size_t Index> struct SerializerImpl { template <class Tuple, typename std::enable_if< Index<std::tuple_size< typename std::remove_reference<Tuple>::type>::value, int>::type = 0> static void serializeTo(char *Buffer, Tuple &&T) { auto P = reinterpret_cast<const char *>(&std::get<Index>(T)); constexpr auto Size = sizeof(std::get<Index>(T)); internal_memcpy(Buffer, P, Size); SerializerImpl<Index + 1>::serializeTo(Buffer + Size, std::forward<Tuple>(T)); } template <class Tuple, typename std::enable_if< Index >= std::tuple_size<typename std::remove_reference< Tuple>::type>::value, int>::type = 0> static void serializeTo(char *, Tuple &&) {} }; using Serializer = SerializerImpl<0>; template <class Tuple, size_t Index> struct AggregateSizesImpl { static constexpr size_t value = sizeof(typename std::tuple_element<Index, Tuple>::type) + AggregateSizesImpl<Tuple, Index - 1>::value; }; template <class Tuple> struct AggregateSizesImpl<Tuple, 0> { static constexpr size_t value = sizeof(typename std::tuple_element<0, Tuple>::type); }; template <class Tuple> struct AggregateSizes { static constexpr size_t value = AggregateSizesImpl<Tuple, std::tuple_size<Tuple>::value - 1>::value; }; template <MetadataRecord::RecordKinds Kind, class... DataTypes> MetadataRecord createMetadataRecord(DataTypes &&... Ds) { static_assert(AggregateSizes<std::tuple<DataTypes...>>::value <= sizeof(MetadataRecord) - 1, "Metadata payload longer than metadata buffer!"); MetadataRecord R; R.Type = 1; R.RecordKind = static_cast<uint8_t>(Kind); Serializer::serializeTo(R.Data, std::make_tuple(std::forward<DataTypes>(Ds)...)); return R; } class FDRLogWriter { BufferQueue::Buffer &Buffer; char *NextRecord = nullptr; template <class T> void writeRecord(const T &R) { internal_memcpy(NextRecord, reinterpret_cast<const char *>(&R), sizeof(T)); NextRecord += sizeof(T); // We need this atomic fence here to ensure that other threads attempting to // read the bytes in the buffer will see the writes committed before the // extents are updated. atomic_thread_fence(memory_order_release); atomic_fetch_add(Buffer.Extents, sizeof(T), memory_order_acq_rel); } public: explicit FDRLogWriter(BufferQueue::Buffer &B, char *P) : Buffer(B), NextRecord(P) { DCHECK_NE(Buffer.Data, nullptr); DCHECK_NE(NextRecord, nullptr); } explicit FDRLogWriter(BufferQueue::Buffer &B) : FDRLogWriter(B, static_cast<char *>(B.Data)) {} template <MetadataRecord::RecordKinds Kind, class... Data> bool writeMetadata(Data &&... Ds) { // TODO: Check boundary conditions: // 1) Buffer is full, and cannot handle one metadata record. // 2) Buffer queue is finalising. writeRecord(createMetadataRecord<Kind>(std::forward<Data>(Ds)...)); return true; } template <size_t N> size_t writeMetadataRecords(MetadataRecord (&Recs)[N]) { constexpr auto Size = sizeof(MetadataRecord) * N; internal_memcpy(NextRecord, reinterpret_cast<const char *>(Recs), Size); NextRecord += Size; // We need this atomic fence here to ensure that other threads attempting to // read the bytes in the buffer will see the writes committed before the // extents are updated. atomic_thread_fence(memory_order_release); atomic_fetch_add(Buffer.Extents, Size, memory_order_acq_rel); return Size; } enum class FunctionRecordKind : uint8_t { Enter = 0x00, Exit = 0x01, TailExit = 0x02, EnterArg = 0x03, }; bool writeFunction(FunctionRecordKind Kind, int32_t FuncId, int32_t Delta) { FunctionRecord R; R.Type = 0; R.RecordKind = uint8_t(Kind); R.FuncId = FuncId; R.TSCDelta = Delta; writeRecord(R); return true; } bool writeFunctionWithArg(FunctionRecordKind Kind, int32_t FuncId, int32_t Delta, uint64_t Arg) { // We need to write the function with arg into the buffer, and then // atomically update the buffer extents. This ensures that any reads // synchronised on the buffer extents record will always see the writes // that happen before the atomic update. FunctionRecord R; R.Type = 0; R.RecordKind = uint8_t(Kind); R.FuncId = FuncId; R.TSCDelta = Delta; MetadataRecord A = createMetadataRecord<MetadataRecord::RecordKinds::CallArgument>(Arg); NextRecord = reinterpret_cast<char *>(internal_memcpy( NextRecord, reinterpret_cast<char *>(&R), sizeof(R))) + sizeof(R); NextRecord = reinterpret_cast<char *>(internal_memcpy( NextRecord, reinterpret_cast<char *>(&A), sizeof(A))) + sizeof(A); // We need this atomic fence here to ensure that other threads attempting to // read the bytes in the buffer will see the writes committed before the // extents are updated. atomic_thread_fence(memory_order_release); atomic_fetch_add(Buffer.Extents, sizeof(R) + sizeof(A), memory_order_acq_rel); return true; } bool writeCustomEvent(int32_t Delta, const void *Event, int32_t EventSize) { // We write the metadata record and the custom event data into the buffer // first, before we atomically update the extents for the buffer. This // allows us to ensure that any threads reading the extents of the buffer // will only ever see the full metadata and custom event payload accounted // (no partial writes accounted). MetadataRecord R = createMetadataRecord<MetadataRecord::RecordKinds::CustomEventMarker>( EventSize, Delta); NextRecord = reinterpret_cast<char *>(internal_memcpy( NextRecord, reinterpret_cast<char *>(&R), sizeof(R))) + sizeof(R); NextRecord = reinterpret_cast<char *>( internal_memcpy(NextRecord, Event, EventSize)) + EventSize; // We need this atomic fence here to ensure that other threads attempting to // read the bytes in the buffer will see the writes committed before the // extents are updated. atomic_thread_fence(memory_order_release); atomic_fetch_add(Buffer.Extents, sizeof(R) + EventSize, memory_order_acq_rel); return true; } bool writeTypedEvent(int32_t Delta, uint16_t EventType, const void *Event, int32_t EventSize) { // We do something similar when writing out typed events, see // writeCustomEvent(...) above for details. MetadataRecord R = createMetadataRecord<MetadataRecord::RecordKinds::TypedEventMarker>( EventSize, Delta, EventType); NextRecord = reinterpret_cast<char *>(internal_memcpy( NextRecord, reinterpret_cast<char *>(&R), sizeof(R))) + sizeof(R); NextRecord = reinterpret_cast<char *>( internal_memcpy(NextRecord, Event, EventSize)) + EventSize; // We need this atomic fence here to ensure that other threads attempting to // read the bytes in the buffer will see the writes committed before the // extents are updated. atomic_thread_fence(memory_order_release); atomic_fetch_add(Buffer.Extents, EventSize, memory_order_acq_rel); return true; } char *getNextRecord() const { return NextRecord; } void resetRecord() { NextRecord = reinterpret_cast<char *>(Buffer.Data); atomic_store(Buffer.Extents, 0, memory_order_release); } void undoWrites(size_t B) { DCHECK_GE(NextRecord - B, reinterpret_cast<char *>(Buffer.Data)); NextRecord -= B; atomic_fetch_sub(Buffer.Extents, B, memory_order_acq_rel); } }; // namespace __xray } // namespace __xray #endif // COMPILER-RT_LIB_XRAY_XRAY_FDR_LOG_WRITER_H_
Upload File
Create Folder