// Copyright 2006 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.

#ifndef STRESSAPPTEST_SATTYPES_H_
#define STRESSAPPTEST_SATTYPES_H_

#include <arpa/inet.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <time.h>
#include <string.h>
#include <algorithm>
#include <string>

#ifdef HAVE_CONFIG_H  // Built using autoconf
#ifdef __ANDROID__
#include "stressapptest_config_android.h"  // NOLINT
#else
#include "stressapptest_config.h"  // NOLINT
using namespace __gnu_cxx;  //NOLINT
#endif  // __ANDROID__
using namespace std;

typedef signed long long   int64;
typedef signed int         int32;
typedef signed short int   int16;
typedef signed char        int8;

typedef unsigned long long uint64;
typedef unsigned int       uint32;
typedef unsigned short     uint16;
typedef unsigned char      uint8;

#define DISALLOW_COPY_AND_ASSIGN(TypeName)        \
  TypeName(const TypeName&);                      \
  void operator=(const TypeName&)

inline const char* Timestamp() {
  return STRESSAPPTEST_TIMESTAMP;
}

inline const char* BuildChangelist() {
  return "open source release";
}

static const bool kOpenSource = true;
#else  // !HAVE_CONFIG_H
static const bool kOpenSource = false;
  #include "googlesattypes.h"  // NOLINT
#endif  // HAVE_CONFIG_H
// Workaround to allow 32/64 bit conversion
// without running into strict aliasing problems.
union datacast_t {
  uint64 l64;
  struct {
    uint32 l;
    uint32 h;
  } l32;
};


// File sync'd print to console and log
void logprintf(int priority, const char *format, ...);

// Stop the log and dump any queued lines.
void logstop();

// We print to stderr ourselves first in case we're in such a bad state that the
// logger can't work.
#define sat_assert(x) \
{\
  if (!(x)) {\
    logstop();\
    fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\
    logprintf(0, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\
    exit(1);\
  }\
}

#if !defined(CPU_SETSIZE)
  // Define type and macros for cpu mask operations
  // Note: this code is hacked together to deal with difference
  // function signatures across versions of glibc, ie those that take
  // cpu_set_t versus those that take unsigned long.  -johnhuang
  typedef uint64 cpu_set_t;
  #define CPU_SETSIZE                   (sizeof(cpu_set_t) * 8)
  #define CPU_ISSET(index, cpu_set_ptr) (*(cpu_set_ptr) & 1ull << (index))
  #define CPU_SET(index, cpu_set_ptr)   (*(cpu_set_ptr) |= 1ull << (index))
  #define CPU_ZERO(cpu_set_ptr)         (*(cpu_set_ptr) = 0)
  #define CPU_CLR(index, cpu_set_ptr)   (*(cpu_set_ptr) &= ~(1ull << (index)))
#endif

static inline bool cpuset_isequal(const cpu_set_t *c1, const cpu_set_t *c2) {
  for (int i = 0; i < CPU_SETSIZE; ++i)
    if ((CPU_ISSET(i, c1) != 0) != (CPU_ISSET(i, c2) != 0))
      return false;
  return true;
}

static inline bool cpuset_issubset(const cpu_set_t *c1, const cpu_set_t *c2) {
  for (int i = 0; i < CPU_SETSIZE; ++i)
    if (CPU_ISSET(i, c1) && !CPU_ISSET(i, c2))
      return false;
  return true;
}

static inline int cpuset_count(const cpu_set_t *cpuset) {
  int count = 0;
  for (int i = 0; i < CPU_SETSIZE; ++i)
    if (CPU_ISSET(i, cpuset))
      ++count;
  return count;
}

static inline void cpuset_set_ab(cpu_set_t *cpuset, int a, int b) {
  CPU_ZERO(cpuset);
  for (int i = a; i < b; ++i)
    CPU_SET(i, cpuset);
}

static inline string cpuset_format(const cpu_set_t *cpuset) {
  string format;
  int digit = 0, last_non_zero_size = 1;
  for (int i = 0; i < CPU_SETSIZE; ++i) {
    if (CPU_ISSET(i, cpuset)) {
      digit |= 1 << (i & 3);
    }
    if ((i & 3) == 3) {
      format += char(digit <= 9 ? '0' + digit: 'A' + digit - 10);
      if (digit) {
        last_non_zero_size = format.size();
        digit = 0;
      }
    }
  }
  if (digit) {
    format += char(digit <= 9 ? '0' + digit: 'A' + digit - 10);
    last_non_zero_size = format.size();
  }
  format.erase(last_non_zero_size);
  reverse(format.begin(), format.end());
  return format;
}

static const int32 kUSleepOneSecond = 1000000;

// This is guaranteed not to use signals.
inline bool sat_usleep(int32 microseconds) {
  timespec req;
  req.tv_sec = microseconds / 1000000;
  // Convert microseconds argument to nano seconds.
  req.tv_nsec = (microseconds % 1000000) * 1000;
  return nanosleep(&req, NULL) == 0;
}

// This is guaranteed not to use signals.
inline bool sat_sleep(time_t seconds) {
  timespec req;
  req.tv_sec = seconds;
  req.tv_nsec = 0;
  return nanosleep(&req, NULL) == 0;
}

// Get an error code description for use in error messages.
//
// Args:
//   error_num: an errno error code
inline string ErrorString(int error_num) {
  char buf[256];
#ifdef STRERROR_R_CHAR_P
  return string(strerror_r(error_num, buf, sizeof buf));
#else
  if (strerror_r(error_num, buf, sizeof buf))
    return "unknown failure";
  else
    return string(buf);
#endif
}

// Execute the cpuid instruction and pass back the contents of the registers.
// This only works on x86 based platforms.
inline void cpuid(
  unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
  *ebx = 0;
  *ecx = 0;
  *edx = 0;
  // CPUID features documented at:
  // http://www.sandpile.org/ia32/cpuid.htm
#if defined(STRESSAPPTEST_CPU_I686) || defined(STRESSAPPTEST_CPU_X86_64)
#if defined(__PIC__) && defined(STRESSAPPTEST_CPU_I686)
  // In PIC compilations using the i686 cpu type, ebx contains the address
  // of the global offset table. The compiler can't properly handle constraints
  // using the ebx register for this compile, so preserve the register
  // ourselves.
  asm(
    "mov %%ebx, %%edi;"
    "cpuid;"
    "xchg %%edi, %%ebx;"
    // Output registers.
    : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx)
    // Input registers.
    : "a" (*eax)
  );  // Asm
#else
  asm(
    "cpuid;"
    // Output registers.
    : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
    // Input registers.
    : "a" (*eax)
  );  // Asm
#endif  // defined(__PIC__) && defined(STRESSAPPTEST_CPU_I686)
#elif defined(STRESSAPPTEST_CPU_PPC)
  return;
#elif defined(STRESSAPPTEST_CPU_ARMV7A)
  return;
#else
#warning "Unsupported CPU type."
#endif
}

// Define handy constants here
static const int kTicksPerSec = 100;
static const int kMegabyte = (1024LL*1024LL);
static const int kSatDiskPageMax = 32;
static const int kSatDiskPage = 8;
static const int kSatPageSize = (1024LL*1024LL);
static const int kCacheLineSize = 64;
static const uint16_t kNetworkPort = 19996;

#endif  // STRESSAPPTEST_SATTYPES_H_
