On Fri, Mar 24, 2017 at 1:46 PM, Peter Zijlstra <pet...@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); }