/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "nb/fixed_no_free_allocator.h"

#include "nb/pointer_arithmetic.h"
#include "starboard/common/log.h"

namespace nb {

FixedNoFreeAllocator::FixedNoFreeAllocator(void* memory_start,
                                           std::size_t memory_size)
    : memory_start_(memory_start),
      memory_end_(AsPointer(AsInteger(memory_start) + memory_size)) {
  SB_CHECK(IsAligned(memory_start, kMinAlignment));
  next_memory_ = memory_start_;
}

void FixedNoFreeAllocator::Free(void* memory) {
  // Nothing to do here besides ensure that the freed memory belongs to us.
  if (memory < memory_start_ || memory >= memory_end_) {
    SB_NOTREACHED() << "Invalid block to free: |memory| is " << memory
                    << ", start is " << memory_start_ << ", and end is "
                    << memory_end_;
  }
}

std::size_t FixedNoFreeAllocator::GetCapacity() const {
  return AsInteger(memory_end_) - AsInteger(memory_start_);
}

std::size_t FixedNoFreeAllocator::GetAllocated() const {
  return AsInteger(next_memory_) - AsInteger(memory_start_);
}

void FixedNoFreeAllocator::PrintAllocations() const {
  SB_NOTIMPLEMENTED();
}

void* FixedNoFreeAllocator::Allocate(std::size_t* size,
                                     std::size_t alignment,
                                     bool align_pointer) {
  // Find the next aligned memory available.
  uint8_t* aligned_next_memory =
      AsPointer(AlignUp(AsInteger(next_memory_), alignment));

  if (aligned_next_memory + *size < aligned_next_memory) {
    // "aligned_next_memory + size" overflows.
    return NULL;
  }

  if (aligned_next_memory + *size > memory_end_) {
    // We don't have enough memory available to make this allocation.
    return NULL;
  }

  if (!align_pointer) {
    *size += AsInteger(aligned_next_memory) - AsInteger(next_memory_);
  }

  void* memory_pointer = align_pointer ? aligned_next_memory : next_memory_;
  next_memory_ = aligned_next_memory + *size;
  return memory_pointer;
}

}  // namespace nb
