// 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_