On Wed, Jul 08, 2020 at 05:09:30PM +0200, Ahmed S. Darwish wrote:
> On Wed, Jul 08, 2020 at 02:29:38PM +0200, Peter Zijlstra wrote:

> > How about something disguisting like this then?
> >
> ...
> > #define __SEQ_RT    IS_BUILTIN(CONFIG_PREEMPT_RT)
> >
> > SEQCOUNT_LOCKTYPE(raw_spinlock, raw_spinlock_t,     false,          lock)
> > SEQCOUNT_LOCKTYPE(spinlock, spinlock_t,             __SEQ_RT,       lock)
> > SEQCOUNT_LOCKTYPE(rwlock,   rwlock_t,               __SEQ_RT,       lock)
> > SEQCOUNT_LOCKTYPE(mutex,    struct mutex,           true,           lock)
> > SEQCOUNT_LOCKTYPE(ww_mutex, struct ww_mutex,        true,           
> > lock->base)
> >
> > #if (defined(CONFIG_CC_IS_GCC) && CONFIG_GCC_VERSION < 40900) || 
> > defined(__CHECKER__)
> >
> > #define __seqprop_pick(const_expr, s, locktype, prop, otherwise)    \
> >     __builtin_choose_expr(const_expr,                               \
> >                           __seqprop_##locktype##_##prop((void *)(s)), \
> >                           otherwise)
> >
> > extern void __seqprop_invalid(void);
> >
> > #define __seqprop(s, prop)                                                  
> >         \
> >     __seqprop_pick(__same_type(*(s), seqcount_t), (s), seqcount, prop,      
> >         \
> >       __seqprop_pick(__same_type(*(s), seqcount_raw_spinlock_t), (s), 
> > raw_spinlock, prop, \
> >         __seqprop_pick(__same_type(*(s), seqcount_spinlock_t), (s), 
> > spinlock, prop, \
> >           __seqprop_pick(__same_type(*(s), seqcount_rwlock_t), (s), rwlock, 
> > prop,   \
> >             __seqprop_pick(__same_type(*(s), seqcount_mutex_t), (s), mutex, 
> > prop,   \
> >               __seqprop_pick(__same_type(*(s), seqcount_ww_mutex_t), (s), 
> > ww_mutex, prop, \
> >                 __seqprop_invalid()))))))
> >
> > #else
> >
> > #define __seqprop_case(s, locktype, prop) \
> >     seqcount_##locktype##_t: __seqprop_##locktype##_##prop((void *)s)
> >
> > #define __seqprop(s, prop)                                  \
> >     _Generic(*(s),                                          \
> >              seqcount_t: __seqprop_seqcount_##prop((void*)s),\
> >              __seqprop_case((s), raw_spinlock, prop),       \
> >              __seqprop_case((s), spinlock, prop),           \
> >              __seqprop_case((s), rwlock, prop),             \
> >              __seqprop_case((s), mutex, prop),              \
> >              __seqprop_case((s), ww_mutex, prop))
> >
> > #endif
> >
> > #define __to_seqcount_t(s)                  __seqprop(s, ptr)
> > #define __associated_lock_is_preemptible(s) __seqprop(s, preempt)
> > #define __assert_associated_lock_held(s)    __seqprop(s, assert)
> 
> Hmm, I'll prototype the whole thing (along with PREEMPT_RT associated
> lock()/unlock() as you've mentioned in the other e-mail), and come back.
> 
> Honestly, I have a first impression that this is heading into too much
> complexity and compaction, but let's finish the whole thing first.

So the thing I pasted compiles kernel/sched/cputime.o, but that only
uses the old seqcount_t thing, not any of the fancy new stuff, still the
compiler groks it all.

And while the gcc-4.8 code is horrendous crap, the rest should be pretty
straight forward and concentrates on the pieces where there are
differences.

I even considered:

#define __SEQPROP(name, prop, expr) \
static __always_inline __seqprop_##prop##_t \
__seqprop##name##_##prop(seqcount##name##_t *s) \
{ \
        expr; \
}

Such that we could write:

__SEQPROP(, ptr, return s)
__SEQPROP(, preempt, return false)
__SEQPROP(, assert, )

__SEQPROP(_##locktype, ptr, return &s->seqcount) \
__SEQPROP(_##locktype, preempt, return preempt) \
__SEQPROP(_##locktype, assert, 
__SEQCOUNT_LOCKDEP(lockdep_assert_held(s->lockmember))) \

But I figured _that_ might've been one step too far ;-)

Reply via email to