无锁递增如何在LDD3的“简短记录”中起作用?

时间:2019-06-11 20:40:56

标签: c linux linux-kernel locking linux-device-driver

我很难理解shortp_incr_bp()的工作方式。在没有自旋锁或信号灯的情况下如何原子地增加? (我不太理解所提供的注释。)如果barrier()不存在会发生什么?优化如何导致不正确的值?这种优化出错的一种方法是什么?

/*
 * Input is managed through a simple circular buffer which, among other things,
 * is allowed to overrun if the reader isn't fast enough.  That makes life simple
 * on the "read" interrupt side, where we don't want to block.
 */
static unsigned long shortp_in_buffer = 0;
static unsigned long volatile shortp_in_head;
static volatile unsigned long shortp_in_tail;

/*
 * Atomically increment an index into "shortp_in_buffer"
 *
 * This function has been carefully written to wrap a pointer into the circular 
 * buffer without ever exposing an incorrect value. The "barrier" call is there 
 * to block compiler optimizations across the other two lines of the function. 
 * Without the barrier, the compiler might decide to optimize out the "new" 
 * variable and assign directly to "*index". That optimization could expose an 
 * incorrect value of the index for a brief period in the case where it wraps. 
 * By taking care to prevent in inconsistent value from ever being visible to 
 * other threads, we can manipulate the circular buffer pointers safely without 
 * locks.
 */
static inline void shortp_incr_bp(volatile unsigned long *index, int delta)
{
    unsigned long new = *index + delta;
    barrier();  /* Don't optimize these two together */
    *index = (new >= (shortp_in_buffer + PAGE_SIZE)) ? shortp_in_buffer : new;
}

0 个答案:

没有答案