1 // Copyright 2016 The Fuchsia Authors
2 //
3 // Use of this source code is governed by a MIT-style
4 // license that can be found in the LICENSE file or at
5 // https://opensource.org/licenses/MIT
6 
7 #pragma once
8 
9 #include <fbl/auto_lock.h>
10 #include <fbl/macros.h>
11 #include <kernel/mutex.h>
12 #include <kernel/spinlock.h>
13 
14 // Various lock guard wrappers for kernel only locks
15 // NOTE: wrapper for mutex_t is in fbl/auto_lock.h
16 
17 class TA_SCOPED_CAP AutoSpinLockNoIrqSave {
18 public:
AutoSpinLockNoIrqSave(spin_lock_t * lock)19     explicit AutoSpinLockNoIrqSave(spin_lock_t* lock) TA_ACQ(lock)
20         : spinlock_(lock) {
21         DEBUG_ASSERT(lock);
22         spin_lock(spinlock_);
23     }
AutoSpinLockNoIrqSave(SpinLock * lock)24     explicit AutoSpinLockNoIrqSave(SpinLock* lock) TA_ACQ(lock)
25         : AutoSpinLockNoIrqSave(lock->GetInternal()) {}
TA_REL()26     ~AutoSpinLockNoIrqSave() TA_REL() { release(); }
27 
release()28     void release() TA_REL() {
29         if (spinlock_) {
30             spin_unlock(spinlock_);
31             spinlock_ = nullptr;
32         }
33     }
34 
35     // suppress default constructors
36     DISALLOW_COPY_ASSIGN_AND_MOVE(AutoSpinLockNoIrqSave);
37 
38 private:
39     spin_lock_t* spinlock_;
40 };
41 
42 class TA_SCOPED_CAP AutoSpinLock {
43 public:
AutoSpinLock(spin_lock_t * lock)44     explicit AutoSpinLock(spin_lock_t* lock) TA_ACQ(lock)
45         : spinlock_(lock) {
46         DEBUG_ASSERT(lock);
47         spin_lock_irqsave(spinlock_, state_);
48     }
AutoSpinLock(SpinLock * lock)49     explicit AutoSpinLock(SpinLock* lock) TA_ACQ(lock)
50         : AutoSpinLock(lock->GetInternal()) {}
TA_REL()51     ~AutoSpinLock() TA_REL() { release(); }
52 
release()53     void release() TA_REL() {
54         if (spinlock_) {
55             spin_unlock_irqrestore(spinlock_, state_);
56             spinlock_ = nullptr;
57         }
58     }
59 
60     // suppress default constructors
61     DISALLOW_COPY_ASSIGN_AND_MOVE(AutoSpinLock);
62 
63 private:
64     spin_lock_t* spinlock_;
65     spin_lock_saved_state_t state_;
66 };
67