blob: 0a39db3b88c00be2c89217139b6d905588d94733 [file] [log] [blame]
// Copyright 2023 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.
#ifndef LIB_UART_SYNC_H_
#define LIB_UART_SYNC_H_
#include <lib/arch/intrin.h>
#include <lib/zircon-internal/thread_annotations.h>
#include <tuple>
#include <type_traits>
namespace uart {
// Degenerate case of unsynchronized policy, that provides the expected API to be implemented when
// another policy needs to be used.
struct UnsynchronizedPolicy {
// The |Lock| consists of any environment specific capability providing synchronization
// primitives.
// * |Lock| must be default-constructible.
// * |Lock| acquisition and release is private to the declared |Guard|.
// * |Lock| must model a version of TA Capabilities.
// * |MemberOf| is the containing type where |Lock| is embedded as a member.
template <typename MemberOf>
struct TA_CAP("uart") Lock {
constexpr Lock() = default;
};
// The |Guard| consists of any environment specific scoped capability that presents itself
// as a RAII for acquiring the opaque |LockType|.
// * |Guard| must be constructible from (|Lock*|, const char* |id|).
// * |LockPolicy| is forwarded to |Guard| type.
template <typename LockPolicy>
class TA_SCOPED_CAP Guard {
public:
template <typename LockType>
Guard(LockType* lock, const char* tag) TA_ACQ(lock) {}
~Guard() TA_REL() {}
};
// The |Waiter| consists of any environment specific object, that provides a mechanism for
// waiting for an event to happen.
// * |Waiter| must implement |template<typename Guard, T> Wait(Guard&, T&&
// enable_tx_interrupt)|.
//
// While the library only requires |Wait| to be implemented, users should provide a wake mechanism
// in blocking implementations, such that observers stuck waiting can resume their work.
//
// |Wait| is guaranteed to be called while |guard| holds the underlying capability.
struct Waiter {
template <typename Guard, typename T>
void Wait(Guard& guard, T&& enable_tx_interrupt) TA_REQ(guard) {
arch::Yield();
}
};
// Default Lock Policy to be used.
// The meaning of the policy is only meaningful to the |Guard| or this |SyncPolicy|.
struct DefaultLockPolicy {};
// Delegate for Lock Holding assertions.
template <typename LockType>
static void AssertHeld(LockType& lock) TA_ASSERT(lock) {}
};
} // namespace uart
#endif // LIB_UART_SYNC_H_