// Copyright 2019 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_AUTO_PREEMPT_DISABLER_H_
#define ZIRCON_KERNEL_INCLUDE_KERNEL_AUTO_PREEMPT_DISABLER_H_

#include <kernel/preempt_disabled_token.h>
#include <kernel/thread.h>

// AutoPreemptDisabler is a RAII helper that automatically manages disabling and
// re-enabling preemption. When the object goes out of scope, it automatically
// re-enables preemption if it had been previously disabled by the instance.
//
// Example usage:
//
// // Immediately disable preemption, then obtain the list_ lock and append an
// // element to the list.
// {
//   AutoPreemptDisabler preempt_disabler;
//   Guard<Mutex> guard{&lock_};
//   list_.push_back(ktl::move(element_uptr));
// }
//
//  // Reserve the option to disable preemption, but do not do so right now.
//  {
//     AutoPreemptDisabler preempt_disabler{AutoPreemptDisabler::Defer};
//     Guard<Mutex> guard{&lock_};
//
//     // Do some work.
//
//     if (predicate()) {
//       preempt_disabler.Disable();
//       // Do some more work with preemption disabled.
//     }
//  } // lock_ is released first, then (if predicate() was true), preemption is re-enabled.
//

class AutoPreemptDisabler {
 public:
  // Tag type to construct the AutoPreemptDisabler without preemption initially
  // disabled.
  enum DeferType { Defer };

  AutoPreemptDisabler() { Thread::Current::preemption_state().PreemptDisable(); }
  explicit AutoPreemptDisabler(DeferType) : disabled_{false} {}

  ~AutoPreemptDisabler() { Enable(); }

  AutoPreemptDisabler(const AutoPreemptDisabler&) = delete;
  AutoPreemptDisabler& operator=(const AutoPreemptDisabler&) = delete;
  AutoPreemptDisabler(AutoPreemptDisabler&&) = delete;
  AutoPreemptDisabler& operator=(AutoPreemptDisabler&&) = delete;

  // Disables preemption if it was not disabled by this instance already.
  void Disable() TA_ASSERT(preempt_disabled_token) {
    if (!disabled_) {
      Thread::Current::preemption_state().PreemptDisable();
      disabled_ = true;
    }
  }

  // Enables preemption if it was previously disabled by this instance.
  void Enable() {
    if (disabled_) {
      Thread::Current::preemption_state().PreemptReenable();
      disabled_ = false;
    }
  }

  void AssertDisabled() const TA_ASSERT(preempt_disabled_token) { DEBUG_ASSERT(disabled_); }

 private:
  bool disabled_{true};
};

// AnnotatedAutoPreemptDisabler is an RAII helper which is almost identical in
// functionality to the AutoPreemptDisabler.  The main difference is that the
// Annotated version will automatically acquire/release the
// preempt_disabled_token, allowing it to be used in situations where static
// analysis demands proof that preemption has been disabled before a method can
// be called.
class TA_SCOPED_CAP AnnotatedAutoPreemptDisabler {
 public:
  AnnotatedAutoPreemptDisabler() TA_ACQ(preempt_disabled_token) {
    Thread::Current::preemption_state().PreemptDisableAnnotated();
  }

  ~AnnotatedAutoPreemptDisabler() TA_REL() { Enable(); }

  // Enables preemption if it was previously disabled by this instance.
  void Enable() TA_REL() {
    if (disabled_) {
      Thread::Current::preemption_state().PreemptReenableAnnotated();
      disabled_ = false;
    }
  }

  AnnotatedAutoPreemptDisabler(const AutoPreemptDisabler&) = delete;
  AnnotatedAutoPreemptDisabler& operator=(const AutoPreemptDisabler&) = delete;
  AnnotatedAutoPreemptDisabler(AutoPreemptDisabler&&) = delete;
  AnnotatedAutoPreemptDisabler& operator=(AutoPreemptDisabler&&) = delete;

 private:
  bool disabled_{true};
};

