1/* @title: Lock Validator Assertions */
2#pragma once
3#include <compiler.h>
4#include <sync/mutex.h>
5#include <sync/mutex_simple.h>
6#include <sync/qspinlock.h>
7#include <sync/rwlock.h>
8#include <sync/spinlock.h>
9
10/* Assert that the current thread holds the lock. When DEBUG_LOCK_CHK
11 * is on and the lock is checked, this actually gets to use
12 * the provable engine. But otherwise, it falls back to a naive
13 * read of the lock word. RWLOCK needs
14 * RWLOCK_ACQUIRE_READ/RWLOCK_ACQUIRE_WRITE, which is why we have
15 * _1 and _2, so all locks regardless of type can funnel through
16 * this callsite */
17
18#define LOCK_CHK_ASSERT_HELD_1(l) \
19 _Generic((l), \
20 struct spinlock *: spinlock_assert_held_internal, \
21 struct qspinlock *: qspin_assert_held_internal, \
22 struct mutex *: mutex_assert_held_internal, \
23 struct mutex_simple *: mutex_simple_assert_held_internal)( \
24 (l), LOCK_CHK_SITE_HERE())
25
26#define LOCK_CHK_ASSERT_HELD_2(l, mode) \
27 _Generic((l), struct rwlock *: rwlock_assert_held_internal)( \
28 (l), (mode), LOCK_CHK_SITE_HERE())
29
30#define LOCK_CHK_ASSERT_HELD(...) \
31 _DISPATCH(LOCK_CHK_ASSERT_HELD, PP_NARG(__VA_ARGS__))(__VA_ARGS__)
32
33/* Inverse of above */
34#define LOCK_CHK_ASSERT_NOT_HELD(l) \
35 _Generic((l), \
36 struct spinlock *: spinlock_assert_not_held_internal, \
37 struct qspinlock *: qspin_assert_not_held_internal, \
38 struct mutex *: mutex_assert_not_held_internal, \
39 struct mutex_simple *: mutex_simple_assert_not_held_internal, \
40 struct rwlock *: rwlock_assert_not_held_internal)( \
41 (l), LOCK_CHK_SITE_HERE())
42