1 // Copyright 2006 Google Inc. All Rights Reserved.
2 
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 
7 //      http://www.apache.org/licenses/LICENSE-2.0
8 
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef STRESSAPPTEST_SATTYPES_H_
16 #define STRESSAPPTEST_SATTYPES_H_
17 
18 #include <arpa/inet.h>
19 #include <sched.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/types.h>
23 #include <time.h>
24 #include <string.h>
25 #include <algorithm>
26 #include <string>
27 
28 #ifdef HAVE_CONFIG_H  // Built using autoconf
29 #ifdef __ANDROID__
30 #include "stressapptest_config_android.h"  // NOLINT
31 #else
32 #include "stressapptest_config.h"  // NOLINT
33 using namespace __gnu_cxx;  //NOLINT
34 #endif  // __ANDROID__
35 using namespace std;
36 
37 typedef signed long long   int64;
38 typedef signed int         int32;
39 typedef signed short int   int16;
40 typedef signed char        int8;
41 
42 typedef unsigned long long uint64;
43 typedef unsigned int       uint32;
44 typedef unsigned short     uint16;
45 typedef unsigned char      uint8;
46 
47 #define DISALLOW_COPY_AND_ASSIGN(TypeName)        \
48   TypeName(const TypeName&);                      \
49   void operator=(const TypeName&)
50 
Timestamp()51 inline const char* Timestamp() {
52   return STRESSAPPTEST_TIMESTAMP;
53 }
54 
BuildChangelist()55 inline const char* BuildChangelist() {
56   return "open source release";
57 }
58 
59 static const bool kOpenSource = true;
60 #else  // !HAVE_CONFIG_H
61 static const bool kOpenSource = false;
62   #include "googlesattypes.h"  // NOLINT
63 #endif  // HAVE_CONFIG_H
64 // Workaround to allow 32/64 bit conversion
65 // without running into strict aliasing problems.
66 union datacast_t {
67   uint64 l64;
68   struct {
69     uint32 l;
70     uint32 h;
71   } l32;
72 };
73 
74 
75 // File sync'd print to console and log
76 void logprintf(int priority, const char *format, ...);
77 
78 // Stop the log and dump any queued lines.
79 void logstop();
80 
81 // We print to stderr ourselves first in case we're in such a bad state that the
82 // logger can't work.
83 #define sat_assert(x) \
84 {\
85   if (!(x)) {\
86     logstop();\
87     fprintf(stderr, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\
88     logprintf(0, "Assertion failed at %s:%d\n", __FILE__, __LINE__);\
89     exit(1);\
90   }\
91 }
92 
93 #if !defined(CPU_SETSIZE)
94   // Define type and macros for cpu mask operations
95   // Note: this code is hacked together to deal with difference
96   // function signatures across versions of glibc, ie those that take
97   // cpu_set_t versus those that take unsigned long.  -johnhuang
98   typedef uint64 cpu_set_t;
99   #define CPU_SETSIZE                   (sizeof(cpu_set_t) * 8)
100   #define CPU_ISSET(index, cpu_set_ptr) (*(cpu_set_ptr) & 1ull << (index))
101   #define CPU_SET(index, cpu_set_ptr)   (*(cpu_set_ptr) |= 1ull << (index))
102   #define CPU_ZERO(cpu_set_ptr)         (*(cpu_set_ptr) = 0)
103   #define CPU_CLR(index, cpu_set_ptr)   (*(cpu_set_ptr) &= ~(1ull << (index)))
104 #endif
105 
cpuset_isequal(const cpu_set_t * c1,const cpu_set_t * c2)106 static inline bool cpuset_isequal(const cpu_set_t *c1, const cpu_set_t *c2) {
107   for (int i = 0; i < CPU_SETSIZE; ++i)
108     if ((CPU_ISSET(i, c1) != 0) != (CPU_ISSET(i, c2) != 0))
109       return false;
110   return true;
111 }
112 
cpuset_issubset(const cpu_set_t * c1,const cpu_set_t * c2)113 static inline bool cpuset_issubset(const cpu_set_t *c1, const cpu_set_t *c2) {
114   for (int i = 0; i < CPU_SETSIZE; ++i)
115     if (CPU_ISSET(i, c1) && !CPU_ISSET(i, c2))
116       return false;
117   return true;
118 }
119 
cpuset_count(const cpu_set_t * cpuset)120 static inline int cpuset_count(const cpu_set_t *cpuset) {
121   int count = 0;
122   for (int i = 0; i < CPU_SETSIZE; ++i)
123     if (CPU_ISSET(i, cpuset))
124       ++count;
125   return count;
126 }
127 
cpuset_set_ab(cpu_set_t * cpuset,int a,int b)128 static inline void cpuset_set_ab(cpu_set_t *cpuset, int a, int b) {
129   CPU_ZERO(cpuset);
130   for (int i = a; i < b; ++i)
131     CPU_SET(i, cpuset);
132 }
133 
cpuset_format(const cpu_set_t * cpuset)134 static inline string cpuset_format(const cpu_set_t *cpuset) {
135   string format;
136   int digit = 0, last_non_zero_size = 1;
137   for (int i = 0; i < CPU_SETSIZE; ++i) {
138     if (CPU_ISSET(i, cpuset)) {
139       digit |= 1 << (i & 3);
140     }
141     if ((i & 3) == 3) {
142       format += char(digit <= 9 ? '0' + digit: 'A' + digit - 10);
143       if (digit) {
144         last_non_zero_size = format.size();
145         digit = 0;
146       }
147     }
148   }
149   if (digit) {
150     format += char(digit <= 9 ? '0' + digit: 'A' + digit - 10);
151     last_non_zero_size = format.size();
152   }
153   format.erase(last_non_zero_size);
154   reverse(format.begin(), format.end());
155   return format;
156 }
157 
158 static const int32 kUSleepOneSecond = 1000000;
159 
160 // This is guaranteed not to use signals.
sat_usleep(int32 microseconds)161 inline bool sat_usleep(int32 microseconds) {
162   timespec req;
163   req.tv_sec = microseconds / 1000000;
164   // Convert microseconds argument to nano seconds.
165   req.tv_nsec = (microseconds % 1000000) * 1000;
166   return nanosleep(&req, NULL) == 0;
167 }
168 
169 // This is guaranteed not to use signals.
sat_sleep(time_t seconds)170 inline bool sat_sleep(time_t seconds) {
171   timespec req;
172   req.tv_sec = seconds;
173   req.tv_nsec = 0;
174   return nanosleep(&req, NULL) == 0;
175 }
176 
177 // Get an error code description for use in error messages.
178 //
179 // Args:
180 //   error_num: an errno error code
ErrorString(int error_num)181 inline string ErrorString(int error_num) {
182   char buf[256];
183 #ifdef STRERROR_R_CHAR_P
184   return string(strerror_r(error_num, buf, sizeof buf));
185 #else
186   if (strerror_r(error_num, buf, sizeof buf))
187     return "unknown failure";
188   else
189     return string(buf);
190 #endif
191 }
192 
193 // Execute the cpuid instruction and pass back the contents of the registers.
194 // This only works on x86 based platforms.
cpuid(unsigned int * eax,unsigned int * ebx,unsigned int * ecx,unsigned int * edx)195 inline void cpuid(
196   unsigned int *eax, unsigned int *ebx, unsigned int *ecx, unsigned int *edx) {
197   *ebx = 0;
198   *ecx = 0;
199   *edx = 0;
200   // CPUID features documented at:
201   // http://www.sandpile.org/ia32/cpuid.htm
202 #if defined(STRESSAPPTEST_CPU_I686) || defined(STRESSAPPTEST_CPU_X86_64)
203 #if defined(__PIC__) && defined(STRESSAPPTEST_CPU_I686)
204   // In PIC compilations using the i686 cpu type, ebx contains the address
205   // of the global offset table. The compiler can't properly handle constraints
206   // using the ebx register for this compile, so preserve the register
207   // ourselves.
208   asm(
209     "mov %%ebx, %%edi;"
210     "cpuid;"
211     "xchg %%edi, %%ebx;"
212     // Output registers.
213     : "=a" (*eax), "=D" (*ebx), "=c" (*ecx), "=d" (*edx)
214     // Input registers.
215     : "a" (*eax)
216   );  // Asm
217 #else
218   asm(
219     "cpuid;"
220     // Output registers.
221     : "=a" (*eax), "=b" (*ebx), "=c" (*ecx), "=d" (*edx)
222     // Input registers.
223     : "a" (*eax)
224   );  // Asm
225 #endif  // defined(__PIC__) && defined(STRESSAPPTEST_CPU_I686)
226 #elif defined(STRESSAPPTEST_CPU_PPC)
227   return;
228 #elif defined(STRESSAPPTEST_CPU_ARMV7A)
229   return;
230 #elif defined(STRESSAPPTEST_CPU_AARCH64)
231   return;
232 #else
233 #warning "Unsupported CPU type."
234 #endif
235 }
236 
237 // Define handy constants here
238 static const int kTicksPerSec = 100;
239 static const int kMegabyte = (1024LL*1024LL);
240 static const int kSatDiskPageMax = 32;
241 static const int kSatDiskPage = 8;
242 static const int kSatPageSize = (1024LL*1024LL);
243 static const int kCacheLineSize = 64;
244 static const uint16_t kNetworkPort = 19996;
245 
246 #endif  // STRESSAPPTEST_SATTYPES_H_
247