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