]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/xray/xray_buffer_queue.h
MFV r315633, 315635:
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / xray / xray_buffer_queue.h
1 //===-- xray_buffer_queue.h ------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of XRay, a dynamic runtime instrumentation system.
11 //
12 // Defines the interface for a buffer queue implementation.
13 //
14 //===----------------------------------------------------------------------===//
15 #ifndef XRAY_BUFFER_QUEUE_H
16 #define XRAY_BUFFER_QUEUE_H
17
18 #include <atomic>
19 #include <cstdint>
20 #include <deque>
21 #include <mutex>
22 #include <system_error>
23 #include <unordered_set>
24
25 namespace __xray {
26
27 /// BufferQueue implements a circular queue of fixed sized buffers (much like a
28 /// freelist) but is concerned mostly with making it really quick to initialise,
29 /// finalise, and get/return buffers to the queue. This is one key component of
30 /// the "flight data recorder" (FDR) mode to support ongoing XRay function call
31 /// trace collection.
32 class BufferQueue {
33 public:
34   struct Buffer {
35     void *Buffer = nullptr;
36     std::size_t Size = 0;
37   };
38
39 private:
40   std::size_t BufferSize;
41   std::deque<Buffer> Buffers;
42   std::mutex Mutex;
43   std::unordered_set<void *> OwnedBuffers;
44   std::atomic<bool> Finalizing;
45
46 public:
47   /// Initialise a queue of size |N| with buffers of size |B|.
48   BufferQueue(std::size_t B, std::size_t N);
49
50   /// Updates |Buf| to contain the pointer to an appropriate buffer. Returns an
51   /// error in case there are no available buffers to return when we will run
52   /// over the upper bound for the total buffers.
53   ///
54   /// Requirements:
55   ///   - BufferQueue is not finalising.
56   ///
57   /// Returns:
58   ///   - std::errc::not_enough_memory on exceeding MaxSize.
59   ///   - no error when we find a Buffer.
60   ///   - std::errc::state_not_recoverable on finalising BufferQueue.
61   std::error_code getBuffer(Buffer &Buf);
62
63   /// Updates |Buf| to point to nullptr, with size 0.
64   ///
65   /// Returns:
66   ///   - ...
67   std::error_code releaseBuffer(Buffer &Buf);
68
69   bool finalizing() const { return Finalizing.load(std::memory_order_acquire); }
70
71   // Sets the state of the BufferQueue to finalizing, which ensures that:
72   //
73   //   - All subsequent attempts to retrieve a Buffer will fail.
74   //   - All releaseBuffer operations will not fail.
75   //
76   // After a call to finalize succeeds, all subsequent calls to finalize will
77   // fail with std::errc::state_not_recoverable.
78   std::error_code finalize();
79
80   // Cleans up allocated buffers.
81   ~BufferQueue();
82 };
83
84 } // namespace __xray
85
86 #endif // XRAY_BUFFER_QUEUE_H