aboutsummaryrefslogtreecommitdiff
path: root/src/sat.h
blob: 5cc3bec12adf15464fdffb7c11b3ea293726745a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
// 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.

// sat.h : sat stress test object interface and data structures

#ifndef STRESSAPPTEST_SAT_H_
#define STRESSAPPTEST_SAT_H_

#include <signal.h>

#include <map>
#include <string>
#include <vector>

// This file must work with autoconf on its public version,
// so these includes are correct.
#include "finelock_queue.h"
#include "queue.h"
#include "sattypes.h"
#include "worker.h"
#include "os.h"

// SAT stress test class.
class Sat {
 public:
  // Enum for page queue implementation switch.
  enum PageQueueType { SAT_ONELOCK, SAT_FINELOCK };

  Sat();
  virtual ~Sat();

  // Read configuration from arguments. Called first.
  bool ParseArgs(int argc, char **argv);
  virtual bool CheckGoogleSpecificArgs(int argc, char **argv, int *i);
  // Initialize data structures, subclasses, and resources,
  // based on command line args.
  // Called after ParseArgs().
  bool Initialize();

  // Execute the test. Initialize() and ParseArgs() must be called first.
  // This must be called from a single-threaded program.
  bool Run();

  // Pretty print result summary.
  // Called after Run().
  // Return value is success or failure of the SAT run, *not* of this function!
  bool PrintResults();

  // Pretty print version info.
  bool PrintVersion();

  // Pretty print help.
  virtual void PrintHelp();

  // Clean up allocations and resources.
  // Called last.
  bool Cleanup();

  // Abort Run().  Only for use by Run()-installed signal handlers.
  void Break() { user_break_ = true; }

  // Fetch and return empty and full pages into the empty and full pools.
  bool GetValid(struct page_entry *pe);
  bool PutValid(struct page_entry *pe);
  bool GetEmpty(struct page_entry *pe);
  bool PutEmpty(struct page_entry *pe);

  bool GetValid(struct page_entry *pe, int32 tag);
  bool GetEmpty(struct page_entry *pe, int32 tag);

  // Accessor functions.
  int verbosity() const { return verbosity_; }
  int logfile() const { return logfile_; }
  int page_length() const { return page_length_; }
  int disk_pages() const { return disk_pages_; }
  int strict() const { return strict_; }
  int tag_mode() const { return tag_mode_; }
  int status() const { return statuscount_; }
  void bad_status() { statuscount_++; }
  int errors() const { return errorcount_; }
  int warm() const { return warm_; }
  bool stop_on_error() const { return stop_on_error_; }
  int32 region_mask() const { return region_mask_; }
  // Semi-accessor to find the "nth" region to avoid replicated bit searching..
  int32 region_find(int32 num) const {
    for (int i = 0; i < 32; i++) {
      if ((1 << i) & region_mask_) {
        if (num == 0)
          return i;
        num--;
      }
    }
    return 0;
  }

  // Causes false errors for unittesting.
  // Setting to "true" causes errors to be injected.
  void set_error_injection(bool errors) { error_injection_ = errors; }
  bool error_injection() const { return error_injection_; }

 protected:
  // Opens log file for writing. Returns 0 on failure.
  bool InitializeLogfile();
  // Checks for supported environment. Returns 0 on failure.
  bool CheckEnvironment();
  // Allocates size_ bytes of test memory.
  bool AllocateMemory();
  // Initializes datapattern reference structures.
  bool InitializePatterns();
  // Initializes test memory with datapatterns.
  bool InitializePages();

  // Start up worker threads.
  virtual void InitializeThreads();
  // Spawn worker threads.
  void SpawnThreads();
  // Reap worker threads.
  void JoinThreads();
  // Run bandwidth and error analysis.
  virtual void RunAnalysis();
  // Delete worker threads.
  void DeleteThreads();

  // Return the number of cpus in the system.
  int CpuCount();
  // Return the worst-case (largest) cache line size of the system.
  int CacheLineSize();

