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
163 class EXPORTED_PUBLIC LogCallback {
164 public:
165 virtual void callback(const LogCord& cord, bool locked = true) = 0;
166 virtual ~LogCallback();
167 };
168
170 enum SeverityLevel { Debug = 0, Notice, Warning, Error, Fatal };
171
176
179 EXPORTED_PUBLIC static Log& instance();
180
182 void initialise1();
183
185 void initialise2();
186
193 EXPORTED_PUBLIC bool installCallback(LogCallback* pCallback, bool bSkipBacklog = false);
194
203 EXPORTED_PUBLIC bool removeCallback(LogCallback* pCallback);
204
206 EXPORTED_PUBLIC void addEntry(const LogEntry& entry, bool lock = true);
207
210 size_t getStaticEntryCount() const;
213 size_t getDynamicEntryCount() const;
214
217 struct EXPORTED_PUBLIC LogEntry {
219 LogEntry();
220
222 unsigned int timestamp;
230 bool lockfree = false;
232 bool showTimestamp = true;
233
237 LogEntry& operator<<(const char*);
238 template <size_t N>
239 LogEntry& operator<<(const char (&str)[N]) {
240 str.appendBytes(str, N);
241 return *this;
242 }
243 LogEntry& operator<<(const String&);
244 LogEntry& operator<<(const StringView&);
245 LogEntry& operator<<(const Cord&);
246 template <size_t N>
247 LogEntry& operator<<(const StaticString<N>& s) {
248 str.appendBytes(s, s.length());
249 return *this;
250 }
251 LogEntry& operator<<(const TinyStaticString&);
252 LogEntry& operator<<(const NormalStaticString&);
253 LogEntry& operator<<(const LargeStaticString&);
254 LogEntry& operator<<(const HugeStaticString&);
258 LogEntry& operator<<(char* append_str);
261 LogEntry& operator<<(bool b);
264 template <class T>
266 // Preserve the current number type but always print pointers as
267 // hex.
268 NumberType currentNumberType = numberType;
269 return (*this) << Hex << (reinterpret_cast<uintptr_t>(p)) << currentNumberType;
270 }
273 template <class T>
275
277 LogEntry& operator<<(SeverityLevel level);
279 LogEntry& operator<<(NumberType type);
280 LogEntry& operator<<(LogEntryModifier modifier);
281 };
282
286
288 const StaticLogEntry& getStaticEntry(size_t n) const;
290 const DynamicLogEntry& getDynamicEntry(size_t n) const;
291
293 EXPORTED_PUBLIC size_t copyText(char* buffer, size_t capacity);
294
295 static constexpr size_t textCapacity() {
296 return LOG_ENTRIES * (LOG_LENGTH + 4);
297 }
298
299 bool echoToSerial();
300
301 const LogEntry& getLatestEntry() const;
302
303 void enableTimestamps();
304 void disableTimestamps();
305
306#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
307 using CallbackPinHook = void (*)(LogCallback* callback);
308 using EntrySnapshotHook = void (*)(const LogEntry& entry);
309
310 EXPORTED_PUBLIC static void setCallbackPinHook(CallbackPinHook hook);
311 EXPORTED_PUBLIC static void setEntrySnapshotHook(EntrySnapshotHook hook);
312#endif
313
314 private:
316 LogCallback* callback;
317 size_t inFlight;
318 size_t removers;
319 bool enabled;
320 };
321
322 struct CallbackPin {
323 CallbackSlot* slot;
324 LogCallback* callback;
325 void* owner;
326 CallbackPin* next;
327 };
328
330 Log();
332 ~Log();
335 Log(const Log&);
338 Log& operator=(const Log&);
339
340 const NormalStaticString& getTimestamp();
341
342 const TinyStaticString& severityToString(SeverityLevel level) const;
343
344 size_t snapshotCallbacks(CallbackPin pins[LOG_CALLBACK_COUNT]);
345 bool pinCallback(CallbackSlot* slot, CallbackPin& pin);
346 bool callbackEnabled(const CallbackPin& pin);
347 void releaseCallback(CallbackPin& pin);
348 void dispatchCallbacks(CallbackPin pins[LOG_CALLBACK_COUNT], size_t count, const LogCord& message,
349 bool locked);
350 void dispatchCallback(CallbackSlot* slot, const LogCord& message, bool locked);
351 void* currentCallbackOwner();
352 bool isCallbackContext(void* owner);
353 void clearCallback(CallbackSlot* slot);
354
358 // Vector<DynamicLogEntry*> m_DynamicLog;
361
362 size_t m_StaticEntryStart, m_StaticEntryEnd;
363
366
369 CallbackSlot m_OutputCallbacks[LOG_CALLBACK_COUNT];
370 CallbackPin* m_ActiveCallbackPins;
371 size_t m_nOutputCallbacks;
372
374 EXPORTED_PUBLIC static Log m_Instance;
375
378
381
384
387
389 Time::Timestamp m_LastTime;
390
393
396 static TinyStaticString m_NoticeSeverityString;
397 static TinyStaticString m_WarningSeverityString;
398 static TinyStaticString m_ErrorSeverityString;
399 static TinyStaticString m_FatalSeverityString;
400
403
406 static TinyStaticString m_DedupeTail;
407
408#if HOSTED && PEDIGREE_HOSTED_SMOKE_TESTS
409 static CallbackPinHook m_CallbackPinHook;
410 static EntrySnapshotHook m_EntrySnapshotHook;
411#endif
412};
413
416#endif
Definition Cord.h:33
the kernel's log
Definition Log.h:155
StaticLogEntry m_StaticLog[LOG_ENTRIES]
Definition Log.h:356
~Log()
Definition Log.cc:109
Spinlock m_Lock
Definition Log.h:175
size_t getStaticEntryCount() const
Definition Log.cc:438
size_t m_HashMatchedCount
Definition Log.h:383
void initialise1()
Definition Log.cc:121
bool m_EchoToSerial
Definition Log.h:365
NormalStaticString m_CachedTimestamp
Definition Log.h:392
static TinyStaticString m_DebugSeverityString
Definition Log.h:395
SeverityLevel m_LastEntrySeverity
Definition Log.h:380
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:612
const StaticLogEntry & getStaticEntry(size_t n) const
Definition Log.cc:446
LogEntry StaticLogEntry
Definition Log.h:284
Log & operator=(const Log &)
static TinyStaticString m_LineEnding
Definition Log.h:402
static NormalStaticString m_DedupeHead
Definition Log.h:405
size_t getDynamicEntryCount() const
Definition Log.cc:442
Time::Timestamp m_LastTime
Definition Log.h:389
static EXPORTED_PUBLIC Log & instance()
Definition Log.cc:117
SeverityLevel
Definition Log.h:170
uint64_t m_LastEntryHash
Definition Log.h:377
EXPORTED_PUBLIC bool installCallback(LogCallback *pCallback, bool bSkipBacklog=false)
Definition Log.cc:145
size_t m_StaticEntries
Definition Log.h:360
bool m_Timestamps
Definition Log.h:386
const DynamicLogEntry & getDynamicEntry(size_t n) const
Definition Log.cc:450
EXPORTED_PUBLIC size_t copyText(char *buffer, size_t capacity)
Definition Log.cc:454
WaitQueue m_CallbackWaiters
Definition Log.h:368
Log()
Definition Log.cc:85
static EXPORTED_PUBLIC Log m_Instance
Definition Log.h:374
#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:265
unsigned int timestamp
Definition Log.h:222
SeverityLevel severity
Definition Log.h:224
NumberType numberType
Definition Log.h:228
StaticString< LOG_LENGTH > str
Definition Log.h:226