blob: 07813c25fbe389c53db73cd3d0f7fb05150d893e [file] [log] [blame]
// Copyright 2018 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#pragma once
#include <atomic>
#include <threads.h>
#include <zircon/thread_annotations.h>
namespace devmgr {
// locking and lock debugging
namespace internal {
extern mtx_t devhost_api_lock;
extern std::atomic<thrd_t> devhost_api_lock_owner;
} // namespace internal
#define REQ_DM_LOCK TA_REQ(&::devmgr::internal::devhost_api_lock)
#define USE_DM_LOCK TA_GUARDED(&::devmgr::internal::devhost_api_lock)
static inline void DM_LOCK() TA_ACQ(&::devmgr::internal::devhost_api_lock) {
mtx_lock(&internal::devhost_api_lock);
internal::devhost_api_lock_owner.store(thrd_current());
}
static inline void DM_UNLOCK() TA_REL(&::devmgr::internal::devhost_api_lock) {
internal::devhost_api_lock_owner.store(0);
mtx_unlock(&internal::devhost_api_lock);
}
static inline bool DM_LOCK_HELD() {
return thrd_equal(internal::devhost_api_lock_owner.load(), thrd_current());
}
class ApiAutoLock {
public:
ApiAutoLock() TA_ACQ(&::devmgr::internal::devhost_api_lock) { DM_LOCK(); }
~ApiAutoLock() TA_REL(&::devmgr::internal::devhost_api_lock) { DM_UNLOCK(); }
};
class ApiAutoRelock {
public:
ApiAutoRelock() TA_REL(&::devmgr::internal::devhost_api_lock) { DM_UNLOCK(); }
~ApiAutoRelock() TA_ACQ(&::devmgr::internal::devhost_api_lock) { DM_LOCK(); }
};
} // namespace devmgr