Messages in this thread | | | From | Linus Torvalds <> | Date | Fri, 24 Mar 2017 13:58:53 -0700 | Subject | Re: locking/atomic: Introduce atomic_try_cmpxchg() |
| |
On Fri, Mar 24, 2017 at 1:46 PM, Peter Zijlstra <peterz@infradead.org> wrote: > > I certainly like it better, but so far I'm having trouble reproducing > your results. What compiler version are you on?
I have:
gcc version 6.3.1 20161221 (Red Hat 6.3.1-1) (GCC)
from
gcc-6.3.1-1.fc24.x86_64
and I'm attaching the edited form of your test-case, just so that we're on the exact same page.
Linus /* gcc -Os -std=gnu99 -fno-strict-overflow -falign-jumps=1 -falign-loops=1 -c tiny.c; objdump -dr tiny.o */
typedef _Bool bool;
#define try_cmpxchg(ptr, value, new, success_label) ({ \ bool __txchg_success; \ __typeof__(*(ptr)) __old; \ asm volatile("lock cmpxchgl %3, %1" \ : "=@ccz" (__txchg_success), \ "+m" (*ptr), \ "=a" (__old) \ : "r" (new), \ "2" (value) \ : "memory"); \ if (likely(__txchg_success)) goto success_label;\ __old; })
#define EXCEPTION_VALUE(val, handler) asm volatile ("ud2 # %0" : : "r" (val))
#define UINT_MAX (~0U)
#define likely(x) __builtin_expect(!!(x), 1) #define unlikely(x) __builtin_expect(!!(x), 0)
static inline void refcount_inc(unsigned int *r) { unsigned int new, val = *(unsigned int volatile *)r;
for (;;) { if (unlikely(val == UINT_MAX)) /* saturated */ return;
if (unlikely(!val)) /* use-after-free */ goto exception;
/* cannot overflow because we already checked UINT_MAX */ new = val + 1; val = try_cmpxchg(r, val, new, success); }
success: return;
exception: EXCEPTION_VALUE(val, __refcount_warn); }
void T_refcount_inc(unsigned int *r) { refcount_inc(r); }
| |