The Pedigree Project 0.1
Log.h
1/*
2 * Copyright (c) 2008-2014, Pedigree Developers
3 *
4 * Please see the CONTRIB file in the root of the source tree for a full
5 * list of contributors.
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#ifndef KERNEL_LOG_H
21#define KERNEL_LOG_H
22#include "pedigree/kernel/Spinlock.h"
23#include "pedigree/kernel/compiler.h"
24#include "pedigree/kernel/process/WaitQueue.h"
25#include "pedigree/kernel/processor/types.h"
26#include "pedigree/kernel/time/Time.h"
27#include "pedigree/kernel/utilities/StaticCord.h"
28#include "pedigree/kernel/utilities/StaticString.h"
29
30#include <config.h>
31
32class String;
33class StringView;
34class Cord;
35class Thread;
36
41
42#define LOG_AT_LEVEL(level, text, lock) \
43 do { \
44 Log::LogEntry __log_macro_logentry; \
45 __log_macro_logentry << level << text; \
46 if (!lock) \
47 __log_macro_logentry << Unlocked; \
48 Log::instance().addEntry(__log_macro_logentry, lock); \
49 } while (0)
50
51#if LOGGING
52
54#if DEBUG_LOGGING
55#define DEBUG_LOG(text) LOG_AT_LEVEL(Log::Debug, text, 1)
56#define DEBUG_LOG_NOLOCK(text) LOG_AT_LEVEL(Log::Debug, text, 0)
57#else
58#define DEBUG_LOG(text)
59#define DEBUG_LOG_NOLOCK(text)
60#endif
61
63#define NOTICE(text) LOG_AT_LEVEL(Log::Notice, text, 1)
64#define NOTICE_NOLOCK(text) LOG_AT_LEVEL(Log::Notice, text, 0)
65
67#define WARNING(text) LOG_AT_LEVEL(Log::Warning, text, 1)
68#define WARNING_NOLOCK(text) LOG_AT_LEVEL(Log::Warning, text, 0)
69
71#define ERROR(text) LOG_AT_LEVEL(Log::Error, text, 1)
72#define ERROR_NOLOCK(text) LOG_AT_LEVEL(Log::Error, text, 0)
73
78#define FATAL(text) \
79 do { \
80 LOG_AT_LEVEL(Log::Fatal, text, 1); \
81 while (1) \
82 ; \
83 } while (0)
84#define FATAL_NOLOCK(text) \
85 do { \
86 LOG_AT_LEVEL(Log::Fatal, text, 0); \
87 while (1) \
88 ; \
89 } while (0)
90
91#if PEDANTIC_PEDIGREE
92#define PEDANTRY FATAL
93#else
94#define PEDANTRY WARNING
95#endif
96
97#else // LOGGING
98
99#define DEBUG_LOG(text)
100#define DEBUG_LOG_NOLOCK(text)
101#define NOTICE(text)
102#define NOTICE_NOLOCK(text)
103#define WARNING(text)
104#define WARNING_NOLOCK(text)
105#define ERROR(text)
106#define ERROR_NOLOCK(text)
107#define FATAL(text)
108#define FATAL_NOLOCK(text)
109#define PEDANTRY(text)
110
111#endif
112
114#define LOG_LENGTH 128
116// 64K static log buffer
117#define LOG_ENTRIES ((1 << 16) / sizeof(LogEntry))
119#define LOG_CALLBACK_COUNT 16
120
130
138
139// Function pointer to update boot progress -
140// Description.
141typedef void (*BootProgressUpdateFn)(const char*);
142
143extern size_t g_BootProgressCurrent;
144extern size_t g_BootProgressTotal;
145extern BootProgressUpdateFn g_BootProgressUpdate;
146
147extern void installSerialLogger();
148
155class Log {
156 public:
157 struct LogEntry;
158
160 class EXPORTED_PUBLIC LogCallback {
161 public:
162 virtual void callback(const LogCord& cord, bool locked = true) = 0;
163 virtual ~LogCallback();
164 };
165
167 enum SeverityLevel { Debug = 0, Notice, Warning, Error, Fatal };
168
173
176 EXPORTED_PUBLIC static Log& instance();
177
179 void initialise1();
180
182 void initialise2();
183
190 EXPORTED_PUBLIC bool installCallback(LogCallback* pCallback, bool bSkipBacklog = false);
191
200 EXPORTED_PUBLIC bool removeCallback(LogCallback* pCallback);
201
203 EXPORTED_PUBLIC void addEntry(const LogEntry& entry, bool lock = true);
204
207 size_t getStaticEntryCount() const;
210 size_t getDynamicEntryCount() const;
211
214 struct EXPORTED_PUBLIC LogEntry {
216 LogEntry();
217
219 unsigned int timestamp;
227 bool lockfree = false;
229 bool showTimestamp = true;
230
234 LogEntry& operator<<(const char*);
235 template <size_t N>
236 LogEntry& operator<<(const char (&str)[N]) {
237 str.appendBytes(str, N);
238 return *this;
239 }
240 LogEntry& operator<<(const String&);
241 LogEntry& operator<<(const StringView&);
242 LogEntry& operator<<(const Cord&);
243 template <size_t N>
244 LogEntry& operator<<(const StaticString<N>& s) {
245 str.appendBytes(s, s.length());
246 return *this;
247 }
248 LogEntry& operator<<(const TinyStaticString&);
249 LogEntry& operator<<(const NormalStaticString&);
250 LogEntry& operator<<(const LargeStaticString&);
251 LogEntry& operator<<(const HugeStaticString&);
255 LogEntry& operator<<(char* append_str);
258 LogEntry& operator<<(bool b);
261 template <class T>
263 // Preserve the current number type but always print pointers as
264 // hex.
265 NumberType currentNumberType = numberType;
266 return (*this) << Hex << (reinterpret_cast<uintptr_t>(p)) << currentNumberType;
267 }
270 template <class T>
272
274 LogEntry& operator<<(SeverityLevel level);
276 LogEntry& operator<<(NumberType type);
277 LogEntry& operator<<(LogEntryModifier modifier);
278 };
279
283
285 const StaticLogEntry& getStaticEntry(size_t n) const;
287 const DynamicLogEntry& getDynamicEntry(size_t n) const;
288
290 EXPORTED_PUBLIC size_t copyText(char* buffer, size_t capacity);
291
292 static constexpr size_t textCapacity() {
293 return LOG_ENTRIES * (LOG_LENGTH + 4);
294 }
295
296 bool echoToSerial();
297
298 const LogEntry& getLatestEntry() const;
299
300 void enableTimestamps();
301 void disableTimestamps();
302
303#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
304 using CallbackPinHook = void (*)(LogCallback* callback);
305 using EntrySnapshotHook = void (*)(const LogEntry& entry);
306
307 EXPORTED_PUBLIC static void setCallbackPinHook(CallbackPinHook hook);
308 EXPORTED_PUBLIC static void setEntrySnapshotHook(EntrySnapshotHook hook);
309#endif
310
311 private:
313 LogCallback* callback;
314 size_t inFlight;
315 size_t removers;
316 bool enabled;
317 };
318
319 struct CallbackPin {
320 CallbackSlot* slot;
321 LogCallback* callback;
322 void* owner;
323 CallbackPin* next;
324 };
325
327 Log();
329 ~Log();
332 Log(const Log&);
335 Log& operator=(const Log&);
336
337 const NormalStaticString& getTimestamp();
338
339 const TinyStaticString& severityToString(SeverityLevel level) const;
340
341 size_t snapshotCallbacks(CallbackPin pins[LOG_CALLBACK_COUNT]);
342 bool pinCallback(CallbackSlot* slot, CallbackPin& pin);
343 bool callbackEnabled(const CallbackPin& pin);
344 void releaseCallback(CallbackPin& pin);
345 void dispatchCallbacks(CallbackPin pins[LOG_CALLBACK_COUNT], size_t count, const LogCord& message,
346 bool locked);
347 void dispatchCallback(CallbackSlot* slot, const LogCord& message, bool locked);
348 void* currentCallbackOwner();
349 bool isCallbackContext(void* owner);
350 void clearCallback(CallbackSlot* slot);
351
355 // Vector<DynamicLogEntry*> m_DynamicLog;
358
359 size_t m_StaticEntryStart, m_StaticEntryEnd;
360
363
366 CallbackSlot m_OutputCallbacks[LOG_CALLBACK_COUNT];
367 CallbackPin* m_ActiveCallbackPins;
368 size_t m_nOutputCallbacks;
369
371 EXPORTED_PUBLIC static Log m_Instance;
372
375
378
381
384
386 Time::Timestamp m_LastTime;
387
390
393 static TinyStaticString m_NoticeSeverityString;
394 static TinyStaticString m_WarningSeverityString;
395 static TinyStaticString m_ErrorSeverityString;
396 static TinyStaticString m_FatalSeverityString;
397
400
403 static TinyStaticString m_DedupeTail;
404
405#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
406 static CallbackPinHook m_CallbackPinHook;
407 static EntrySnapshotHook m_EntrySnapshotHook;
408#endif
409};
410
413#endif
Definition Cord.h:33
the kernel's log
Definition Log.h:155
StaticLogEntry m_StaticLog[LOG_ENTRIES]
Definition Log.h:353
~Log()
Definition Log.cc:109
Spinlock m_Lock
Definition Log.h:172
size_t getStaticEntryCount() const
Definition Log.cc:428
size_t m_HashMatchedCount
Definition Log.h:380
void initialise1()
Definition Log.cc:121
bool m_EchoToSerial
Definition Log.h:362
NormalStaticString m_CachedTimestamp
Definition Log.h:389
static TinyStaticString m_DebugSeverityString
Definition Log.h:392
SeverityLevel m_LastEntrySeverity
Definition Log.h:377
void initialise2()
Definition Log.cc:138
EXPORTED_PUBLIC bool removeCallback(LogCallback *pCallback)
Definition Log.cc:228
Log(const Log &)
EXPORTED_PUBLIC void addEntry(const LogEntry &entry, bool lock=true)
Definition Log.cc:602
const StaticLogEntry & getStaticEntry(size_t n) const
Definition Log.cc:436
LogEntry StaticLogEntry
Definition Log.h:281
Log & operator=(const Log &)
static TinyStaticString m_LineEnding
Definition Log.h:399
static NormalStaticString m_DedupeHead
Definition Log.h:402
size_t getDynamicEntryCount() const
Definition Log.cc:432
Time::Timestamp m_LastTime
Definition Log.h:386
static EXPORTED_PUBLIC Log & instance()
Definition Log.cc:117
SeverityLevel
Definition Log.h:167
uint64_t m_LastEntryHash
Definition Log.h:374
EXPORTED_PUBLIC bool installCallback(LogCallback *pCallback, bool bSkipBacklog=false)
Definition Log.cc:145
size_t m_StaticEntries
Definition Log.h:357
bool m_Timestamps
Definition Log.h:383
const DynamicLogEntry & getDynamicEntry(size_t n) const
Definition Log.cc:440
EXPORTED_PUBLIC size_t copyText(char *buffer, size_t capacity)
Definition Log.cc:444
WaitQueue m_CallbackWaiters
Definition Log.h:365
Log()
Definition Log.cc:85
static EXPORTED_PUBLIC Log m_Instance
Definition Log.h:371
#define LOG_ENTRIES
Definition Log.h:117
LogEntryModifier
Definition Log.h:132
#define LOG_CALLBACK_COUNT
Definition Log.h:119
#define LOG_LENGTH
Definition Log.h:114
NumberType
Definition Log.h:122
@ Unlocked
Definition Log.h:134
@ NoTimestamp
Definition Log.h:136
@ Oct
Definition Log.h:128
@ Dec
Definition Log.h:126
@ Hex
Definition Log.h:124
LogEntry & operator<<(T n)
LogEntry & operator<<(T *p)
Definition Log.h:262
unsigned int timestamp
Definition Log.h:219
SeverityLevel severity
Definition Log.h:221
NumberType numberType
Definition Log.h:225
StaticString< LOG_LENGTH > str
Definition Log.h:223