|
| #define | __ctx_lock_type(name) |
| |
| #define | __reentrant_ctx_lock |
| |
| #define | __acquires_ctx_lock(...) |
| |
| #define | __acquires_shared_ctx_lock(...) |
| |
| #define | __try_acquires_ctx_lock(ret, var) |
| |
| #define | __try_acquires_shared_ctx_lock(ret, var) |
| |
| #define | __releases_ctx_lock(...) |
| |
| #define | __releases_shared_ctx_lock(...) |
| |
| #define | __assumes_ctx_lock(...) |
| |
| #define | __assumes_shared_ctx_lock(...) |
| |
| #define | __returns_ctx_lock(var) |
| |
| #define | __guarded_by(...) |
| |
| #define | __pt_guarded_by(...) |
| |
| #define | __excludes_ctx_lock(...) |
| |
| #define | __requires_ctx_lock(...) |
| |
| #define | __requires_shared_ctx_lock(...) |
| |
| #define | __acquire_ctx_lock(var) do { } while (0) |
| |
| #define | __acquire_shared_ctx_lock(var) do { } while (0) |
| |
| #define | __try_acquire_ctx_lock(var, ret) (ret) |
| |
| #define | __try_acquire_shared_ctx_lock(var, ret) (ret) |
| |
| #define | __release_ctx_lock(var) do { } while (0) |
| |
| #define | __release_shared_ctx_lock(var) do { } while (0) |
| |
| #define | __assume_ctx_lock(var) do { (void)(var); } while (0) |
| |
| #define | __assume_shared_ctx_lock(var) do { (void)(var); } while (0) |
| |
| #define | context_lock_struct(name, ...) struct __VA_ARGS__ name |
| |
| #define | disable_context_analysis() |
| |
| #define | enable_context_analysis() |
| |
| #define | __no_context_analysis |
| |
| #define | context_unsafe(...) |
| |
| #define | __context_unsafe(comment) __no_context_analysis |
| |
| #define | context_unsafe_alias(p) _context_unsafe_alias((void **)&(p)) |
| |
|
backed by a real data structure (linker error if accidentally referenced). The type name is __ctx_lock_@name.
|
| #define | token_context_lock(name, ...) |
| |
|
lock class @ctx. This is helpful where multiple related token contexts are declared, to allow using the same underlying type (__ctx_lock_@ctx) as function arguments.
|
| #define | token_context_lock_instance(ctx, name) extern const struct __ctx_lock_##ctx *name |
| |
| #define | __must_hold(...) __requires_ctx_lock(__VA_ARGS__) |
| |
| #define | __must_not_hold(...) __excludes_ctx_lock(__VA_ARGS__) |
| |
| #define | __acquires(...) __acquires_ctx_lock(__VA_ARGS__) |
| |
| #define | __cond_acquires_impl_true(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x) |
| |
| #define | __cond_acquires_impl_false(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x) |
| |
| #define | __cond_acquires_impl_nonzero(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x) |
| |
| #define | __cond_acquires_impl_0(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x) |
| |
| #define | __cond_acquires_impl_nonnull(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(1, x) |
| |
| #define | __cond_acquires_impl_NULL(x, ...) __try_acquires##__VA_ARGS__##_ctx_lock(0, x) |
| |
| #define | __cond_acquires(ret, x) __cond_acquires_impl_##ret(x) |
| |
| #define | __releases(...) __releases_ctx_lock(__VA_ARGS__) |
| |
| #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) |
| |
| #define | __cond_releases(ret, x) __releases(x) __cond_acquires_impl_not_##ret(x) |
| |
| #define | __acquire(x) __acquire_ctx_lock(x) |
| |
| #define | __release(x) __release_ctx_lock(x) |
| |
| #define | __must_hold_shared(...) __requires_shared_ctx_lock(__VA_ARGS__) |
| |
| #define | __acquires_shared(...) __acquires_shared_ctx_lock(__VA_ARGS__) |
| |
| #define | __cond_acquires_shared(ret, x) __cond_acquires_impl_##ret(x, _shared) |
| |
| #define | __releases_shared(...) __releases_shared_ctx_lock(__VA_ARGS__) |
| |
| #define | __acquire_shared(x) __acquire_shared_ctx_lock(x) |
| |
| #define | __release_shared(x) __release_shared_ctx_lock(x) |
| |
| #define | __acquire_ret(call, ret_expr) |
| |
| #define | __acquire_shared_ret(call, ret_expr) |
| |
| #define | __acquires_ret __no_context_analysis |
| |
| #define | __acquires_shared_ret __no_context_analysis |
| |
| #define __cond_acquires |
( |
|
ret, |
|
|
|
x |
|
) |
| __cond_acquires_impl_##ret(x) |
__cond_acquires() - function attribute, function conditionally acquires a context lock exclusively @ret: abstract value returned by function if context lock acquired @x: context lock instance pointer
Function attribute declaring that the function conditionally acquires the given context lock instance @x exclusively, but does not release it. The function return value @ret denotes when the context lock is acquired.
@ret may be one of: true, false, nonzero, 0, nonnull, NULL.
| #define __cond_acquires_shared |
( |
|
ret, |
|
|
|
x |
|
) |
| __cond_acquires_impl_##ret(x, _shared) |
__cond_acquires_shared() - function attribute, function conditionally acquires a context lock shared @ret: abstract value returned by function if context lock acquired @x: context lock instance pointer
Function attribute declaring that the function conditionally acquires the given context lock instance @x with shared access, but does not release it. The function return value @ret denotes when the context lock is acquired.
@ret may be one of: true, false, nonzero, 0, nonnull, NULL.
| #define __cond_releases |
( |
|
ret, |
|
|
|
x |
|
) |
| __releases(x) __cond_acquires_impl_not_##ret(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 context_unsafe_alias |
( |
|
p | ) |
_context_unsafe_alias((void **)&(p)) |
context_unsafe_alias() - helper to insert a context lock "alias barrier" : pointer aliasing a context lock or object containing context locks
No-op function that acts as a "context lock alias barrier", where the analysis rightfully detects that we're switching aliases, but the switch is considered safe but beyond the analysis reasoning abilities.
This should be inserted before the first use of such an alias.
Implementation Note: The compiler ignores aliases that may be reassigned but their value cannot be determined (e.g. when passing a non-const pointer to an alias as a function argument).