// Copyright 2021 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_CONCURRENT_COPY_H_
#define LIB_CONCURRENT_COPY_H_

#include <lib/concurrent/common.h>
#include <lib/stdcompat/bit.h>
#include <stdint.h>

#include <atomic>

namespace concurrent {
namespace internal {

template <CopyDir, SyncOpt, MaxTransferAligned>
void WellDefinedCopy(void* dst, const void* src, size_t size_bytes);

}  // namespace internal

// Copy |size_bytes| bytes from |src| to |dst| using atomic store operations to move
// the element into |dst| so that the behavior of the system is always well
// defined, even if there is a WellDefinedCopyFrom operation reading from the
// memory pointed to by |dst| concurrent with this CopyTo operation.
//
// WellDefinedCopyTo has memcpy semantics, not memmove semantics. In other
// words, it is illegal for |src| or |dst| to overlap in any way.
//
// While it is not required, by default, that |src| and |dst| have any specific
// alignment, both |src| and |dst| *must* have the _same_ alignment.
//
// IOW: (|src| & 0x7) *must* equal (|dst| & 0x7)
//
// :: Template Args ::
//
// |kSyncOpt|
// Controls the options for memory order synchronization.  See the comments in
// lib/concurrent/common.h for details.
//
// |kWorstCaseAlignment|
// An explicit guarantee of the worst case alignment that |src|/|dst| will obey.
// When this alignment guarantee is greater than or equal to the maximum
// internal transfer granularity of 64 bits, the initial explicit alignment step
// of the operation can be optimized away for a minor performance gain.
template <SyncOpt kSyncOpt = SyncOpt::AcqRelOps, size_t kWorstCaseAlignment = 1>
void WellDefinedCopyTo(void* dst, const void* src, size_t size_bytes) {
  static_assert(cpp20::has_single_bit(kWorstCaseAlignment),
                "kWorstCaseAlignment must be a power of 2");
  constexpr internal::MaxTransferAligned kMTA =
      (kWorstCaseAlignment >= internal::kMaxTransferGranularity) ? internal::MaxTransferAligned::Yes
                                                                 : internal::MaxTransferAligned::No;

  if constexpr (kSyncOpt == SyncOpt::Fence) {
    std::atomic_thread_fence(std::memory_order_release);
    internal::WellDefinedCopy<internal::CopyDir::To, SyncOpt::None, kMTA>(dst, src, size_bytes);
  } else {
    internal::WellDefinedCopy<internal::CopyDir::To, kSyncOpt, kMTA>(dst, src, size_bytes);
  }
}

// Copy |size_bytes| bytes from |src| to |dst| using atomic load operations to load the
// element from |src| so that the behavior of the system is always well defined,
// even if there is a WellDefinedCopyTo operation writing to the memory pointed
// to by |src| concurrent with this CopyFrom operation.
//
// WellDefinedCopyFrom has memcpy semantics, not memmove semantics. In other
// words, it is illegal for |src| or |dst| to overlap in any way.
//
// While it is not required, by default, that |src| and |dst| have any specific
// alignment, both |src| and |dst| *must* have the _same_ alignment.
//
// IOW: (|src| & 0x7) *must* equal (|dst| & 0x7)
//
// :: Template Args ::
//
// |kSyncOpt|
// Controls the options for memory order synchronization.  See the comments in
// lib/concurrent/common.h for details.
//
// |kWorstCaseAlignment|
// An explicit guarantee of the worst case alignment that |src|/|dst| will obey.
// When this alignment guarantee is greater than or equal to the maximum
// internal transfer granularity of 64 bits, the initial explicit alignment step
// of the operation can be optimized away for a minor performance gain.
template <SyncOpt kSyncOpt = SyncOpt::AcqRelOps, size_t kWorstCaseAlignment = 1>
void WellDefinedCopyFrom(void* dst, const void* src, size_t size_bytes) {
  static_assert(cpp20::has_single_bit(kWorstCaseAlignment),
                "kWorstCaseAlignment must be a power of 2");
  constexpr internal::MaxTransferAligned kMTA =
      (kWorstCaseAlignment >= internal::kMaxTransferGranularity) ? internal::MaxTransferAligned::Yes
                                                                 : internal::MaxTransferAligned::No;

  if constexpr (kSyncOpt == SyncOpt::Fence) {
    internal::WellDefinedCopy<internal::CopyDir::From, SyncOpt::None, kMTA>(dst, src, size_bytes);
    std::atomic_thread_fence(std::memory_order_acquire);
  } else {
    internal::WellDefinedCopy<internal::CopyDir::From, kSyncOpt, kMTA>(dst, src, size_bytes);
  }
}

template <typename T>
class WellDefinedCopyable {
 public:
  static_assert(std::is_trivially_copyable_v<T>,
                "T must be trivially copyable in order to use WellDefinedCopyable<>");

  template <typename... Args, typename = std::enable_if_t<std::is_constructible_v<T, Args...>>>
  WellDefinedCopyable(Args&&... args) : instance_(std::forward<Args>(args)...) {}
  ~WellDefinedCopyable() = default;

  // No copy, no move.
  WellDefinedCopyable(const WellDefinedCopyable<T>&) = delete;
  WellDefinedCopyable(WellDefinedCopyable<T>&&) = delete;
  WellDefinedCopyable<T>& operator=(const WellDefinedCopyable<T>&) = delete;
  WellDefinedCopyable<T>& operator=(WellDefinedCopyable<T>&&) = delete;

  // Read from the wrapped object into the destination buffer provided by the caller.
  template <SyncOpt kSyncOpt = SyncOpt::AcqRelOps>
  void Read(T& dst, SyncOptType<kSyncOpt> = SyncOptType<kSyncOpt>{}) const {
    WellDefinedCopyFrom<kSyncOpt, alignof(T)>(&dst, &instance_, sizeof(T));
  }

  // Update the wrapped object from the source buffer provided by the caller.
  template <SyncOpt kSyncOpt = SyncOpt::AcqRelOps>
  void Update(const T& src, SyncOptType<kSyncOpt> = SyncOptType<kSyncOpt>{}) {
    WellDefinedCopyTo<kSyncOpt, alignof(T)>(&instance_, &src, sizeof(T));
  }

  // WARNING: There be dragons here!
  //
  // |unsynchronized_get| provides direct read-only access to the underlying
  // instance of |T|. Accessing the buffer this way is _only_ safe if the user
  // can guarantee that no write operations may be concurrently performed
  // against the storage while the user is reading the instance.
  //
  // One example of a legitimate use of this method might be when a user is
  // operating in the write exclusive portion of a sequence lock.  They are
  // guaranteed to be the only potential writer of the wrapped object, so while
  // it is still important that they continue to use Update when they wish to
  // mutate their instance of T, it is OK for them to read T directly without
  // using Read as this will not cause any undefined behavior when done
  // concurrently with other readers in the system.
  //
  // Note that the method returns a `const T&`, but is not flagged as being
  // `const` itself.  This helps to guarantee that users who need to read data
  // in the exclusive portion of a sequence lock can do so, but cannot do so
  // while in the middle of a shared read transaction.
  const T& unsynchronized_get() { return instance_; }

 protected:
  T instance_;
};

}  // namespace concurrent

#endif  // LIB_CONCURRENT_COPY_H_
