From: Olaf Kirch Subject: Use coarser locking for the log buffer blogd claims and releases a mutex for every character it writes into the log buffer. Change parselog to grab the lock once, and release it when done parsing all of the input. Signed-off-by: Olaf Kirch Index: showconsole-1.09/libconsole.c =================================================================== --- showconsole-1.09/libconsole.c +++ showconsole-1.09/libconsole.c 2009-01-26 16:58:00.000000000 +0100 @@ -346,9 +346,8 @@ static volatile ssize_t avail; static inline void resetlog(void) { tail = head = data; avail = 0; } -static inline void storelog(const unsigned char *const buf, const size_t len) +static inline void __storelog(const unsigned char *const buf, const size_t len) { - lock(&llock); if (len > end - tail) { static int be_warned = 0; if (!be_warned) { @@ -360,13 +359,18 @@ static inline void storelog(const unsign memcpy(tail, buf, len); avail = (tail += len) - head; xout: - unlock(&llock); return; } -static inline void addlog(const unsigned char c) +static void storelog(const unsigned char *const buf, const size_t len) { lock(&llock); + __storelog(buf, len); + unlock(&llock); +} + +static inline void __addlog(const unsigned char c) +{ if (end - tail <= 0) { static int be_warned = 0; if (!be_warned) { @@ -378,10 +382,16 @@ static inline void addlog(const unsigned *tail = c; avail = (tail += 1) - head; xout: - unlock(&llock); return; } +static void addlog(const unsigned char c) +{ + lock(&llock); + __addlog(c); + unlock(&llock); +} + static inline void writelog(void) { if (!flog) @@ -492,6 +502,8 @@ static void parselog(unsigned char *buf, ssize_t r = s, up; unsigned char uprt[16]; + lock(&llock); + while (r > 0) { c = (unsigned char)*buf; @@ -506,25 +518,25 @@ static void parselog(unsigned char *buf, case 28 ... 31: nl = 0; spin = 0; - addlog('^'); addlog(c + 64); + __addlog('^'); __addlog(c + 64); break; case '\n': if (spin > 4) /* last spinner line */ - storelog(prog, strlen((char*)prog)); + __storelog(prog, strlen((char*)prog)); nl = 1; line++; spin = 0; - addlog(c); + __addlog(c); break; case '\r': spin++; if (spin < 5) { if (spin > 1) - addlog('\n'); + __addlog('\n'); nl = 1; } if (spin == 5) - storelog((unsigned char*)"\n\n", 24); + __storelog((unsigned char*)"\n\n", 24); break; case 14: case 15: @@ -543,8 +555,8 @@ static void parselog(unsigned char *buf, case 160 ... 255: if (spin < 5) { if (spin == 1 && nl) - addlog('\n'); - addlog(c); + __addlog('\n'); + __addlog(c); } else { /* Seems to be a lengthy spinner line */ static int old = 0; static ssize_t p = 0; @@ -561,14 +573,14 @@ static void parselog(unsigned char *buf, case 127: nl = 0; spin = 0; - addlog('^'); addlog('?'); + __addlog('^'); __addlog('?'); break; case 128 ... 128+26: case 128+28 ... 159: nl = 0; spin = 0; if ((up = snprintf((char*)uprt, sizeof(uprt), "\\%03o", c)) > 0) - storelog(uprt, (size_t)up); + __storelog(uprt, (size_t)up); break; case 128+27: spin = 0; @@ -578,7 +590,7 @@ static void parselog(unsigned char *buf, nl = 0; spin = 0; if ((up = snprintf((char*)uprt, sizeof(uprt), "0x%X", c)) > 0) - storelog(uprt, (size_t)up); + __storelog(uprt, (size_t)up); break; } break; @@ -597,11 +609,11 @@ static void parselog(unsigned char *buf, case 'E': case 'D': if (spin > 4) /* last spinner line */ - storelog(prog, strlen((char*)prog)); + __storelog(prog, strlen((char*)prog)); nl = 1; line++; spin = 0; - addlog('\n'); + __addlog('\n'); break; case '(': state = ESsetG0; @@ -674,11 +686,14 @@ static void parselog(unsigned char *buf, unsigned char echo[64]; ssize_t len; + /* Release the lock while doing IO */ + unlock(&llock); if ((len = snprintf(echo, sizeof(echo), "\033[%lu;%dR", line, nl)) > 0) safeout(fdread, echo, len); else safeout(fdread, "\033R", 2); tcdrain(fdread); + lock(&llock); } break; #endif @@ -686,6 +701,8 @@ static void parselog(unsigned char *buf, buf++; r--; } + + unlock(&llock); } static void copylog(const unsigned char *buf, const size_t s)