// Copyright 2016 The Fuchsia Authors
//
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file or at
// https://opensource.org/licenses/MIT
#ifndef ZIRCON_KERNEL_INCLUDE_KERNEL_DPC_H_
#define ZIRCON_KERNEL_INCLUDE_KERNEL_DPC_H_

#include <zircon/compiler.h>
#include <zircon/types.h>

#include <fbl/intrusive_double_list.h>
#include <kernel/event.h>
#include <kernel/thread.h>
#include <kernel/thread_lock.h>

// Deferred Procedure Calls - queue callback to invoke on the current cpu in thread context.
// Dpcs are executed with interrupts enabled, and do not ever migrate cpus while executing.
// A Dpc may not execute on the original current cpu if it is hotunplugged/offlined.
// Dpcs may block, though this may starve other queued work.

class Dpc : public fbl::DoublyLinkedListable<Dpc*, fbl::NodeOptions::AllowCopyMove> {
 public:
  using Func = void(Dpc*);

  explicit Dpc(Func* func = nullptr, void* arg = nullptr) : func_(func), arg_(arg) {}

  template <class ArgType>
  ArgType* arg() {
    return static_cast<ArgType*>(arg_);
  }

  // Queue this object and signal the worker thread to execute it.
  //
  // |Queue| will not block, but it may wait briefly for a spinlock.
  //
  // |Queue| may return before or after the Dpc has executed.  It is the caller's responsibilty to
  // ensure that a queued Dpc object is not destroyed prior to its execution.
  //
  // Returns ZX_ERR_ALREADY_EXISTS if |this| is already queued.
  zx_status_t Queue();

  // Queue this object and signal the worker thread to execute it.
  //
  // This method is similar to |Queue| with |reschedule| equal to false, except that it must be
  // called while holding the ThreadLock.
  //
  // |QueueThreadLocked| may return before or after the Dpc has executed.  It is the caller's
  // responsibilty to ensure that a queued Dpc object is not destroyed prior to its execution.
  //
  // Returns ZX_ERR_ALREADY_EXISTS if |this| is already queued.
  zx_status_t QueueThreadLocked() TA_REQ(thread_lock);

 private:
  friend class DpcQueue;

  // The DpcQueue this Dpc gets enqueued onto is the only thing to actually Invoke this Dpc,
  // on its worker thread.
  void Invoke();

  Func* func_;
  void* arg_;
};

// Each cpu maintains a DpcQueue, in its percpu structure.
class DpcQueue {
 public:
  // Initializes this DpcQueue for the current cpu.
  void InitForCurrentCpu();

  // Begins the Dpc shutdown process for the owning cpu.
  //
  // Shutting down a Dpc queue is a two-phase process.  This is the first phase.  See
  // |TransitionOffCpu| for the second phase.
  //
  // This method:
  // - tells the owning cpu's Dpc thread to stop servicing its queue then
  // - waits, up to |deadline|, for it to finish any in-progress DPC and join
  //
  // Because this method blocks until the Dpc thread has terminated, it is critical that the caller
  // not hold any locks that might be needed by any previously queued DPCs.  Otheriwse, deadlock may
  // occur.
  //
  // Upon successful completion, this DpcQueue may contain unexecuted Dpcs and new ones
  // may be added by |Queue|.  However, they will not execute (on any cpu) until
  // |TransitionOffCpu| is called.
  //
  // Once |Shutdown| has completed successfully, finish the shutdown process by calling
  // |TransitionOffCpu| on some cpu other than the owning cpu.
  //
  // If |Shutdown| fails, this DpcQueue is left in an undefined state and
  // |TransitionOffCpu| must not be called.
  zx_status_t Shutdown(zx_time_t deadline);

  // Moves queued Dpcs from |source| to this DpcQueue.
  //
  // This is the second phase of Dpc shutdown.  See |Shutdown|.
  //
  // This must only be called after |Shutdown| has completed successfully.
  //
  // This must only be called on the current cpu.
  void TransitionOffCpu(DpcQueue& source);

  // These are called by Dpc::Queue and Dpc::QueueThreadLocked.
  void Enqueue(Dpc* dpc);
  void Signal() TA_EXCL(thread_lock);
  void SignalLocked() TA_REQ(thread_lock);

 private:
  static int WorkerThread(void* unused);
  int Work();

  // The cpu that owns this DpcQueue.
  cpu_num_t cpu_ = INVALID_CPU;

  // Whether the DpcQueue has been initialized for the owning cpu.
  bool initialized_ = false;

  // Request the thread_ to stop by setting to true.
  //
  // This guarded by the static global dpc_lock.
  bool stop_ = false;

  // This guarded by the static global dpc_lock.
  fbl::DoublyLinkedList<Dpc*> list_;

  Event event_;

  // Each cpu maintains a dedicated thread for processing Dpcs.
  Thread* thread_ = nullptr;
};

#endif  // ZIRCON_KERNEL_INCLUDE_KERNEL_DPC_H_
