blob: 54fe7d9ed458f58cc8fae97aac6d0a2f2cd67d0c [file] [log] [blame]
// Copyright 2017 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 <fbl/ref_ptr.h>
#include <lib/zx/interrupt.h>
#include <zircon/compiler.h>
#include <zircon/errors.h>
#include <zircon/types.h>
#include <dispatcher-pool/dispatcher-event-source.h>
namespace dispatcher {
// class Interrupt
//
// Interrupt is one of the EventSources in the dispatcher framework and is used to
// manage dispatching hardware interrupts received from a zx::interrupt object.
//
// :: Handler ::
//
// Interrupt defines a single handler (ProcessHandler) which runs when the Interrupt has
// become signalled. The CLOCK_MONOTONIC time of the IRQ signalling will be
// delivered to the user as a parameter to this handle. Returning an error from
// the process handler will cause the Interrupt to automatically become deactivated.
// Returning ZX_OK will cause the Interrupt to become re-armed.
//
// :: Activation ::
//
// Activation requires a user to provide a valid ExecutionDomain, a
// zx::interrupt, and a valid ProcessHandler. The Interrupt object takes ownership
// of the zx::interrupt object.
//
class Interrupt : public EventSource {
public:
static constexpr size_t MAX_HANDLER_CAPTURE_SIZE = sizeof(void*) * 2;
using ProcessHandler =
fbl::InlineFunction<zx_status_t(Interrupt*, zx_time_t), MAX_HANDLER_CAPTURE_SIZE>;
static fbl::RefPtr<Interrupt> Create();
zx_status_t Activate(fbl::RefPtr<ExecutionDomain> domain,
zx::interrupt irq,
ProcessHandler process_handler);
virtual void Deactivate() __TA_EXCLUDES(obj_lock_) override;
protected:
void Dispatch(ExecutionDomain* domain) __TA_EXCLUDES(obj_lock_) override;
zx_status_t DoPortWaitLocked() __TA_REQUIRES(obj_lock_) override;
zx_status_t DoPortCancelLocked() __TA_REQUIRES(obj_lock_) override;
private:
friend class fbl::RefPtr<Interrupt>;
Interrupt() : EventSource(0) { }
ProcessHandler process_handler_;
bool irq_bound_ __TA_GUARDED(obj_lock_) = false;
};
} // namespace dispatcher