/*
 * Copyright (C) 2019 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 <errno.h>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <cinttypes>
#include <memory>

namespace {

constexpr auto kIdleSize = 10000 * 4096;
constexpr auto kNoIdleSize = 1000 * 4096;

static bool interrupted = false;

volatile unsigned char* __attribute__((noinline)) AllocIdle(size_t bytes);
volatile unsigned char* __attribute__((noinline)) AllocIdle(size_t bytes) {
  // This volatile is needed to prevent the compiler from trying to be
  // helpful and compiling a "useless" malloc + free into a noop.
  volatile unsigned char* x = static_cast<unsigned char*>(malloc(bytes));
  if (x) {
    x[1] = 'x';
  }
  return x;
}

volatile unsigned char* __attribute__((noinline)) AllocNoIdle(size_t bytes);
volatile unsigned char* __attribute__((noinline)) AllocNoIdle(size_t bytes) {
  // This volatile is needed to prevent the compiler from trying to be
  // helpful and compiling a "useless" malloc + free into a noop.
  volatile unsigned char* x = static_cast<unsigned char*>(malloc(bytes));
  if (x) {
    x[0] = 'x';
  }
  return x;
}

class MemoryToucher {
 public:
  virtual void Touch(volatile unsigned char* nonidle) = 0;
  virtual ~MemoryToucher() = default;
};

class ReadDevZeroChunks : public MemoryToucher {
 public:
  ReadDevZeroChunks(size_t chunk_size)
      : chunk_size_(chunk_size), fd_(open("/dev/zero", O_RDONLY)) {
    if (fd_ == -1) {
      fprintf(stderr, "Failed to open: %s", strerror(errno));
      abort();
    }
  }

  ~ReadDevZeroChunks() override = default;

  void Touch(volatile unsigned char* nonidle) override {
    size_t total_rd = 0;
    while (total_rd < kNoIdleSize) {
      size_t chunk = chunk_size_;
      if (chunk > kNoIdleSize - total_rd)
        chunk = kNoIdleSize - total_rd;

      ssize_t rd =
          read(fd_, const_cast<unsigned char*>(nonidle) + total_rd, chunk);
      if (rd == -1) {
        fprintf(stderr, "Failed to write: %s.", strerror(errno));
        abort();
      }
      total_rd += static_cast<size_t>(rd);
    }
  }

 private:
  size_t chunk_size_;
  int fd_;
};

class ReadDevZeroChunksAndSleep : public ReadDevZeroChunks {
 public:
  ReadDevZeroChunksAndSleep(size_t chunk_size)
      : ReadDevZeroChunks(chunk_size) {}
  void Touch(volatile unsigned char* nonidle) override {
    ReadDevZeroChunks::Touch(nonidle);
    sleep(1);
  }
};

class SumUp : public MemoryToucher {
 public:
  SumUp()
      : sum_(const_cast<volatile uint64_t*>(
            static_cast<uint64_t*>(malloc(sizeof(uint64_t))))) {}
  ~SumUp() override = default;

  void Touch(volatile unsigned char* nonidle) override {
    for (size_t i = 0; i < kNoIdleSize; ++i)
      *sum_ += nonidle[i];
  }

 private:
  volatile uint64_t* sum_;
};

class ReadDevZeroChunksAndSum : public ReadDevZeroChunks {
 public:
  ReadDevZeroChunksAndSum(size_t chunk_size) : ReadDevZeroChunks(chunk_size) {}
  void Touch(volatile unsigned char* nonidle) override {
    ReadDevZeroChunks::Touch(nonidle);
    sum_up_.Touch(nonidle);
  }

 private:
  SumUp sum_up_;
};

class AssignValues : public MemoryToucher {
 public:
  ~AssignValues() override = default;

  void Touch(volatile unsigned char* nonidle) override {
    for (size_t i = 0; i < kNoIdleSize; ++i)
      nonidle[i] = static_cast<unsigned char>(i % 256);
  }
};

}  // namespace

int main(int argc, char** argv) {
  volatile auto* idle = AllocIdle(kIdleSize);
  volatile auto* nonidle = AllocNoIdle(kNoIdleSize);

  printf("Own PID: %" PRIdMAX "\n", static_cast<intmax_t>(getpid()));
  printf("Idle: %p\n", static_cast<void*>(const_cast<unsigned char*>(idle)));
  printf("Nonidle: %p\n",
         static_cast<void*>(const_cast<unsigned char*>(nonidle)));

  for (size_t i = 0; i < kIdleSize; ++i)
    idle[i] = static_cast<unsigned char>(i % 256);
  for (size_t i = 0; i < kNoIdleSize; ++i)
    nonidle[i] = static_cast<unsigned char>(i % 256);

  printf("Allocated everything.\n");

  struct sigaction action = {};
  action.sa_handler = [](int) { interrupted = true; };
  if (sigaction(SIGUSR1, &action, nullptr) != 0) {
    fprintf(stderr, "Failed to register signal handler.\n");
    abort();
  }

  if (argc < 2) {
    fprintf(stderr,
            "Specifiy one of AssignValues / SumUp / ReadDevZeroChunks\n");
    abort();
  }

  std::unique_ptr<MemoryToucher> toucher;
  if (strcmp(argv[1], "AssignValues") == 0) {
    toucher.reset(new AssignValues());
    printf("Using AssignValues.\n");
  } else if (strcmp(argv[1], "SumUp") == 0) {
    toucher.reset(new SumUp());
    printf("Using SumUp.\n");
  } else if (strcmp(argv[1], "ReadDevZeroChunks") == 0 ||
             strcmp(argv[1], "ReadDevZeroChunksAndSleep") == 0 ||
             strcmp(argv[1], "ReadDevZeroChunksAndSum") == 0) {
    if (argc < 3) {
      fprintf(stderr, "Specify chunk size.\n");
      abort();
    }
    char* end;
    long long chunk_arg = strtoll(argv[2], &end, 10);
    if (*end != '\0' || *argv[2] == '\0') {
      fprintf(stderr, "Invalid chunk size: %s\n", argv[2]);
      abort();
    }
    if (strcmp(argv[1], "ReadDevZeroChunksAndSleep") == 0) {
      printf("Using ReadDevZeroChunksAndSleep.\n");
      toucher.reset(
          new ReadDevZeroChunksAndSleep(static_cast<size_t>(chunk_arg)));
    } else if (strcmp(argv[1], "ReadDevZeroChunksAndSum") == 0) {
      printf("Using ReadDevZeroChunksAndSum.\n");
      toucher.reset(
          new ReadDevZeroChunksAndSum(static_cast<size_t>(chunk_arg)));
    } else {
      printf("Using ReadDevZeroChunks.\n");
      toucher.reset(new ReadDevZeroChunks(static_cast<size_t>(chunk_arg)));
    }
  } else {
    fprintf(stderr, "Invalid input.\n");
    abort();
  }

  while (true) {
    bool report = interrupted;
    if (report) {
      printf("Waiting to finish touching everything.\n");
      interrupted = false;
      sleep(2);
    }

    toucher->Touch(nonidle);

    if (report)
      printf("Touched everything.\n");
  }
}