  // Collect error counts from threads.
  int64 GetTotalErrorCount();

  // Command line arguments.
  string cmdline_;

  // Memory and test configuration.
  int runtime_seconds_;               // Seconds to run.
  int page_length_;                   // Length of each memory block.
  int64 pages_;                       // Number of memory blocks.
  int64 size_;                        // Size of memory tested, in bytes.
  int64 size_mb_;                     // Size of memory tested, in MB.
  int64 reserve_mb_;                  // Reserve at least this amount of memory
                                      // for the system, in MB.
  int64 min_hugepages_mbytes_;        // Minimum hugepages size.
  int64 freepages_;                   // How many invalid pages we need.
  int disk_pages_;                    // Number of pages per temp file.
  uint64 paddr_base_;                 // Physical address base.
  uint64 channel_hash_;               // Mask of address bits XORed for channel.
  int channel_width_;                 // Channel width in bits.
  vector< vector<string> > channels_;  // Memory module names per channel.

  // Control flags.
  volatile sig_atomic_t user_break_;  // User has signalled early exit.  Used as
                                      // a boolean.
  int verbosity_;                     // How much to print.
  int print_delay_;                   // Chatty update frequency.
  int strict_;                        // Check results per transaction.
  int warm_;                          // FPU warms CPU while copying.
  int address_mode_;                  // 32 or 64 bit binary.
  bool stop_on_error_;                // Exit immendiately on any error.
  bool findfiles_;                    // Autodetect tempfile locations.

  bool error_injection_;              // Simulate errors, for unittests.
  bool crazy_error_injection_;        // Simulate lots of errors.
  uint64 max_errorcount_;             // Number of errors before forced exit.
  int run_on_anything_;               // Ignore unknown machine ereor.
  int use_logfile_;                   // Log to a file.
  char logfilename_[255];             // Name of file to log to.
  int logfile_;                       // File handle to log to.
  bool log_timestamps_;               // Whether to add timestamps to log lines.

  // Disk thread options.
  int read_block_size_;               // Size of block to read from disk.
  int write_block_size_;              // Size of block to write to disk.
  int64 segment_size_;                // Size of segment to split disk into.
  int cache_size_;                    // Size of disk cache.
  int blocks_per_segment_;            // Number of blocks to test per segment.
  int read_threshold_;                // Maximum time (in us) a read should take
                                      // before warning of a slow read.
  int write_threshold_;               // Maximum time (in us) a write should
                                      // take before warning of a slow write.
  int non_destructive_;               // Whether to use non-destructive mode for
                                      // the disk test.

  // Generic Options.
  int monitor_mode_;                  // Switch for monitor-only mode SAT.
                                      // This switch trumps most of the other
                                      // argument, as SAT will only run error
                                      // polling threads.
  int tag_mode_;                      // Do tagging of memory and strict
                                      // checking for misplaced cachelines.

  bool do_page_map_;                  // Should we print a list of used pages?
  unsigned char *page_bitmap_;        // Store bitmap of physical pages seen.
  uint64 page_bitmap_size_;           // Length of physical memory represented.

  // Cpu Cache Coherency Options.
  bool cc_test_;                      // Flag to decide whether to start the
                                      // cache coherency threads.
  int cc_cacheline_count_;            // Number of cache line size structures.
  int cc_cacheline_size_;             // Size of a cache line.
  int cc_inc_count_;                  // Number of times to increment the shared
                                      // cache lines structure members.

  // Cpu Frequency Options.
  bool cpu_freq_test_;                // Flag to decide whether to start the
                                      // cpu frequency thread.
  int cpu_freq_threshold_;            // The MHz threshold which will cause
                                      // the test to fail.
  int cpu_freq_round_;                // Round the computed frequency to this
                                      // value.

