1. 源代码
static void emit_log_char(char c)
{LOG_BUF(log_end) = c;//复制到log_buf
log_end++;
if (log_end - log_start > log_buf_len)
log_start = log_end - log_buf_len;
if (log_end - con_start > log_buf_len)
con_start = log_end - log_buf_len;
if (logged_chars < log_buf_len)
logged_chars++;
}
2. 分析
LOG_BUF是个环形缓冲区。其中log_start和log_end是两个标志,类似于生产者和消费者。但这里有两个问题:
- log_end超过缓冲区最大长度如何处理?
- 可以看到是通过LOG_BUF的宏处理的,该宏不贴出来了。实际上是用log_end & 0xffffffff(实际数值可能不同)这种形式来保证不数组溢出的。
- 缓冲区满了怎么处理?
- 是通过log_end - log_start来判断处理的。保证log_start到log_end之间的是最后要打印的内容
- log_end一直在增加,超出unsigned long的最大范围怎么办?
- unsigned long不怕溢出。实际中试了下,unsigned long a = 0xffffffff,unsigned long b = 1; 而b - a = 2,与正常反转一样。
与通常的生产者和消费者的代码相比,这段代码不需要取%运算,但log_buf_len必须为2的幂。