compiler-context-analysys: Add __cond_releases()

Useful for things like unlock fastpaths, which on success release the
lock.

Suggested-by: Marco Elver <elver@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Marco Elver <elver@google.com>
Link: https://patch.msgid.link/20260121111213.634625032@infradead.org
master
Peter Zijlstra 2026-01-20 13:40:30 +01:00
parent 25500ba7e7
commit 07574b8eba
1 changed files with 32 additions and 0 deletions

View File

@ -320,6 +320,38 @@ static inline void _context_unsafe_alias(void **p) { }
*/
#define __releases(...) __releases_ctx_lock(__VA_ARGS__)
/*
* Clang's analysis does not care precisely about the value, only that it is
* either zero or non-zero. So the __cond_acquires() interface might be
* misleading if we say that @ret is the value returned if acquired. Instead,
* provide symbolic variants which we translate.
*/
#define __cond_acquires_impl_not_true(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
#define __cond_acquires_impl_not_false(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
#define __cond_acquires_impl_not_nonzero(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
#define __cond_acquires_impl_not_0(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
#define __cond_acquires_impl_not_nonnull(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x)
#define __cond_acquires_impl_not_NULL(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x)
/**
* __cond_releases() - function attribute, function conditionally
* releases a context lock exclusively
* @ret: abstract value returned by function if context lock releases
* @x: context lock instance pointer
*
* Function attribute declaring that the function conditionally releases the
* given context lock instance @x exclusively. The associated context(s) must
* be active on entry. The function return value @ret denotes when the context
* lock is released.
*
* @ret may be one of: true, false, nonzero, 0, nonnull, NULL.
*
* NOTE: clang does not have a native attribute for this; instead implement
* it as an unconditional release and a conditional acquire for the
* inverted condition -- which is semantically equivalent.
*/
#define __cond_releases(ret, x) __releases(x) __cond_acquires_impl_not_##ret(x)
/**
* __acquire() - function to acquire context lock exclusively
* @x: context lock instance pointer