  // Thread control.
  int file_threads_;                  // Threads of file IO.
  int net_threads_;                   // Threads of network IO.
  int listen_threads_;                // Threads for network IO to connect.
  int memory_threads_;                // Threads of memcpy.
  int invert_threads_;                // Threads of invert.
  int fill_threads_;                  // Threads of memset.
  int check_threads_;                 // Threads of strcmp.
  int cpu_stress_threads_;            // Threads of CPU stress workload.
  int disk_threads_;                  // Threads of disk test.
  int random_threads_;                // Number of random disk threads.
  int total_threads_;                 // Total threads used.
  bool error_poll_;                   // Poll for system errors.

  // Resources.
  cc_cacheline_data *cc_cacheline_data_;  // The cache line sized datastructure
                                          // used by the ccache threads
                                          // (in worker.h).
  vector<string> filename_;           // Filenames for file IO.
  vector<string> ipaddrs_;            // Addresses for network IO.
  vector<string> diskfilename_;       // Filename for disk IO device.
  // Block table for IO device.
  vector<DiskBlockTable*> blocktables_;

  int32 region_mask_;                 // Bitmask of available NUMA regions.
  int32 region_count_;                // Count of available NUMA regions.
  int32 region_[32];                  // Pagecount per region.
  int region_mode_;                   // What to do with NUMA hints?
  static const int kLocalNuma = 1;    // Target local memory.
  static const int kRemoteNuma = 2;   // Target remote memory.

  // Results.
  int64 errorcount_;                  // Total hardware incidents seen.
  int statuscount_;                   // Total test errors seen.

  // Thread type constants and types
  enum ThreadType {
    kMemoryType = 0,
    kFileIOType = 1,
    kNetIOType = 2,
    kNetSlaveType = 3,
    kCheckType = 4,
    kInvertType = 5,
    kDiskType = 6,
    kRandomDiskType = 7,
    kCPUType = 8,
    kErrorType = 9,
    kCCType = 10,
    kCPUFreqType = 11,
  };

  // Helper functions.
  virtual void AcquireWorkerLock();
  virtual void ReleaseWorkerLock();
  pthread_mutex_t worker_lock_;  // Lock access to the worker thread structure.
  typedef vector<WorkerThread*> WorkerVector;
  typedef map<int, WorkerVector*> WorkerMap;
  // Contains all worker threads.
  WorkerMap workers_map_;
  // Delay between power spikes.
  time_t pause_delay_;
  // The duration of each pause (for power spikes).
  time_t pause_duration_;
  // For the workers we pause and resume to create power spikes.
  WorkerStatus power_spike_status_;
  // For the workers we never pause.
  WorkerStatus continuous_status_;

  class OsLayer *os_;                   // Os abstraction: put hacks here.
  class PatternList *patternlist_;      // Access to global data patterns.

  // RunAnalysis methods
  void AnalysisAllStats();              // Summary of all runs.
  void MemoryStats();
  void FileStats();
  void NetStats();
  void CheckStats();
  void InvertStats();
  void DiskStats();

  void QueueStats();

  // Physical page use reporting.
  void AddrMapInit();
  void AddrMapUpdate(struct page_entry *pe);
  void AddrMapPrint();

  // additional memory data from google-specific tests.
  virtual void GoogleMemoryStats(float *memcopy_data,
                                 float *memcopy_bandwidth);

  virtual void GoogleOsOptions(std::map<std::string, std::string> *options);

  // Page queues, only one of (valid_+empty_) or (finelock_q_) will be used
  // at a time. A commandline switch controls which queue implementation will
  // be used.
  class PageEntryQueue *valid_;        // Page queue structure, valid pages.
  class PageEntryQueue *empty_;        // Page queue structure, free pages.
  class FineLockPEQueue *finelock_q_;  // Page queue with fine-grain locks
  Sat::PageQueueType pe_q_implementation_;   // Queue implementation switch

  DISALLOW_COPY_AND_ASSIGN(Sat);
};

Sat *SatFactory();

#endif  // STRESSAPPTEST_SAT_H_