Как работает безблокировочное увеличение в «сокращенном» LDD3? - PullRequest
0 голосов
/ 11 июня 2019

Мне трудно понять, как работает 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;
}

...