//===-- sanitizer_ring_buffer.h ---------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// Simple ring buffer.
//
//===----------------------------------------------------------------------===//
#ifndef SANITIZER_RING_BUFFER_H
#define SANITIZER_RING_BUFFER_H

#include "sanitizer_common.h"

namespace __sanitizer {
// RingBuffer<T>: fixed-size ring buffer optimized for speed of push().
// T should be a POD type and sizeof(T) should be divisible by sizeof(void*).
// At creation, all elements are zero.
template<class T>
class RingBuffer {
 public:
  COMPILER_CHECK(sizeof(T) % sizeof(void *) == 0);
  static RingBuffer *New(uptr Size) {
    void *Ptr = MmapOrDie(SizeInBytes(Size), "RingBuffer");
    RingBuffer *RB = reinterpret_cast<RingBuffer*>(Ptr);
    uptr End = reinterpret_cast<uptr>(Ptr) + SizeInBytes(Size);
    RB->last_ = RB->next_ = reinterpret_cast<T*>(End - sizeof(T));
    return RB;
  }
  void Delete() {
    UnmapOrDie(this, SizeInBytes(size()));
  }
  uptr size() const {
    return last_ + 1 -
           reinterpret_cast<T *>(reinterpret_cast<uptr>(this) +
                                 2 * sizeof(T *));
  }

  static uptr SizeInBytes(uptr Size) {
    return Size * sizeof(T) + 2 * sizeof(T*);
  }

  uptr SizeInBytes() { return SizeInBytes(size()); }

  void push(T t) {
    *next_ = t;
    next_--;
    // The condition below works only if sizeof(T) is divisible by sizeof(T*).
    if (next_ <= reinterpret_cast<T*>(&next_))
      next_ = last_;
  }

  T operator[](uptr Idx) const {
    CHECK_LT(Idx, size());
    sptr IdxNext = Idx + 1;
    if (IdxNext > last_ - next_)
      IdxNext -= size();
    return next_[IdxNext];
  }

 private:
  RingBuffer() {}
  ~RingBuffer() {}
  RingBuffer(const RingBuffer&) = delete;

  // Data layout:
  // LNDDDDDDDD
  // D: data elements.
  // L: last_, always points to the last data element.
  // N: next_, initially equals to last_, is decremented on every push,
  //    wraps around if it's less or equal than its own address.
  T *last_;
  T *next_;
  T data_[1];  // flexible array.
};

// A ring buffer with externally provided storage that encodes its state in 8
// bytes. Has significant constraints on size and alignment of storage.
// See a comment in hwasan/hwasan_thread_list.h for the motivation behind this.
#if SANITIZER_WORDSIZE == 64
template <class T>
class CompactRingBuffer {
  // Top byte of long_ stores the buffer size in pages.
  // Lower bytes store the address of the next buffer element.
  static constexpr int kPageSizeBits = 12;
  static constexpr int kSizeShift = 56;
  static constexpr uptr kNextMask = (1ULL << kSizeShift) - 1;

  uptr GetStorageSize() const { return (long_ >> kSizeShift) << kPageSizeBits; }

  void Init(void *storage, uptr size) {
    CHECK_EQ(sizeof(CompactRingBuffer<T>), sizeof(void *));
    CHECK(IsPowerOfTwo(size));
    CHECK_GE(size, 1 << kPageSizeBits);
    CHECK_LE(size, 128 << kPageSizeBits);
    CHECK_EQ(size % 4096, 0);
    CHECK_EQ(size % sizeof(T), 0);
    CHECK_EQ((uptr)storage % (size * 2), 0);
    long_ = (uptr)storage | ((size >> kPageSizeBits) << kSizeShift);
  }

  void SetNext(const T *next) {
    long_ = (long_ & ~kNextMask) | (uptr)next;
  }

 public:
  CompactRingBuffer(void *storage, uptr size) {
    Init(storage, size);
  }

  // A copy constructor of sorts.
  CompactRingBuffer(const CompactRingBuffer &other, void *storage) {
    uptr size = other.GetStorageSize();
    internal_memcpy(storage, other.StartOfStorage(), size);
    Init(storage, size);
    uptr Idx = other.Next() - (const T *)other.StartOfStorage();
    SetNext((const T *)storage + Idx);
  }

  T *Next() const { return (T *)(long_ & kNextMask); }

  void *StartOfStorage() const {
    return (void *)((uptr)Next() & ~(GetStorageSize() - 1));
  }

  void *EndOfStorage() const {
    return (void *)((uptr)StartOfStorage() + GetStorageSize());
  }

  uptr size() const { return GetStorageSize() / sizeof(T); }

  void push(T t) {
    T *next = Next();
    *next = t;
    next++;
    next = (T *)((uptr)next & ~GetStorageSize());
    SetNext(next);
  }

  const T &operator[](uptr Idx) const {
    CHECK_LT(Idx, size());
    const T *Begin = (const T *)StartOfStorage();
    sptr StorageIdx = Next() - Begin;
    StorageIdx -= (sptr)(Idx + 1);
    if (StorageIdx < 0)
      StorageIdx += size();
    return Begin[StorageIdx];
  }

 public:
  ~CompactRingBuffer() {}
  CompactRingBuffer(const CompactRingBuffer &) = delete;

  uptr long_;
};
#endif
}  // namespace __sanitizer

#endif  // SANITIZER_RING_BUFFER_H
