| 1 | #include "sync/tests/test_internal.h" |
| 2 | |
| 3 | #include <sync/seqlock.h> |
| 4 | |
| 5 | LOCK_CHK_CLASS_DECLARE_LOCAL(lock_reinit_class); |
| 6 | static MUTEX_SIMPLE_DEFINE(static_simple_mutex); |
| 7 | |
| 8 | #ifdef DEBUG_LOCK_CHK |
| 9 | |
| 10 | static bool lock_init_state_valid(struct spinlock *spin, |
| 11 | struct qspinlock *qspin, struct mutex *mutex, |
| 12 | struct mutex_simple *simple, |
| 13 | struct rwlock *rw, struct seqlock *seq) { |
| 14 | return spin->chk.initialized && spin->chk.flags == LOCK_CHKD_FULL && |
| 15 | spin->chk.map.class != NULL && qspin->chk.initialized && |
| 16 | qspin->chk.flags == LOCK_CHKD_FULL && qspin->chk.map.class != NULL && |
| 17 | mutex->chk.initialized && mutex->chk.flags == LOCK_CHKD_FULL && |
| 18 | mutex->chk.map.class != NULL && simple->chk.initialized && |
| 19 | simple->chk.flags == LOCK_CHKD_FULL && |
| 20 | simple->chk.map.class != NULL && rw->chk.initialized && |
| 21 | rw->chk.flags == LOCK_CHKD_FULL && rw->chk.map.class != NULL && |
| 22 | seq->lock.chk.initialized && seq->lock.chk.flags == LOCK_CHKD_FULL && |
| 23 | seq->lock.chk.map.class != NULL; |
| 24 | } |
| 25 | |
| 26 | static bool lock_reinit_state_valid(struct spinlock *spin, |
| 27 | struct qspinlock *qspin, |
| 28 | struct mutex *mutex, |
| 29 | struct mutex_simple *simple, |
| 30 | struct rwlock *rw) { |
| 31 | const struct lock_chk_class *class = LOCK_CHK_CLASS(lock_reinit_class); |
| 32 | |
| 33 | return spin->chk.flags == LOCK_CHKD_FULL && spin->chk.map.class == class && |
| 34 | qspin->chk.flags == LOCK_CHKD_FULL && |
| 35 | qspin->chk.map.class == class && |
| 36 | mutex->chk.flags == LOCK_CHKD_FULL && |
| 37 | mutex->chk.map.class == class && |
| 38 | simple->chk.flags == LOCK_CHKD_FULL && |
| 39 | simple->chk.map.class == class && rw->chk.flags == LOCK_CHKD_FULL && |
| 40 | rw->chk.map.class == class; |
| 41 | } |
| 42 | |
| 43 | #else /* !defined(DEBUG_LOCK_CHK) */ |
| 44 | |
| 45 | static bool lock_init_state_valid(struct spinlock *spin, |
| 46 | struct qspinlock *qspin, struct mutex *mutex, |
| 47 | struct mutex_simple *simple, |
| 48 | struct rwlock *rw, struct seqlock *seq) { |
| 49 | unused(spin, qspin, mutex, simple, rw, seq); |
| 50 | return true; |
| 51 | } |
| 52 | |
| 53 | static bool lock_reinit_state_valid(struct spinlock *spin, |
| 54 | struct qspinlock *qspin, |
| 55 | struct mutex *mutex, |
| 56 | struct mutex_simple *simple, |
| 57 | struct rwlock *rw) { |
| 58 | unused(spin, qspin, mutex, simple, rw); |
| 59 | return true; |
| 60 | } |
| 61 | |
| 62 | #endif /* DEBUG_LOCK_CHK */ |
| 63 | |
| 64 | TEST_DECLARE_UNIT(lock_chk, initializers_install_policy) { |
| 65 | struct spinlock spin; |
| 66 | struct qspinlock qspin; |
| 67 | struct mutex mutex; |
| 68 | struct mutex_simple simple; |
| 69 | struct rwlock rw; |
| 70 | struct seqlock seq; |
| 71 | |
| 72 | spinlock_init(&spin); |
| 73 | qspinlock_init(&qspin); |
| 74 | mutex_init(&mutex); |
| 75 | mutex_simple_init(&simple); |
| 76 | rwlock_init(&rw, THREAD_PRIO_CLASS_TIMESHARE); |
| 77 | seqlock_init(&seq); |
| 78 | |
| 79 | TEST_ASSERT(list_empty(&static_simple_mutex.waiters.list)); |
| 80 | TEST_ASSERT( |
| 81 | lock_init_state_valid(&spin, &qspin, &mutex, &simple, &rw, &seq)); |
| 82 | return TEST_SUCCESS; |
| 83 | } |
| 84 | |
| 85 | TEST_DECLARE_UNIT(lock_chk, policy_mutation_and_reinit) { |
| 86 | struct spinlock spin; |
| 87 | struct qspinlock qspin; |
| 88 | struct mutex mutex; |
| 89 | struct mutex_simple simple; |
| 90 | struct rwlock rw; |
| 91 | const struct lock_chk_class *class = LOCK_CHK_CLASS(lock_reinit_class); |
| 92 | |
| 93 | spinlock_init(&spin); |
| 94 | qspinlock_init(&qspin); |
| 95 | mutex_init(&mutex); |
| 96 | mutex_simple_init(&simple); |
| 97 | rwlock_init(&rw, THREAD_PRIO_CLASS_TIMESHARE); |
| 98 | |
| 99 | spinlock_set_chk_flags(lock: &spin, flags: LOCK_CHKD_ORDER); |
| 100 | qspinlock_set_chk_flags(lock: &qspin, flags: LOCK_CHKD_ORDER); |
| 101 | mutex_set_chk_flags(mtx: &mutex, flags: LOCK_CHKD_THREAD); |
| 102 | mutex_simple_set_chk_flags(m: &simple, flags: LOCK_CHKD_THREAD); |
| 103 | rwlock_set_chk_flags(lock: &rw, flags: LOCK_CHKD_THREAD); |
| 104 | |
| 105 | spinlock_reinit_chk(lock: &spin, class, flags: LOCK_CHKD_FULL); |
| 106 | qspinlock_reinit_chk(lock: &qspin, class, flags: LOCK_CHKD_FULL); |
| 107 | mutex_reinit_chk(mtx: &mutex, class, flags: LOCK_CHKD_FULL); |
| 108 | mutex_simple_reinit_chk(m: &simple, class, flags: LOCK_CHKD_FULL); |
| 109 | rwlock_reinit_chk(lock: &rw, ceiling: THREAD_PRIO_CLASS_URGENT, class, flags: LOCK_CHKD_FULL); |
| 110 | |
| 111 | TEST_ASSERT(lock_reinit_state_valid(&spin, &qspin, &mutex, &simple, &rw)); |
| 112 | return TEST_SUCCESS; |
| 113 | } |
| 114 | |