On Wed, Jul 29, 2020 at 01:11:20PM +0200, pet...@infradead.org wrote: > Subject: locking/refcount: Provide __refcount API to obtain the old value > From: Peter Zijlstra <pet...@infradead.org> > Date: Wed Jul 29 13:00:57 CEST 2020 > > David requested means to obtain the old/previous value from the > refcount API for tracing purposes. > > Duplicate (most of) the API as __refcount*() with an additional > 'int *' argument into which, if !NULL, the old value will be stored. > > Requested-by: David Howells <dhowe...@redhat.com> > Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org> > --- > include/linux/refcount.h | 65 > +++++++++++++++++++++++++++++++++++++++++------ > 1 file changed, 57 insertions(+), 8 deletions(-) > > --- a/include/linux/refcount.h > +++ b/include/linux/refcount.h > @@ -165,7 +165,7 @@ static inline unsigned int refcount_read > * > * Return: false if the passed refcount is 0, true otherwise > */ > -static inline __must_check bool refcount_add_not_zero(int i, refcount_t *r) > +static inline __must_check bool __refcount_add_not_zero(int i, refcount_t > *r, int *oldp) > { > int old = refcount_read(r); > > @@ -174,12 +174,20 @@ static inline __must_check bool refcount > break; > } while (!atomic_try_cmpxchg_relaxed(&r->refs, &old, old + i)); > > + if (oldp) > + *oldp = old; > + > if (unlikely(old < 0 || old + i < 0)) > refcount_warn_saturate(r, REFCOUNT_ADD_NOT_ZERO_OVF); > > return old; > } > > +static inline __must_check bool refcount_add_not_zero(int i, refcount_t *r) > +{ > + return __refcount_add_not_zero(i, r, NULL); > +}
so, I could also emulate C++'s bool refcount_add_not_zero(int i, refcount_t *r, int *oldp = NULL) style by going to town on this with a bunch of CPP magic, but I don't think that'll actually make things clearer. It'll look something like: #define __REF_ARGS(_0, _1, _2, _3, _n, X...) _n #define REG_ARGS(X...) __REF_ARGS(, ##X, 3, 2, 1, 0) #define __REF_CONCAT(a, b) a ## b #define REF_CONCAT(a, b) __REF_CONCAT(a, b) #define REF_UNARY_2(func, arg1, arg2) func(arg1, arg2) #define REF_UNARY_1(func, arg1) func(arg1, NULL) #define REF_UNARY(func, X...) REF_CONCAT(REF_UNARY_, REF_ARGS(X))(func, X) #define REF_BINARY_3(func, arg1, arg2, arg3) func(arg1, arg2, arg3) #define REF_BINARY_2(func, arg1, arg2) func(arg1, arg2, NULL) #define REF_BINARY(func, X...) REF_CONCAT(REF_BINARY_, REF_ARGS(X))(func, X) #define refcount_add(X...) REF_BINARY(__refcount_add, X) #define refcount_inc(X...) REF_UNARY(__refcount_inc, X) Opinions?