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);
}

Reply via email to