blob: 6211e22589dd0eb59752be4886a37690935ec070 [file] [log] [blame]
brians343bc112013-02-10 01:53:46 +00001#ifndef AOS_ATOM_CODE_LOGGING_LOGGING_H_
2#define AOS_ATOM_CODE_LOGGING_LOGGING_H_
3
4// IWYU pragma: private, include "aos/common/logging/logging.h"
5
6#ifndef AOS_COMMON_LOGGING_LOGGING_H_
7#error This file may only be #included through common/logging/logging.h!!!
8#endif
9
10#include "aos/aos_core.h"
11
12#ifdef __cplusplus
13extern "C" {
14#endif
15
16int log_init(const char *name);
17// WARNING: THIS LEAKS MEMORY AND SHARED MEMORY
18void log_uninit(void);
19
20extern log_level log_min;
21
22// The basic structure that goes into the shared memory queue.
23// It is packed so the pid_t at the front is at the same location as
24// the one in log_crio_message.
25typedef struct log_message_t_ {
26 pid_t source;
27 log_level level;
28 char message[LOG_MESSAGE_LEN];
29 char name[40];
30 struct timespec time;
31 uint8_t sequence; // per process
32} __attribute__((packed)) log_message;
33
34#ifdef __cplusplus
35#define LOG_BOOL bool
36#else
37#define LOG_BOOL uint8_t
38#endif
39extern LOG_BOOL log_initted;
40#undef LOG_BOOL
41
42// Unless explicitly stated otherwise, format must always be a string constant
43// and args are printf-style arguments for format.
44// The validitiy of format and args together will be checked at compile time
45// using a gcc function attribute.
46
47// Logs the specified thing.
48#define LOG(level, format, args...) do { \
49 if (level >= log_min) { \
50 log_do(level, LOG_SOURCENAME ": " STRINGIFY(__LINE__) ": " format, ##args); \
51 } \
52} while (0)
53// Allows "bottling up" multiple log fragments which can then all be logged in
54// one message with LOG_UNCORK.
55// format does not have to be a constant
56#define LOG_CORK(format, args...) do { \
57 log_cork(__LINE__, format, ##args); \
58} while (0)
59// Actually logs all of the saved up log fragments (including format and args on
60// the end).
61#define LOG_UNCORK(level, format, args...) do { \
62 log_uncork(__LINE__, level, LOG_SOURCENAME ": %d-%d: ", format, ##args); \
63} while (0)
64// Makes a normal logging call if possible or just prints it out on stderr.
65#define LOG_IFINIT(level, format, args...) do{ \
66 if(log_initted) { \
67 LOG(level, format, args); \
68 } else { \
69 fprintf(stderr, "%s-noinit: " format, log_str(level), ##args); \
70 } \
71}while(0)
72
73// All functions return 0 for success and - for error.
74
75// Actually implements the basic logging call.
76// Does not check that level is valid.
77// TODO(brians): Fix this so it works with clang.
78int log_do(log_level level, const char *format, ...)
79 __attribute__((format(gnu_printf, 2, 3)));
80
81// TODO(brians): Fix this so it works with clang.
82int log_cork(int line, const char *format, ...)
83 __attribute__((format(gnu_printf, 2, 3)));
84// Implements the uncork logging call.
85// IMPORTANT: begin_format must have 2 %d formats as its only 2 format specifiers
86// which will get passed the minimum and maximum line numbers that have been
87// corked into this call.
88// TODO(brians): Fix this so it works with clang.
89int log_uncork(int line, log_level level, const char *begin_format,
90 const char *format, ...)
91 __attribute__((format(gnu_printf, 4, 5)));
92
93const log_message *log_read_next1(int flags);
94const log_message *log_read_next2(int flags, int *index);
95inline const log_message *log_read_next(void) { return log_read_next1(BLOCK); }
96void log_free_message(const log_message *msg);
97
98// The structure that is actually in the shared memory queue.
99union log_queue_message {
100 log_message atom;
101 log_crio_message crio;
102};
103
104#ifdef __cplusplus
105}
106#endif
107
108#endif
109