Re: rwlock(9) and mutex(9) definitions

From: Konstantin Belousov <kostikbel_at_gmail.com>
Date: Wed, 27 Oct 2021 02:06:52 UTC
On Wed, Oct 27, 2021 at 05:03:56AM +0300, Konstantin Belousov wrote:
> On Tue, Oct 26, 2021 at 06:52:21PM -0700, Gleb Smirnoff wrote:
> >   Hi,
> > 
> > [To: list constructed with help of git blame]
> > 
> > despite manual pages describe locking functions as voids in
> > reality some of them (not all) are preprocessor defines wrapped
> > in "do {} while (0)".
> > 
> > Such wraps don't really behave as a true void. For example you
> > can not tail call them:
> > 
> > void
> > smartass_lock(lock, clue)
> > {
> > 	if (clue)
> > 		return (rw_rlock(lock));
> > 	else
> > 		return (rw_wlock(lock));
> > }
> > 
> > This will fail on rw_wlock, but not on rw_rlock. However, if you
> > have WITNESS it will compile correctly :)
> > 
> > So, we need either make these function "static inline void" in
> > mtx.h and rwlock.h, or wrap them in __extension__ ({ }). Btw, the
> > latter is already done for mtx_trylock_spin() by kib in 90b581f2cc327.
> > Of course for try-lock functions inability of tail call is a bigger
> > issue then for voids. However, voids should be fixed as well, I believe.
> > 
> > Your call? "static inline" or "__extension__ ({ })"?
> 
> Usually defines are easier.  For static inline functions, compiler parses
> and validates the definition regardless of its use.  So for instance if
> the header is included into userspace compilation consumers, static inlines
> break.
> 
> If not that, providing real parseable definitions are better on all other
> counters.

That said, you seems to use wrong syntax for your example.  Might be, it
is enough to fix that, and not change the definition?

void
something(bool clue)
{
 	if (clue) {
 		rw_rlock(lock);
 	else
		rw_wlock(lock);
}
Both rw_rlock and rw_wlock are in tail context.  You cannot _return_ void.