// 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 #include #include #include #include #include #include #include #include #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; #elif defined(STRESSAPPTEST_CPU_AARCH64) 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_