btrfs: [] on the end of a struct field is a variable length array.
[haiku.git] / headers / private / kernel / tracing.h
blobacad6bc6366fa062c0491ecb053a306c3ab8d070
1 /*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
4 * Distributed under the terms of the MIT License.
5 */
6 #ifndef KERNEL_TRACING_H
7 #define KERNEL_TRACING_H
10 #include <SupportDefs.h>
11 #include <KernelExport.h>
13 #include <stdarg.h>
14 #include <stdio.h>
16 #include "tracing_config.h"
19 struct trace_entry {
20 uint32 size : 13; // actual size is *4
21 uint32 previous_size : 13; // actual size is *4
22 uint32 flags : 6;
25 struct tracing_stack_trace {
26 int32 depth;
27 addr_t return_addresses[0];
31 #ifdef __cplusplus
33 #include <new>
36 // trace output flags
37 #define TRACE_OUTPUT_TEAM_ID 0x01
38 // print the team ID
39 #define TRACE_OUTPUT_DIFF_TIME 0x02
40 // print the difference time to the previously printed entry instead of the
41 // absolute time
44 class TraceOutput {
45 public:
46 TraceOutput(char* buffer, size_t bufferSize, uint32 flags);
48 void Clear();
49 void Print(const char* format,...)
50 __attribute__ ((format (__printf__, 2, 3)));
51 void PrintArgs(const char* format, va_list args);
52 void PrintStackTrace(tracing_stack_trace* stackTrace);
53 bool IsFull() const { return fSize >= fCapacity; }
55 char* Buffer() const { return fBuffer; }
56 size_t Capacity() const { return fCapacity; }
57 size_t Size() const { return fSize; }
59 uint32 Flags() const { return fFlags; }
61 void SetLastEntryTime(bigtime_t time);
62 bigtime_t LastEntryTime() const;
64 private:
65 char* fBuffer;
66 size_t fCapacity;
67 size_t fSize;
68 uint32 fFlags;
69 bigtime_t fLastEntryTime;
73 class TraceEntry {
74 public:
75 TraceEntry();
76 virtual ~TraceEntry();
78 virtual void Dump(TraceOutput& out);
79 virtual void DumpStackTrace(TraceOutput& out);
81 size_t Size() const { return ToTraceEntry()->size; }
82 uint16 Flags() const { return ToTraceEntry()->flags; }
84 void Initialized();
86 void* operator new(size_t size, const std::nothrow_t&) throw();
88 trace_entry* ToTraceEntry() const
90 return (trace_entry*)this - 1;
93 static TraceEntry* FromTraceEntry(trace_entry* entry)
95 return (TraceEntry*)(entry + 1);
100 class AbstractTraceEntry : public TraceEntry {
101 public:
102 AbstractTraceEntry()
104 _Init();
107 // dummy, ignores all arguments
108 AbstractTraceEntry(size_t, size_t, bool)
110 _Init();
113 virtual ~AbstractTraceEntry();
115 virtual void Dump(TraceOutput& out);
117 virtual void AddDump(TraceOutput& out);
119 thread_id ThreadID() const { return fThread; }
120 thread_id TeamID() const { return fTeam; }
121 bigtime_t Time() const { return fTime; }
123 protected:
124 typedef AbstractTraceEntry TraceEntryBase;
126 private:
127 void _Init();
129 protected:
130 thread_id fThread;
131 team_id fTeam;
132 bigtime_t fTime;
136 class AbstractTraceEntryWithStackTrace : public AbstractTraceEntry {
137 public:
138 AbstractTraceEntryWithStackTrace(size_t stackTraceDepth,
139 size_t skipFrames, bool kernelOnly);
141 virtual void DumpStackTrace(TraceOutput& out);
143 tracing_stack_trace* StackTrace() const
145 return fStackTrace;
148 protected:
149 typedef AbstractTraceEntryWithStackTrace TraceEntryBase;
151 private:
152 tracing_stack_trace* fStackTrace;
156 template<bool stackTraceDepth>
157 struct AbstractTraceEntrySelector {
158 typedef AbstractTraceEntryWithStackTrace Type;
162 template<>
163 struct AbstractTraceEntrySelector<0> {
164 typedef AbstractTraceEntry Type;
168 #define TRACE_ENTRY_SELECTOR(stackTraceDepth) \
169 AbstractTraceEntrySelector<stackTraceDepth>::Type
172 class LazyTraceOutput : public TraceOutput {
173 public:
174 LazyTraceOutput(char* buffer, size_t bufferSize, uint32 flags)
175 : TraceOutput(buffer, bufferSize, flags)
179 const char* DumpEntry(const TraceEntry* entry)
181 if (Size() == 0) {
182 const_cast<TraceEntry*>(entry)->Dump(*this);
183 // Dump() should probably be const
186 return Buffer();
191 class TraceFilter {
192 public:
193 virtual ~TraceFilter();
195 virtual bool Filter(const TraceEntry* entry, LazyTraceOutput& out);
197 public:
198 union {
199 thread_id fThread;
200 team_id fTeam;
201 const char* fString;
202 uint64 fValue;
203 struct {
204 TraceFilter* first;
205 TraceFilter* second;
206 } fSubFilters;
211 class WrapperTraceFilter : public TraceFilter {
212 public:
213 virtual void Init(TraceFilter* filter, int direction, bool continued) = 0;
217 class TraceEntryIterator {
218 public:
219 TraceEntryIterator()
221 fEntry(NULL),
222 fIndex(0)
226 void Reset()
228 fEntry = NULL;
229 fIndex = 0;
232 int32 Index() const
234 return fIndex;
237 TraceEntry* Current() const
239 return fEntry != NULL ? TraceEntry::FromTraceEntry(fEntry) : NULL;
242 TraceEntry* Next();
243 TraceEntry* Previous();
244 TraceEntry* MoveTo(int32 index);
246 private:
247 trace_entry* _NextNonBufferEntry(trace_entry* entry);
248 trace_entry* _PreviousNonBufferEntry(trace_entry* entry);
250 private:
251 trace_entry* fEntry;
252 int32 fIndex;
256 inline void
257 TraceOutput::Print(const char* format,...)
259 va_list args;
260 va_start(args, format);
261 PrintArgs(format, args);
262 va_end(args);
266 int dump_tracing(int argc, char** argv, WrapperTraceFilter* wrapperFilter);
268 bool tracing_is_entry_valid(AbstractTraceEntry* entry,
269 bigtime_t entryTime = -1);
271 #endif // __cplusplus
274 #ifdef __cplusplus
275 extern "C" {
276 #endif
278 uint8* alloc_tracing_buffer(size_t size);
279 uint8* alloc_tracing_buffer_memcpy(const void* source, size_t size, bool user);
280 char* alloc_tracing_buffer_strcpy(const char* source, size_t maxSize,
281 bool user);
283 struct tracing_stack_trace* capture_tracing_stack_trace(int32 maxCount,
284 int32 skipFrames, bool kernelOnly);
285 addr_t tracing_find_caller_in_stack_trace(
286 struct tracing_stack_trace* stackTrace, const addr_t excludeRanges[],
287 uint32 excludeRangeCount);
288 void tracing_print_stack_trace(struct tracing_stack_trace* stackTrace);
290 void lock_tracing_buffer();
291 void unlock_tracing_buffer();
292 status_t tracing_init(void);
294 void _user_ktrace_output(const char *message);
296 #ifdef __cplusplus
298 #endif
300 #endif /* KERNEL_TRACING_H */