-
Notifications
You must be signed in to change notification settings - Fork 199
/
Copy pathlogfile.c
102 lines (82 loc) · 2.02 KB
/
logfile.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
/*
* logfile.c
*
* printf-style interface to a log file.
*
* Written & released by Keir Fraser <[email protected]>
*
* This is free and unencumbered software released into the public domain.
* See the file COPYING for more details, or visit <http://unlicense.org>.
*/
/* We buffer logging in a ring buffer. */
static char ring[2048];
#define MASK(x) ((x)&(sizeof(ring)-1))
static unsigned int cons, prod;
/* Shut loggers up while we are sending to the logging file. */
static bool_t quiesce;
int vprintk(const char *format, va_list ap)
{
static char str[128];
char *p, c;
int n;
IRQ_global_disable();
n = vsnprintf(str, sizeof(str), format, ap);
if (quiesce)
goto out;
p = str;
while ((c = *p++) != '\0') {
switch (c) {
case '\r': /* CR: ignore as we generate our own CR/LF */
break;
case '\n': /* LF: convert to CR/LF (usual terminal behaviour) */
ring[MASK(prod++)] = '\r';
/* fall through */
default:
ring[MASK(prod++)] = c;
break;
}
}
out:
IRQ_global_enable();
return n;
}
int printk(const char *format, ...)
{
va_list ap;
int n;
va_start(ap, format);
n = vprintk(format, ap);
va_end(ap);
return n;
}
void logfile_flush(FIL *file)
{
unsigned int nr;
char msg[20];
F_open(file, "FFLOG.TXT", FA_OPEN_APPEND|FA_WRITE);
quiesce = TRUE;
barrier();
if ((unsigned int)(prod-cons) > sizeof(ring)) {
nr = prod - cons - sizeof(ring);
snprintf(msg, sizeof(msg), "\r\n[lost %u]\r\n", nr);
F_write(file, msg, strlen(msg), NULL);
cons += nr;
}
while (cons != prod) {
nr = min_t(unsigned int, prod-cons, sizeof(ring)-MASK(cons));
F_write(file, &ring[MASK(cons)], nr, NULL);
cons += nr;
}
barrier();
quiesce = FALSE;
F_close(file);
}
/*
* Local variables:
* mode: C
* c-file-style: "Linux"
* c-basic-offset: 4
* tab-width: 4
* indent-tabs-mode: nil
* End:
*/