// AutoEagerReschedDisabler is a RAII helper that automatically manages
// disabling and re-enabling eager reschedules, including both local and remote
// CPUs. This type works the same as AutoPreemptDisable, except that it also
// prevents sending reschedule IPIs until eager reschedules are re-enabled.
class AutoEagerReschedDisabler {
 public:
  // Tag type to construct the AutoEagerReschedDisabler without eager
  // reschedules initially disabled.
  enum DeferType { Defer };

  AutoEagerReschedDisabler() { Thread::Current::preemption_state().EagerReschedDisable(); }
  explicit AutoEagerReschedDisabler(DeferType) : disabled_{false} {}

  ~AutoEagerReschedDisabler() { Enable(); }

  AutoEagerReschedDisabler(const AutoEagerReschedDisabler&) = delete;
  AutoEagerReschedDisabler& operator=(const AutoEagerReschedDisabler&) = delete;
  AutoEagerReschedDisabler(AutoEagerReschedDisabler&&) = delete;
  AutoEagerReschedDisabler& operator=(AutoEagerReschedDisabler&&) = delete;

  // Disables preemption if it was not disabled by this instance already.
  void Disable() {
    if (!disabled_) {
      Thread::Current::preemption_state().EagerReschedDisable();
      disabled_ = true;
    }
  }

  // Enables preemption if it was previously disabled by this instance.
  void Enable() {
    if (disabled_) {
      Thread::Current::preemption_state().EagerReschedReenable();
      disabled_ = false;
    }
  }

 private:
  bool disabled_{true};
};

// AnnotatedEagerReschedDsiabler is an RAII helper which is almost identical in
// functionality to the AutoEagerReschedDsiabler.  The main difference is that
// the Annotated version will automatically acquire/release the
// preempt_disabled_token, allowing it to be used in situations where static
// analysis demands proof that preemption has been disabled before a method can
// be called.
class TA_SCOPED_CAP AnnotatedAutoEagerReschedDisabler {
 public:
  AnnotatedAutoEagerReschedDisabler() TA_ACQ(preempt_disabled_token) {
    Thread::Current::preemption_state().EagerReschedDisableAnnotated();
  }
  ~AnnotatedAutoEagerReschedDisabler() TA_REL() { Enable(); }

  // Enables preemption if it was previously disabled by this instance.
  void Enable() TA_REL() {
    if (disabled_) {
      Thread::Current::preemption_state().EagerReschedReenableAnnotated();
      disabled_ = false;
    }
  }

  AnnotatedAutoEagerReschedDisabler(const AutoEagerReschedDisabler&) = delete;
  AnnotatedAutoEagerReschedDisabler& operator=(const AutoEagerReschedDisabler&) = delete;
  AnnotatedAutoEagerReschedDisabler(AutoEagerReschedDisabler&&) = delete;
  AnnotatedAutoEagerReschedDisabler& operator=(AutoEagerReschedDisabler&&) = delete;

 private:
  bool disabled_{true};
};

// AutoExpiringPreemptDisabler is an RAII helper that defers preemption of the
// current thread until either |max_deferral_duration| nanoseconds after
// preemption is requested or the object is destroyed, whichever comes first.
class AutoExpiringPreemptDisabler {
 public:
  explicit AutoExpiringPreemptDisabler(zx_duration_t max_deferral_duration)
      : should_clear_(
            Thread::Current::preemption_state().SetTimesliceExtension(max_deferral_duration)) {}

  ~AutoExpiringPreemptDisabler() {
    if (should_clear_) {
      Thread::Current::preemption_state().ClearTimesliceExtension();
    }
  }

  AutoExpiringPreemptDisabler(const AutoExpiringPreemptDisabler&) = delete;
  AutoExpiringPreemptDisabler& operator=(const AutoExpiringPreemptDisabler&) = delete;
  AutoExpiringPreemptDisabler(AutoExpiringPreemptDisabler&&) = delete;
  AutoExpiringPreemptDisabler& operator=(AutoExpiringPreemptDisabler&&) = delete;

 private:
  const bool should_clear_;
};

#endif  // ZIRCON_KERNEL_INCLUDE_KERNEL_AUTO_PREEMPT_DISABLER_H_
