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
17class TA_SCOPED_CAP AutoSpinLockNoIrqSave {
18public:
19    explicit AutoSpinLockNoIrqSave(spin_lock_t* lock) TA_ACQ(lock)
20        : spinlock_(lock) {
21        DEBUG_ASSERT(lock);
22        spin_lock(spinlock_);
23    }
24    explicit AutoSpinLockNoIrqSave(SpinLock* lock) TA_ACQ(lock)
25        : AutoSpinLockNoIrqSave(lock->GetInternal()) {}
26    ~AutoSpinLockNoIrqSave() TA_REL() { release(); }
27
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
38private:
39    spin_lock_t* spinlock_;
40};
41
42class TA_SCOPED_CAP AutoSpinLock {
43public:
44    explicit AutoSpinLock(spin_lock_t* lock) TA_ACQ(lock)
45        : spinlock_(lock) {
46        DEBUG_ASSERT(lock);
47        spin_lock_irqsave(spinlock_, state_);
48    }
49    explicit AutoSpinLock(SpinLock* lock) TA_ACQ(lock)
50        : AutoSpinLock(lock->GetInternal()) {}
51    ~AutoSpinLock() TA_REL() { release(); }
52
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
63private:
64    spin_lock_t* spinlock_;
65    spin_lock_saved_state_t state_;
66};
67