/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * 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 "base/time_utils.h"
#include "space_test.h"
#include "large_object_space.h"

namespace art {
namespace gc {
namespace space {

class LargeObjectSpaceTest : public SpaceTest {
 public:
  void LargeObjectTest();

  static constexpr size_t kNumThreads = 10;
  static constexpr size_t kNumIterations = 1000;
  void RaceTest();
};


void LargeObjectSpaceTest::LargeObjectTest() {
  size_t rand_seed = 0;
  for (size_t i = 0; i < 2; ++i) {
    LargeObjectSpace* los = nullptr;
    if (i == 0) {
      los = space::LargeObjectMapSpace::Create("large object space");
    } else {
      los = space::FreeListSpace::Create("large object space", nullptr, 128 * MB);
    }

    static const size_t num_allocations = 64;
    static const size_t max_allocation_size = 0x100000;
    std::vector<std::pair<mirror::Object*, size_t>> requests;

    for (size_t phase = 0; phase < 2; ++phase) {
      while (requests.size() < num_allocations) {
        size_t request_size = test_rand(&rand_seed) % max_allocation_size;
        size_t allocation_size = 0;
        size_t bytes_tl_bulk_allocated;
        mirror::Object* obj = los->Alloc(Thread::Current(), request_size, &allocation_size,
                                         nullptr, &bytes_tl_bulk_allocated);
        ASSERT_TRUE(obj != nullptr);
        ASSERT_EQ(allocation_size, los->AllocationSize(obj, nullptr));
        ASSERT_GE(allocation_size, request_size);
        ASSERT_EQ(allocation_size, bytes_tl_bulk_allocated);
        // Fill in our magic value.
        uint8_t magic = (request_size & 0xFF) | 1;
        memset(obj, magic, request_size);
        requests.push_back(std::make_pair(obj, request_size));
      }

      // "Randomly" shuffle the requests.
      for (size_t k = 0; k < 10; ++k) {
        for (size_t j = 0; j < requests.size(); ++j) {
          std::swap(requests[j], requests[test_rand(&rand_seed) % requests.size()]);
        }
      }

      // Free 1 / 2 the allocations the first phase, and all the second phase.
      size_t limit = !phase ? requests.size() / 2 : 0;
      while (requests.size() > limit) {
        mirror::Object* obj = requests.back().first;
        size_t request_size = requests.back().second;
        requests.pop_back();
        uint8_t magic = (request_size & 0xFF) | 1;
        for (size_t k = 0; k < request_size; ++k) {
          ASSERT_EQ(reinterpret_cast<const uint8_t*>(obj)[k], magic);
        }
        ASSERT_GE(los->Free(Thread::Current(), obj), request_size);
      }
    }
    // Test that dump doesn't crash.
    los->Dump(LOG(INFO));

    size_t bytes_allocated = 0, bytes_tl_bulk_allocated;
    // Checks that the coalescing works.
    mirror::Object* obj = los->Alloc(Thread::Current(), 100 * MB, &bytes_allocated, nullptr,
                                     &bytes_tl_bulk_allocated);
    EXPECT_TRUE(obj != nullptr);
    los->Free(Thread::Current(), obj);

    EXPECT_EQ(0U, los->GetBytesAllocated());
    EXPECT_EQ(0U, los->GetObjectsAllocated());
    delete los;
  }
}

class AllocRaceTask : public Task {
 public:
  AllocRaceTask(size_t id, size_t iterations, size_t size, LargeObjectSpace* los) :
    id_(id), iterations_(iterations), size_(size), los_(los) {}

  void Run(Thread* self) {
    for (size_t i = 0; i < iterations_ ; ++i) {
      size_t alloc_size, bytes_tl_bulk_allocated;
      mirror::Object* ptr = los_->Alloc(self, size_, &alloc_size, nullptr,
                                        &bytes_tl_bulk_allocated);

      NanoSleep((id_ + 3) * 1000);  // (3+id) mu s

      los_->Free(self, ptr);
    }
  }

  virtual void Finalize() {
    delete this;
  }

 private:
  size_t id_;
  size_t iterations_;
  size_t size_;
  LargeObjectSpace* los_;
};

void LargeObjectSpaceTest::RaceTest() {
  for (size_t los_type = 0; los_type < 2; ++los_type) {
    LargeObjectSpace* los = nullptr;
    if (los_type == 0) {
      los = space::LargeObjectMapSpace::Create("large object space");
    } else {
      los = space::FreeListSpace::Create("large object space", nullptr, 128 * MB);
    }

    Thread* self = Thread::Current();
    ThreadPool thread_pool("Large object space test thread pool", kNumThreads);
    for (size_t i = 0; i < kNumThreads; ++i) {
      thread_pool.AddTask(self, new AllocRaceTask(i, kNumIterations, 16 * KB, los));
    }

    thread_pool.StartWorkers(self);

    thread_pool.Wait(self, true, false);

    delete los;
  }
}

TEST_F(LargeObjectSpaceTest, LargeObjectTest) {
  LargeObjectTest();
}

TEST_F(LargeObjectSpaceTest, RaceTest) {
  RaceTest();
}

}  // namespace space
}  // namespace gc
}  // namespace art
