1b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Copyright 2006 Google Inc. All Rights Reserved. 2b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 3b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Licensed under the Apache License, Version 2.0 (the "License"); 4b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// you may not use this file except in compliance with the License. 5b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// You may obtain a copy of the License at 6b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 7b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// http://www.apache.org/licenses/LICENSE-2.0 8b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 9b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Unless required by applicable law or agreed to in writing, software 10b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// distributed under the License is distributed on an "AS IS" BASIS, 11b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// See the License for the specific language governing permissions and 13b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// limitations under the License. 14b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 15b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// sat.cc : a stress test for stressful testing 16b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 17b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// stressapptest (or SAT, from Stressful Application Test) is a test 18b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// designed to stress the system, as well as provide a comprehensive 19b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// memory interface test. 20b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 21b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// stressapptest can be run using memory only, or using many system components. 22b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 23b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <errno.h> 24b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <pthread.h> 25b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <signal.h> 26b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <stdarg.h> 27b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <stdio.h> 28b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <stdlib.h> 29b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <string.h> 30b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <unistd.h> 31b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 32b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <sys/stat.h> 33b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <sys/times.h> 34b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 35b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// #define __USE_GNU 36b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// #define __USE_LARGEFILE64 37b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <fcntl.h> 38b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 39b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <list> 40b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <string> 41b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 42b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This file must work with autoconf on its public version, 43b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// so these includes are correct. 44b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "disk_blocks.h" 45b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "logger.h" 46b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "os.h" 47b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "sat.h" 48b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "sattypes.h" 49b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "worker.h" 50b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 51b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// stressapptest versioning here. 52b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#ifndef PACKAGE_VERSION 53b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonstatic const char* kVersion = "1.0.0"; 54b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#else 55b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonstatic const char* kVersion = PACKAGE_VERSION; 56b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#endif 57b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 58b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Global stressapptest reference, for use by signal handler. 59b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This makes Sat objects not safe for multiple instances. 60b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonnamespace { 61b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Sat *g_sat = NULL; 62b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 63b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Signal handler for catching break or kill. 64b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 65b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This must be installed after g_sat is assigned and while there is a single 66b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // thread. 67b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 68b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This must be uninstalled while there is only a single thread, and of course 69b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // before g_sat is cleared or deleted. 70b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SatHandleBreak(int signal) { 71b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson g_sat->Break(); 72b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 73b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 74b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 75b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Opens the logfile for writing if necessary 76b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::InitializeLogfile() { 77b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Open logfile. 78b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (use_logfile_) { 79b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfile_ = open(logfilename_, 808f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#if defined(O_DSYNC) 818f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson O_DSYNC | 828f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#elif defined(O_SYNC) 838f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson O_SYNC | 848f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#elif defined(O_FSYNC) 858f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson O_FSYNC | 868f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 878f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson O_WRONLY | O_CREAT, 88b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 89b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (logfile_ < 0) { 90b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("Fatal Error: cannot open file %s for logging\n", 91b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfilename_); 92b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 93b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 94b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 95b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We seek to the end once instead of opening in append mode because no 96b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // other processes should be writing to it while this one exists. 97b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (lseek(logfile_, 0, SEEK_END) == -1) { 98b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("Fatal Error: cannot seek to end of logfile (%s)\n", 99b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfilename_); 100b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 101b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 102b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 103b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetLogFd(logfile_); 104b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 105b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 106b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 107b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 108b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Check that the environment is known and safe to run on. 109b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Return 1 if good, 0 if unsuppported. 110b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::CheckEnvironment() { 111b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Check that this is not a debug build. Debug builds lack 112b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // enough performance to stress the system. 113b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#if !defined NDEBUG 114b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (run_on_anything_) { 115b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Log: Running DEBUG version of SAT, " 116b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with significantly reduced coverage.\n"); 117b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 118b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Running DEBUG version of SAT, " 119b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with significantly reduced coverage.\n"); 120b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: Command line option '-A' bypasses this error.\n"); 121b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 122b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 123b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 124b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#elif !defined CHECKOPTS 125b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson #error Build system regression - COPTS disregarded. 126b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#endif 127b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 128241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Check if the cpu frequency test is enabled and able to run. 129241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (cpu_freq_test_) { 130241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (!CpuFreqThread::CanRun()) { 131241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(0, "Process Error: This platform does not support this " 132241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "test.\n"); 133241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 134241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 135241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } else if (cpu_freq_threshold_ <= 0) { 136241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(0, "Process Error: The cpu frequency test requires " 137241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "--cpu_freq_threshold set to a value > 0\n"); 138241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 139241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 140241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } else if (cpu_freq_round_ < 0) { 141241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(0, "Process Error: The --cpu_freq_round option must be greater" 142241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " than or equal to zero. A value of zero means no rounding.\n"); 143241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 144241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 145241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 146241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 147241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 148b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Use all CPUs if nothing is specified. 149b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (memory_threads_ == -1) { 150b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memory_threads_ = os_->num_cpus(); 151b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(7, "Log: Defaulting to %d copy threads\n", memory_threads_); 152b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 153b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 154b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Use all memory if no size is specified. 155b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (size_mb_ == 0) 156b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_ = os_->FindFreeMemSize() / kMegabyte; 157b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = static_cast<int64>(size_mb_) * kMegabyte; 158b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 159b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Autodetect file locations. 160b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (findfiles_ && (file_threads_ == 0)) { 161b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get a space separated sting of disk locations. 162b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson list<string> locations = os_->FindFileDevices(); 163b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 164b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Extract each one. 165b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson while (!locations.empty()) { 166b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Copy and remove the disk name. 167b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string disk = locations.back(); 168b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson locations.pop_back(); 169b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 170b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: disk at %s\n", disk.c_str()); 171b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_++; 172b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson filename_.push_back(disk + "/sat_disk.a"); 173b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_++; 174b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson filename_.push_back(disk + "/sat_disk.b"); 175b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 176b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 177b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 178b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We'd better have some memory by this point. 179b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (size_ < 1) { 180b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: No memory found to test.\n"); 181b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 182b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 183b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 184b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 185b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (tag_mode_ && ((file_threads_ > 0) || 186b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (disk_threads_ > 0) || 187b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (net_threads_ > 0))) { 188b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Memory tag mode incompatible " 189b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with disk/network DMA.\n"); 190b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 191b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 192b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 193b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 194b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // If platform is 32 bit Xeon, floor memory size to multiple of 4. 195b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (address_mode_ == 32) { 196b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_ = (size_mb_ / 4) * 4; 197b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = size_mb_ * kMegabyte; 198b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Log: Flooring memory allocation to multiple of 4: %lldMB\n", 199b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_); 200b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 201b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 202b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Check if this system is on the whitelist for supported systems. 203b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!os_->IsSupported()) { 204b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (run_on_anything_) { 205b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Log: Unsupported system. Running with reduced coverage.\n"); 206b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is ok, continue on. 207b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 208b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Unsupported system, " 209b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "no error reporting available\n"); 210b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: Command line option '-A' bypasses this error.\n"); 211b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 212b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 213b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 214b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 215b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 216b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 217b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 218b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 219b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Allocates memory to run the test on 220b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::AllocateMemory() { 221b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate our test memory. 222b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = os_->AllocateTestMem(size_, paddr_base_); 223b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!result) { 224b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: failed to allocate memory\n"); 225b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 226b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 227b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 228b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 229b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 230b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 231b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Sets up access to data patterns 232b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::InitializePatterns() { 233b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize pattern data. 234b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_ = new PatternList(); 235b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!patternlist_) { 236b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: failed to allocate patterns\n"); 237b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 238b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 239b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 240b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!patternlist_->Initialize()) { 241b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: failed to initialize patternlist\n"); 242b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 243b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 244b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 245b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 246b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 247b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 248b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Get any valid page, no tag specified. 249b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetValid(struct page_entry *pe) { 250b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return GetValid(pe, kDontCareTag); 251b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 252b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 253b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 254b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Fetch and return empty and full pages into the empty and full pools. 255b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetValid(struct page_entry *pe, int32 tag) { 256b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = false; 257b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get valid page depending on implementation. 258b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 259b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = finelock_q_->GetValid(pe, tag); 260b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 261b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = valid_->PopRandom(pe); 262b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 263b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (result) { 264b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = os_->PrepareTestMem(pe->offset, page_length_); // Map it. 265b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 266b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tag this access and current pattern. 267b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->ts = os_->GetTimestamp(); 268b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->lastpattern = pe->pattern; 269b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 270b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return (pe->addr != 0); // Return success or failure. 271b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 272b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 273b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 274b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 275b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PutValid(struct page_entry *pe) { 276b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe->addr != 0) 277b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->ReleaseTestMem(pe->addr, pe->offset, page_length_); // Unmap the page. 278b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = 0; 279b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 280b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Put valid page depending on implementation. 281b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 282b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return finelock_q_->PutValid(pe); 283b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 284b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return valid_->Push(pe); 285b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else 286b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 287b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 288b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 289b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Get an empty page with any tag. 290b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetEmpty(struct page_entry *pe) { 291b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return GetEmpty(pe, kDontCareTag); 292b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 293b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 294b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetEmpty(struct page_entry *pe, int32 tag) { 295b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = false; 296b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get empty page depending on implementation. 297b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 298b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = finelock_q_->GetEmpty(pe, tag); 299b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 300b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = empty_->PopRandom(pe); 301b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 302b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (result) { 303b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = os_->PrepareTestMem(pe->offset, page_length_); // Map it. 304b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return (pe->addr != 0); // Return success or failure. 305b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 306b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 307b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 308b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 309b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PutEmpty(struct page_entry *pe) { 310b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe->addr != 0) 311b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->ReleaseTestMem(pe->addr, pe->offset, page_length_); // Unmap the page. 312b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = 0; 313b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 314b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Put empty page depending on implementation. 315b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 316b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return finelock_q_->PutEmpty(pe); 317b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 318b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return empty_->Push(pe); 319b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else 320b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 321b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 322b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 323b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Set up the bitmap of physical pages in case we want to see which pages were 324b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// accessed under this run of SAT. 325b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AddrMapInit() { 326b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!do_page_map_) 327b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 328b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Find about how much physical mem is in the system. 329b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // TODO(nsanders): Find some way to get the max 330b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // and min phys addr in the system. 331b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 maxsize = os_->FindFreeMemSize() * 4; 332b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(maxsize != 0); 333b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 334b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Make a bitmask of this many pages. Assume that the memory is relatively 335b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // zero based. This is true on x86, typically. 336b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is one bit per page. 337b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 arraysize = maxsize / 4096 / 8; 338b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned char *bitmap = new unsigned char[arraysize]; 339b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(bitmap); 340b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 341b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Mark every page as 0, not seen. 342b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memset(bitmap, 0, arraysize); 343b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 344b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_size_ = maxsize; 345b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_ = bitmap; 346b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 347b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 348b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Add the 4k pages in this block to the array of pages SAT has seen. 349b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AddrMapUpdate(struct page_entry *pe) { 350b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!do_page_map_) 351b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 352b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 353b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Go through 4k page blocks. 354b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 arraysize = page_bitmap_size_ / 4096 / 8; 355b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 356b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char *base = reinterpret_cast<char*>(pe->addr); 357b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < page_length_; i += 4096) { 358b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 paddr = os_->VirtualToPhysical(base + i); 359b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 360b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint32 offset = paddr / 4096 / 8; 361b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned char mask = 1 << ((paddr / 4096) % 8); 362b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 363b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (offset >= arraysize) { 364b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Physical address %#llx is " 365b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "greater than expected %#llx.\n", 366b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson paddr, page_bitmap_size_); 367b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0); 368b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 369b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_[offset] |= mask; 370b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 371b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 372b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 373b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Print out the physical memory ranges that SAT has accessed. 374b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AddrMapPrint() { 375b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!do_page_map_) 376b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 377b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 378b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 pages = page_bitmap_size_ / 4096; 379b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 380b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 last_page = 0; 381b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool valid_range = false; 382b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 383b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Printing tested physical ranges.\n"); 384b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 385b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (uint64 i = 0; i < pages; i ++) { 386b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int offset = i / 8; 387b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned char mask = 1 << (i % 8); 388b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 389b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool touched = page_bitmap_[offset] & mask; 390b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (touched && !valid_range) { 391b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_range = true; 392b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson last_page = i * 4096; 393b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (!touched && valid_range) { 394b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_range = false; 395b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: %#016llx - %#016llx\n", last_page, (i * 4096) - 1); 396b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 397b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 398b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Done printing physical ranges.\n"); 399b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 400b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 401b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Initializes page lists and fills pages with data patterns. 402b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::InitializePages() { 403b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int result = 1; 404b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate needed page totals. 405b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 neededpages = memory_threads_ + 406b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_threads_ + 407b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_threads_ + 408b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_threads_ + 409b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_; 410b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 411b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Empty-valid page ratio is adjusted depending on queue implementation. 412b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // since fine-grain-locked queue keeps both valid and empty entries in the 413b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // same queue and randomly traverse to find pages, the empty-valid ratio 414b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // should be more even. 415b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 416b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_ = pages_ / 5 * 2; // Mark roughly 2/5 of all pages as Empty. 417b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else 418b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_ = (pages_ / 100) + (2 * neededpages); 419b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 420b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (freepages_ < neededpages) { 421b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: freepages < neededpages.\n"); 422b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Stats: Total: %lld, Needed: %lld, Marked free: %lld\n", 423b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(pages_), 424b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(neededpages), 425b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(freepages_)); 426b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 427b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 428b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 429b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 430b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (freepages_ > pages_/2) { 431b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: not enough pages for IO\n"); 432b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Stats: Total: %lld, Needed: %lld, Available: %lld\n", 433b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(pages_), 434b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(freepages_), 435b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(pages_/2)); 436b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 437b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 438b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 439b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Allocating pages, Total: %lld Free: %lld\n", 440b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_, 441b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_); 442b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 443b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize page locations. 444b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int64 i = 0; i < pages_; i++) { 445b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry pe; 446b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson init_pe(&pe); 447b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe.offset = i * page_length_; 448b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result &= PutEmpty(&pe); 449b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 450b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 451b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!result) { 452b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: while initializing empty_ list\n"); 453b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 454b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 455b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 456b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 457b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fill valid pages with test patterns. 458b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Use fill threads to do this. 459b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus fill_status; 460b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector fill_vector; 461b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 462b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Starting Fill threads: %d threads, %d pages\n", 463b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_threads_, pages_); 464b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize the fill threads. 465b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < fill_threads_; i++) { 466b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FillThread *thread = new FillThread(); 467b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(i, this, os_, patternlist_, &fill_status); 468b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i != fill_threads_ - 1) { 469b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Starting Fill Threads %d: %d pages\n", 470b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i, pages_ / fill_threads_); 471b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetFillPages(pages_ / fill_threads_); 472b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // The last thread finishes up all the leftover pages. 473b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 474b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Starting Fill Threads %d: %d pages\n", 475b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i, pages_ - pages_ / fill_threads_ * i); 476b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetFillPages(pages_ - pages_ / fill_threads_ * i); 477b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 478b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_vector.push_back(thread); 479b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 480b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 481b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn the fill threads. 482b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_status.Initialize(); 483b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = fill_vector.begin(); 484b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != fill_vector.end(); ++it) 485b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->SpawnThread(); 486b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 487b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Reap the finished fill threads. 488b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = fill_vector.begin(); 489b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != fill_vector.end(); ++it) { 490b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->JoinThread(); 491b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetStatus() != 1) { 492b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Thread %d failed with status %d at %.2f seconds\n", 493b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetStatus(), 494b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->GetRunDurationUSec() * 1.0/1000000); 495b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 496b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 497b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 498b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete (*it); 499b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 500b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_vector.clear(); 501b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_status.Destroy(); 502b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Done filling pages.\n"); 503b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Allocating pages.\n"); 504b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 505b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AddrMapInit(); 506b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 507b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize page locations. 508b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int64 i = 0; i < pages_; i++) { 509b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry pe; 510b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Only get valid pages with uninitialized tags here. 511b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (GetValid(&pe, kInvalidTag)) { 512b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 paddr = os_->VirtualToPhysical(pe.addr); 513b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int32 region = os_->FindRegion(paddr); 514b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_[region]++; 515b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe.paddr = paddr; 516b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe.tag = 1 << region; 517b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_mask_ |= pe.tag; 518b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 519b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Generate a physical region map 520b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AddrMapUpdate(&pe); 521b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 522b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Note: this does not allocate free pages among all regions 523b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // fairly. However, with large enough (thousands) random number 524b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // of pages being marked free in each region, the free pages 525b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // count in each region end up pretty balanced. 526b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < freepages_) { 527b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result &= PutEmpty(&pe); 528b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 529b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result &= PutValid(&pe); 530b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 531b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 532b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: didn't tag all pages. %d - %d = %d\n", 533b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_, i, pages_ - i); 534b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 535b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 536b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 537b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Done allocating pages.\n"); 538b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 539b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AddrMapPrint(); 540b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 541b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < 32; i++) { 542b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (region_mask_ & (1 << i)) { 543b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_count_++; 544b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Region %d: %d.\n", i, region_[i]); 545b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 546b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 547b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Region mask: 0x%x\n", region_mask_); 548b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 549b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 550b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 551b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 552b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Print SAT version info. 553b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PrintVersion() { 554b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Stats: SAT revision %s, %d bit binary\n", 555b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson kVersion, address_mode_); 556b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: %s from %s\n", Timestamp(), BuildChangelist()); 557b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 558b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 559b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 560b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 561b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 562b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Initializes the resources that SAT needs to run. 563b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This needs to be called before Run(), and after ParseArgs(). 564b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Returns true on success, false on error, and will exit() on help message. 565b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::Initialize() { 566b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson g_sat = this; 567b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 568b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initializes sync'd log file to ensure output is saved. 569b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!InitializeLogfile()) 570b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 571241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders Logger::GlobalLogger()->SetTimestampLogging(log_timestamps_); 572b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->StartThread(); 573b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 574b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Commandline - %s\n", cmdline_.c_str()); 575b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PrintVersion(); 576b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 577b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson std::map<std::string, std::string> options; 578b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 579b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson GoogleOsOptions(&options); 580b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 581b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize OS/Hardware interface. 582b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_ = OsLayerFactory(options); 583b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!os_) { 584b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 585b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 586b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 587b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 588b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (min_hugepages_mbytes_ > 0) 589b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->SetMinimumHugepagesSize(min_hugepages_mbytes_ * kMegabyte); 590b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 591241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (reserve_mb_ > 0) 592241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders os_->SetReserveSize(reserve_mb_); 593241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 594241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (channels_.size() > 0) { 595241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(6, "Log: Decoding memory: %dx%d bit channels," 596241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "%d modules per channel (x%d), decoding hash 0x%x\n", 597241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channels_.size(), channel_width_, channels_[0].size(), 598241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channel_width_/channels_[0].size(), channel_hash_); 599241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders os_->SetDramMappingParams(channel_hash_, channel_width_, &channels_); 600241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 601241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 602b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!os_->Initialize()) { 603b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Failed to initialize OS layer\n"); 604b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 605b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete os_; 606b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 607b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 608b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 609b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Checks that OS/Build/Platform is supported. 610b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!CheckEnvironment()) 611b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 612b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 613b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (error_injection_) 614b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->set_error_injection(true); 615b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 616b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run SAT in monitor only mode, do not continue to allocate resources. 617b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (monitor_mode_) { 618b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Running in monitor-only mode. " 619b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "Will not allocate any memory nor run any stress test. " 620b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "Only polling ECC errors.\n"); 621b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 622b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 623b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 624b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate the memory to test. 625b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!AllocateMemory()) 626b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 627b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 628b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Stats: Starting SAT, %dM, %d seconds\n", 629b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(size_/kMegabyte), 630b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runtime_seconds_); 631b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 632b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!InitializePatterns()) 633b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 634b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 635b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize memory allocation. 636b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_ = size_ / page_length_; 637b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 638b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate page queue depending on queue implementation switch. 639b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) { 640b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_ = new FineLockPEQueue(pages_, page_length_); 641b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (finelock_q_ == NULL) 642b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 643b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_->set_os(os_); 644b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->set_err_log_callback(finelock_q_->get_err_log_callback()); 645b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (pe_q_implementation_ == SAT_ONELOCK) { 646b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson empty_ = new PageEntryQueue(pages_); 647b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_ = new PageEntryQueue(pages_); 648b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((empty_ == NULL) || (valid_ == NULL)) 649b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 650b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 651b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 652b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!InitializePages()) { 653b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Initialize Pages failed\n"); 654b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 655b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 656b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 657b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 658b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 659b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 660b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Constructor and destructor. 661b0114cb9f332db144f65291211ae65f7f0e814e6Scott AndersonSat::Sat() { 662b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set defaults, command line might override these. 663b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runtime_seconds_ = 20; 664b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_length_ = kSatPageSize; 665b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_pages_ = kSatDiskPage; 666b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_ = 0; 667b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_ = 0; 668b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = size_mb_ * kMegabyte; 669241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders reserve_mb_ = 0; 670b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson min_hugepages_mbytes_ = 0; 671b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_ = 0; 672b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson paddr_base_ = 0; 673241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channel_hash_ = kCacheLineSize; 674241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channel_width_ = 64; 675b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 676b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson user_break_ = false; 677b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson verbosity_ = 8; 678b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetVerbosity(verbosity_); 679241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders print_delay_ = 10; 680b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson strict_ = 1; 681b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson warm_ = 0; 682b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson run_on_anything_ = 0; 683b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson use_logfile_ = 0; 684b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfile_ = 0; 685241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders log_timestamps_ = true; 686b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Detect 32/64 bit binary. 687b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *pvoid = 0; 688b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson address_mode_ = sizeof(pvoid) * 8; 689b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_injection_ = false; 690b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson crazy_error_injection_ = false; 691b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson max_errorcount_ = 0; // Zero means no early exit. 692b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson stop_on_error_ = false; 693b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_poll_ = true; 694b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson findfiles_ = false; 695b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 696b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson do_page_map_ = false; 697b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_ = 0; 698b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_size_ = 0; 699b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 700b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Cache coherency data initialization. 701b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_test_ = false; // Flag to trigger cc threads. 702b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_count_ = 2; // Two datastructures of cache line size. 703241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders cc_cacheline_size_ = 0; // Size of a cacheline (0 for auto-detect). 704b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_inc_count_ = 1000; // Number of times to increment the shared variable. 705b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data_ = 0; // Cache Line size datastructure. 706b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 707241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Cpu frequency data initialization. 708241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders cpu_freq_test_ = false; // Flag to trigger cpu frequency thread. 709241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders cpu_freq_threshold_ = 0; // Threshold, in MHz, at which a cpu fails. 710241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders cpu_freq_round_ = 10; // Round the computed frequency to this value. 711241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 712b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_init(&worker_lock_, NULL)); 713b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_ = 0; 714b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_threads_ = 0; 715b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson listen_threads_ = 0; 716b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Default to autodetect number of cpus, and run that many threads. 717b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memory_threads_ = -1; 718b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_threads_ = 0; 719b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_threads_ = 8; 720b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_threads_ = 0; 721b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_stress_threads_ = 0; 722b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_threads_ = 0; 723b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_threads_ = 0; 724b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 725b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_mask_ = 0; 726b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_count_ = 0; 727b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < 32; i++) { 728b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_[i] = 0; 729b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 730b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_mode_ = 0; 731b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 732b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_ = 0; 733b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson statuscount_ = 0; 734b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 735b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_ = 0; 736b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson empty_ = 0; 737b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_ = 0; 738b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Default to use fine-grain lock for better performance. 739b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe_q_implementation_ = SAT_FINELOCK; 740b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 741b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_ = 0; 742b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_ = 0; 743b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfilename_[0] = 0; 744b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 745b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_block_size_ = 512; 746b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson write_block_size_ = -1; 747b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson segment_size_ = -1; 748b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cache_size_ = -1; 749b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_per_segment_ = -1; 750b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_threshold_ = -1; 751b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson write_threshold_ = -1; 752b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson non_destructive_ = 1; 753b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson monitor_mode_ = 0; 754b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson tag_mode_ = 0; 755b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson random_threads_ = 0; 756b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 757b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pause_delay_ = 600; 758b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pause_duration_ = 15; 759b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 760b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 761b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Destructor. 762b0114cb9f332db144f65291211ae65f7f0e814e6Scott AndersonSat::~Sat() { 763b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We need to have called Cleanup() at this point. 764b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We should probably enforce this. 765b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 766b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 767b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 768b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define ARG_KVALUE(argument, variable, value) \ 769b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], argument)) { \ 770b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson variable = value; \ 771b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; \ 772b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 773b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 774b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define ARG_IVALUE(argument, variable) \ 775b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], argument)) { \ 776b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; \ 777b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) \ 778b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson variable = strtoull(argv[i], NULL, 0); \ 779b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; \ 780b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 781b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 782b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define ARG_SVALUE(argument, variable) \ 783b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], argument)) { \ 784b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; \ 785b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) \ 786b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson snprintf(variable, sizeof(variable), "%s", argv[i]); \ 787b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; \ 788b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 789b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 790b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Configures SAT from command line arguments. 791b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This will call exit() given a request for 792b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// self-documentation or unexpected args. 793b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::ParseArgs(int argc, char **argv) { 794b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int i; 795b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 filesize = page_length_ * disk_pages_; 796b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 797b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Parse each argument. 798b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (i = 1; i < argc; i++) { 799b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Switch to fall back to corase-grain-lock queue. (for benchmarking) 800b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--coarse_grain_lock", pe_q_implementation_, SAT_ONELOCK); 801b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 802b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of megabyte to use. 803b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-M", size_mb_); 804b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 805241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Specify the amount of megabytes to be reserved for system. 806241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_IVALUE("--reserve_memory", reserve_mb_); 807241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 808b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set minimum megabytes of hugepages to require. 809b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-H", min_hugepages_mbytes_); 810b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 811b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of seconds to run. 812b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-s", runtime_seconds_); 813b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 814b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of memory copy threads. 815b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-m", memory_threads_); 816b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 817b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of memory invert threads. 818b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-i", invert_threads_); 819b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 820b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of check-only threads. 821b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-c", check_threads_); 822b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 823b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of cache line size datastructures. 824b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--cc_inc_count", cc_inc_count_); 825b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 826b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of cache line size datastructures 827b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--cc_line_count", cc_cacheline_count_); 828b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 829241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Override the detected or assumed cache line size. 830241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_IVALUE("--cc_line_size", cc_cacheline_size_); 831241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 832b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Flag set when cache coherency tests need to be run 833241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_KVALUE("--cc_test", cc_test_, true); 834241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 835241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Set when the cpu_frequency test needs to be run 836241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_KVALUE("--cpu_freq_test", cpu_freq_test_, true); 837241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 838241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Set the threshold in MHz at which the cpu frequency test will fail. 839241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_IVALUE("--cpu_freq_threshold", cpu_freq_threshold_); 840241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 841241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Set the rounding value for the cpu frequency test. The default is to 842241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // round to the nearest 10s value. 843241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_IVALUE("--cpu_freq_round", cpu_freq_round_); 844b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 845b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of CPU stress threads. 846b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-C", cpu_stress_threads_); 847b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 848b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set logfile name. 849b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_SVALUE("-l", logfilename_); 850b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 851b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Verbosity level. 852b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-v", verbosity_); 853b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 854241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Chatty printout level. 855241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_IVALUE("--printsec", print_delay_); 856241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 857241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Turn off timestamps logging. 858241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_KVALUE("--no_timestamps", log_timestamps_, false); 859241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 860b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set maximum number of errors to collect. Stop running after this many. 861b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--max_errors", max_errorcount_); 862b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 863b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set pattern block size. 864b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-p", page_length_); 865b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 866b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set pattern block size. 867b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--filesize", filesize); 868b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 869b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // NUMA options. 870b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--local_numa", region_mode_, kLocalNuma); 871b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--remote_numa", region_mode_, kRemoteNuma); 872b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 873b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Autodetect tempfile locations. 874b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--findfiles", findfiles_, 1); 875b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 876b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Inject errors to force miscompare code paths 877b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--force_errors", error_injection_, true); 878b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--force_errors_like_crazy", crazy_error_injection_, true); 879b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (crazy_error_injection_) 880b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_injection_ = true; 881b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 882b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Stop immediately on any arror, for debugging HW problems. 883b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--stop_on_errors", stop_on_error_, 1); 884b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 885b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Don't use internal error polling, allow external detection. 886b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--no_errors", error_poll_, 0); 887b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 888b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Never check data as you go. 889b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("-F", strict_, 0); 890b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 891b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Warm the cpu as you go. 892b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("-W", warm_, 1); 893b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 894b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allow runnign on unknown systems with base unimplemented OsLayer 895b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("-A", run_on_anything_, 1); 896b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 897b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of read blocks for disk test. 898b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--read-block-size", read_block_size_); 899b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 900b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of write blocks for disk test. 901b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--write-block-size", write_block_size_); 902b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 903b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of segment for disk test. 904b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--segment-size", segment_size_); 905b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 906b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of disk cache size for disk test. 907b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--cache-size", cache_size_); 908b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 909b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Number of blocks to test per segment. 910b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--blocks-per-segment", blocks_per_segment_); 911b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 912b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Maximum time a block read should take before warning. 913b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--read-threshold", read_threshold_); 914b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 915b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Maximum time a block write should take before warning. 916b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--write-threshold", write_threshold_); 917b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 918b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do not write anything to disk in the disk test. 919b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--destructive", non_destructive_, 0); 920b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 921b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run SAT in monitor mode. No test load at all. 922b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--monitor_mode", monitor_mode_, true); 923b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 924b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run SAT in address mode. Tag all cachelines by virt addr. 925b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--tag_mode", tag_mode_, true); 926b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 927b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Dump range map of tested pages.. 928b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--do_page_map", do_page_map_, true); 929b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 930b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specify the physical address base to test. 931b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--paddr_base", paddr_base_); 932b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 933b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specify the frequency for power spikes. 934b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--pause_delay", pause_delay_); 935b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 936b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specify the duration of each pause (for power spikes). 937b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--pause_duration", pause_duration_); 938b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 939b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Disk device names 940b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], "-d")) { 941b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; 942b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) { 943b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_threads_++; 944b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson diskfilename_.push_back(string(argv[i])); 945b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocktables_.push_back(new DiskBlockTable()); 946b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 947b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 948b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 949b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 950b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of disk random threads for each disk write thread. 951b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--random-threads", random_threads_); 952b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 953b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set a tempfile to use in a file thread. 954b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], "-f")) { 955b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; 956b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) { 957b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_++; 958b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson filename_.push_back(string(argv[i])); 959b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 960b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 961b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 962b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 963b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set a hostname to use in a network thread. 964b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], "-n")) { 965b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; 966b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) { 967b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_threads_++; 968b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ipaddrs_.push_back(string(argv[i])); 969b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 970b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 971b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 972b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 973b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run threads that listen for incoming SAT net connections. 974b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--listen", listen_threads_, 1); 975b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 976b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (CheckGoogleSpecificArgs(argc, argv, &i)) { 977b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 978b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 979b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 980241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_IVALUE("--channel_hash", channel_hash_); 981241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ARG_IVALUE("--channel_width", channel_width_); 982241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 983241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (!strcmp(argv[i], "--memory_channel")) { 984241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders i++; 985241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (i < argc) { 986241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders char *channel = argv[i]; 987241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channels_.push_back(vector<string>()); 988241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders while (char* next = strchr(channel, ',')) { 989241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channels_.back().push_back(string(channel, next - channel)); 990241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channel = next + 1; 991241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 992241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channels_.back().push_back(string(channel)); 993241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 994241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders continue; 995241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 996241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 997b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Default: 998b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PrintVersion(); 999b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PrintHelp(); 1000b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (strcmp(argv[i], "-h") && strcmp(argv[i], "--help")) { 1001b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("\n Unknown argument %s\n", argv[i]); 1002b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 1003b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson exit(1); 1004b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1005b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Forget it, we printed the help, just bail. 1006b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We don't want to print test status, or any log parser stuff. 1007b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson exit(0); 1008b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1009b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1010b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetVerbosity(verbosity_); 1011b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1012b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Update relevant data members with parsed input. 1013b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Translate MB into bytes. 1014b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = static_cast<int64>(size_mb_) * kMegabyte; 1015b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1016b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set logfile flag. 1017b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (strcmp(logfilename_, "")) 1018b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson use_logfile_ = 1; 1019b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Checks valid page length. 1020b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (page_length_ && 1021b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson !(page_length_ & (page_length_ - 1)) && 1022b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (page_length_ > 1023)) { 1023b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Prints if we have changed from default. 1024b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (page_length_ != kSatPageSize) 1025b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Updating page size to %d\n", page_length_); 1026b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1027b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Revert to default page length. 1028b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(6, "Process Error: " 1029b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "Invalid page size %d\n", page_length_); 1030b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_length_ = kSatPageSize; 1031b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 1032b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1033b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1034b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set disk_pages_ if filesize or page size changed. 1035b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (filesize != static_cast<uint64>(page_length_) * 1036b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<uint64>(disk_pages_)) { 1037b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_pages_ = filesize / page_length_; 1038b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (disk_pages_ == 0) 1039b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_pages_ = 1; 1040b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1041b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1042241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Validate memory channel parameters if supplied 1043241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (channels_.size()) { 1044241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (channels_.size() == 1) { 1045241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channel_hash_ = 0; 1046241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(7, "Log: " 1047241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "Only one memory channel...deactivating interleave decoding.\n"); 1048241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } else if (channels_.size() > 2) { 1049241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(6, "Process Error: " 1050241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "Triple-channel mode not yet supported... sorry.\n"); 1051241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 1052241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 1053241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1054241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders for (uint i = 0; i < channels_.size(); i++) 1055241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (channels_[i].size() != channels_[0].size()) { 1056241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(6, "Process Error: " 1057241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "Channels 0 and %d have a different count of dram modules.\n", i); 1058241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 1059241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 1060241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1061241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (channels_[0].size() & (channels_[0].size() - 1)) { 1062241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(6, "Process Error: " 1063241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "Amount of modules per memory channel is not a power of 2.\n"); 1064241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 1065241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 1066241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1067241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (channel_width_ < 16 1068241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders || channel_width_ & (channel_width_ - 1)) { 1069241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(6, "Process Error: " 1070241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "Channel width %d is invalid.\n", channel_width_); 1071241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 1072241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 1073241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1074241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (channel_width_ / channels_[0].size() < 8) { 1075241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(6, "Process Error: Chip width x%d must be x8 or greater.\n", 1076241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders channel_width_ / channels_[0].size()); 1077241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bad_status(); 1078241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return false; 1079241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1080241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1081241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 1082241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 1083b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Print each argument. 1084b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < argc; i++) { 1085b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i) 1086b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cmdline_ += " "; 1087b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cmdline_ += argv[i]; 1088b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1089b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1090b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 1091b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1092b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1093b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::PrintHelp() { 1094b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("Usage: ./sat(32|64) [options]\n" 1095b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -M mbytes megabytes of ram to test\n" 1096241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --reserve-memory If not using hugepages, the amount of memory to " 1097241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " reserve for the system\n" 1098b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -H mbytes minimum megabytes of hugepages to require\n" 1099b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -s seconds number of seconds to run\n" 1100b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -m threads number of memory copy threads to run\n" 1101b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -i threads number of memory invert threads to run\n" 1102b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -C threads number of memory CPU stress threads to run\n" 1103b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --findfiles find locations to do disk IO automatically\n" 1104b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -d device add a direct write disk thread with block " 1105b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "device (or file) 'device'\n" 1106b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -f filename add a disk thread with " 1107b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "tempfile 'filename'\n" 1108b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -l logfile log output to file 'logfile'\n" 1109241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --no_timestamps do not prefix timestamps to log messages\n" 1110b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --max_errors n exit early after finding 'n' errors\n" 1111b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -v level verbosity (0-20), default is 8\n" 1112241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --printsec secs How often to print 'seconds remaining'\n" 1113b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -W Use more CPU-stressful memory copy\n" 1114b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -A run in degraded mode on incompatible systems\n" 1115b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -p pagesize size in bytes of memory chunks\n" 1116b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --filesize size size of disk IO tempfiles\n" 1117b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -n ipaddr add a network thread connecting to " 1118b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "system at 'ipaddr'\n" 1119b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --listen run a thread to listen for and respond " 1120b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "to network threads.\n" 1121b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --no_errors run without checking for ECC or other errors\n" 1122b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --force_errors inject false errors to test error handling\n" 1123b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --force_errors_like_crazy inject a lot of false errors " 1124b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "to test error handling\n" 1125b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -F don't result check each transaction\n" 1126b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --stop_on_errors Stop after finding the first error.\n" 1127b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --read-block-size size of block for reading (-d)\n" 1128b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --write-block-size size of block for writing (-d). If not " 1129b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "defined, the size of block for writing will be defined as the " 1130b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "size of block for reading\n" 1131b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --segment-size size of segments to split disk into (-d)\n" 1132b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cache-size size of disk cache (-d)\n" 1133b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --blocks-per-segment number of blocks to read/write per " 1134b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "segment per iteration (-d)\n" 1135b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --read-threshold maximum time (in us) a block read should " 1136b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "take (-d)\n" 1137b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --write-threshold maximum time (in us) a block write " 1138b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "should take (-d)\n" 1139b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --random-threads number of random threads for each disk " 1140b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "write thread (-d)\n" 1141b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --destructive write/wipe disk partition (-d)\n" 1142b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --monitor_mode only do ECC error polling, no stress load.\n" 1143b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cc_test do the cache coherency testing\n" 1144b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cc_inc_count number of times to increment the " 1145b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "cacheline's member\n" 1146b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cc_line_count number of cache line sized datastructures " 1147b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "to allocate for the cache coherency threads to operate\n" 1148241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --cc_line_size override the auto-detected cache line size\n" 1149241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --cpu_freq_test enable the cpu frequency test (requires the " 1150241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "--cpu_freq_threshold argument to be set)\n" 1151241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --cpu_freq_threshold fail the cpu frequency test if the frequency " 1152241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "goes below this value (specified in MHz)\n" 1153241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --cpu_freq_round round the computed frequency to this value, if set" 1154241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " to zero, only round to the nearest MHz\n" 1155b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --paddr_base allocate memory starting from this address\n" 1156b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --pause_delay delay (in seconds) between power spikes\n" 1157b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --pause_duration duration (in seconds) of each pause\n" 1158241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --local_numa choose memory regions associated with " 1159b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "each CPU to be tested by that CPU\n" 1160241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --remote_numa choose memory regions not associated with " 1161241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "each CPU to be tested by that CPU\n" 1162241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --channel_hash mask of address bits XORed to determine channel. " 1163241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "Mask 0x40 interleaves cachelines between channels\n" 1164241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --channel_width bits width in bits of each memory channel\n" 1165241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders " --memory_channel u1,u2 defines a comma-separated list of names " 1166241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "for dram packages in a memory channel. Use multiple times to " 1167241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders "define multiple channels.\n"); 1168b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1169b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1170b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::CheckGoogleSpecificArgs(int argc, char **argv, int *i) { 1171b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do nothing, no google-specific argument on public stressapptest 1172b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 1173b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1174b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1175b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::GoogleOsOptions(std::map<std::string, std::string> *options) { 1176b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do nothing, no OS-specific argument on public stressapptest 1177b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1178b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1179b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Launch the SAT task threads. Returns 0 on error. 1180b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::InitializeThreads() { 1181b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Memory copy threads. 1182b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1183b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1184b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting worker threads\n"); 1185b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *memory_vector = new WorkerVector(); 1186b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1187b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Error polling thread. 1188b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This may detect ECC corrected errors, disk problems, or 1189b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // any other errors normally hidden from userspace. 1190b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *error_vector = new WorkerVector(); 1191b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (error_poll_) { 1192b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ErrorPollThread *thread = new ErrorPollThread(); 1193b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1194b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1195b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1196b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_vector->insert(error_vector->end(), thread); 1197b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1198b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Skipping error poll thread due to --no_errors flag\n"); 1199b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1200b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kErrorType, error_vector)); 1201b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1202b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Only start error poll threads for monitor-mode SAT, 1203b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // skip all other types of worker threads. 1204b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (monitor_mode_) { 1205b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1206b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 1207b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1208b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1209b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < memory_threads_; i++) { 1210b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CopyThread *thread = new CopyThread(); 1211b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1212b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1213b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1214b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((region_count_ > 1) && (region_mode_)) { 1215b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int32 region = region_find(i % region_count_); 1216b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t *cpuset = os_->FindCoreMask(region); 1217b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(cpuset); 1218b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (region_mode_ == kLocalNuma) { 1219b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Choose regions associated with this CPU. 1220b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask(cpuset); 1221b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_tag(1 << region); 1222b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (region_mode_ == kRemoteNuma) { 1223b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Choose regions not associated with this CPU.. 1224b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask(cpuset); 1225b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_tag(region_mask_ & ~(1 << region)); 1226b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1227b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1228b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t available_cpus; 1229b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->AvailableCpus(&available_cpus); 1230b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cores = cpuset_count(&available_cpus); 1231b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Don't restrict thread location if we have more than one 1232b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // thread per core. Not so good for performance. 1233b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cpu_stress_threads_ + memory_threads_ <= cores) { 1234b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Place a thread on alternating cores first. 1235b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This assures interleaved core use with no overlap. 1236b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int nthcore = i; 1237b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int nthbit = (((2 * nthcore) % cores) + 1238b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (((2 * nthcore) / cores) % 2)) % cores; 1239b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t all_cores; 1240b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_set_ab(&all_cores, 0, cores); 1241b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!cpuset_isequal(&available_cpus, &all_cores)) { 1242b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We are assuming the bits are contiguous. 1243b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Complain if this is not so. 1244b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: cores = %s, expected %s\n", 1245b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&available_cpus).c_str(), 1246b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&all_cores).c_str()); 1247b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1248b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1249b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set thread affinity. 1250b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask_to_cpu(nthbit); 1251b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1252b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1253b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memory_vector->insert(memory_vector->end(), thread); 1254b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1255b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kMemoryType, memory_vector)); 1256b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1257b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // File IO threads. 1258b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *fileio_vector = new WorkerVector(); 1259b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < file_threads_; i++) { 1260b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FileThread *thread = new FileThread(); 1261b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1262b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1263b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetFile(filename_[i].c_str()); 1264b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set disk threads high priority. They don't take much processor time, 1265b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // but blocking them will delay disk IO. 1266b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetPriority(WorkerThread::High); 1267b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1268b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fileio_vector->insert(fileio_vector->end(), thread); 1269b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1270b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kFileIOType, fileio_vector)); 1271b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1272b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Net IO threads. 1273b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *netio_vector = new WorkerVector(); 1274b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *netslave_vector = new WorkerVector(); 1275b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (listen_threads_ > 0) { 1276b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Create a network slave thread. This listens for connections. 1277b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkListenThread *thread = new NetworkListenThread(); 1278b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1279b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1280b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1281b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson netslave_vector->insert(netslave_vector->end(), thread); 1282b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1283b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < net_threads_; i++) { 1284b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkThread *thread = new NetworkThread(); 1285b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1286b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1287b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetIP(ipaddrs_[i].c_str()); 1288b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1289b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson netio_vector->insert(netio_vector->end(), thread); 1290b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1291b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kNetIOType, netio_vector)); 1292b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kNetSlaveType, netslave_vector)); 1293b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1294b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Result check threads. 1295b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *check_vector = new WorkerVector(); 1296b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < check_threads_; i++) { 1297b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckThread *thread = new CheckThread(); 1298b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1299b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1300b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1301b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_vector->insert(check_vector->end(), thread); 1302b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1303b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kCheckType, check_vector)); 1304b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1305b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Memory invert threads. 1306b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting invert threads\n"); 1307b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *invert_vector = new WorkerVector(); 1308b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < invert_threads_; i++) { 1309b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InvertThread *thread = new InvertThread(); 1310b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1311b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1312b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1313b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_vector->insert(invert_vector->end(), thread); 1314b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1315b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kInvertType, invert_vector)); 1316b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1317b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Disk stress threads. 1318b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *disk_vector = new WorkerVector(); 1319b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *random_vector = new WorkerVector(); 1320b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting disk stress threads\n"); 1321b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < disk_threads_; i++) { 1322b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Creating write threads 1323b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DiskThread *thread = new DiskThread(blocktables_[i]); 1324b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1325b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1326b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetDevice(diskfilename_[i].c_str()); 1327b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (thread->SetParameters(read_block_size_, write_block_size_, 1328b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson segment_size_, cache_size_, 1329b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_per_segment_, 1330b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_threshold_, write_threshold_, 1331b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson non_destructive_)) { 1332b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_vector->insert(disk_vector->end(), thread); 1333b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1334b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: DiskThread::SetParameters() failed\n"); 1335b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete thread; 1336b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1337b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1338b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int j = 0; j < random_threads_; j++) { 1339b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Creating random threads 1340b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson RandomDiskThread *rthread = new RandomDiskThread(blocktables_[i]); 1341b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson rthread->InitThread(total_threads_++, this, os_, patternlist_, 1342b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1343b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson rthread->SetDevice(diskfilename_[i].c_str()); 1344b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (rthread->SetParameters(read_block_size_, write_block_size_, 1345b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson segment_size_, cache_size_, 1346b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_per_segment_, 1347b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_threshold_, write_threshold_, 1348b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson non_destructive_)) { 1349b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson random_vector->insert(random_vector->end(), rthread); 1350b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1351b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: RandomDiskThread::SetParameters() failed\n"); 1352b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete rthread; 1353b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1354b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1355b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1356b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1357b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kDiskType, disk_vector)); 1358b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kRandomDiskType, random_vector)); 1359b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1360b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // CPU stress threads. 1361b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *cpu_vector = new WorkerVector(); 1362b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting cpu stress threads\n"); 1363b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < cpu_stress_threads_; i++) { 1364b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuStressThread *thread = new CpuStressThread(); 1365b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1366b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1367b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1368b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Don't restrict thread location if we have more than one 1369b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // thread per core. Not so good for performance. 1370b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t available_cpus; 1371b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->AvailableCpus(&available_cpus); 1372b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cores = cpuset_count(&available_cpus); 1373b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cpu_stress_threads_ + memory_threads_ <= cores) { 1374b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Place a thread on alternating cores first. 1375b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Go in reverse order for CPU stress threads. This assures interleaved 1376b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // core use with no overlap. 1377b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int nthcore = (cores - 1) - i; 1378b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int nthbit = (((2 * nthcore) % cores) + 1379b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (((2 * nthcore) / cores) % 2)) % cores; 1380b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t all_cores; 1381b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_set_ab(&all_cores, 0, cores); 1382b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!cpuset_isequal(&available_cpus, &all_cores)) { 1383b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: cores = %s, expected %s\n", 1384b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&available_cpus).c_str(), 1385b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&all_cores).c_str()); 1386b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1387b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1388b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set thread affinity. 1389b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask_to_cpu(nthbit); 1390b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1391b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1392b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1393b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_vector->insert(cpu_vector->end(), thread); 1394b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1395b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kCPUType, cpu_vector)); 1396b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1397b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // CPU Cache Coherency Threads - one for each core available. 1398b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cc_test_) { 1399b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *cc_vector = new WorkerVector(); 1400b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting cpu cache coherency threads\n"); 1401b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1402b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate the shared datastructure to be worked on by the threads. 1403b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data_ = reinterpret_cast<cc_cacheline_data*>( 1404b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson malloc(sizeof(cc_cacheline_data) * cc_cacheline_count_)); 1405b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(cc_cacheline_data_ != NULL); 1406b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1407b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize the strucutre. 1408b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memset(cc_cacheline_data_, 0, 1409b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sizeof(cc_cacheline_data) * cc_cacheline_count_); 1410b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1411b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int num_cpus = CpuCount(); 1412241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders char *num; 1413241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Calculate the number of cache lines needed just to give each core 1414241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // its own counter. 1415241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int line_size = cc_cacheline_size_; 1416241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (line_size <= 0) { 1417241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders line_size = CacheLineSize(); 1418241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (line_size < kCacheLineSize) 1419241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders line_size = kCacheLineSize; 1420241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(12, "Log: Using %d as cache line size\n", line_size); 1421241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1422241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // The number of cache lines needed to hold an array of num_cpus. 1423241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // "num" must be the same type as cc_cacheline_data[X].num or the memory 1424241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // size calculations will fail. 1425241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int needed_lines = (sizeof(*num) * num_cpus + line_size - 1) / line_size; 1426b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate all the nums once so that we get a single chunk 1427b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // of contiguous memory. 14288f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#ifdef HAVE_POSIX_MEMALIGN 1429b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int err_result = posix_memalign( 1430b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reinterpret_cast<void**>(&num), 1431241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders line_size, line_size * needed_lines * cc_cacheline_count_); 14328f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#else 1433241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders num = reinterpret_cast<char*>(memalign( 1434241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders line_size, line_size * needed_lines * cc_cacheline_count_)); 14358f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson int err_result = (num == 0); 14368f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 1437b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(err_result == 0); 1438b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1439b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cline; 1440b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (cline = 0; cline < cc_cacheline_count_; cline++) { 1441241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders memset(num, 0, sizeof(*num) * num_cpus); 1442b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data_[cline].num = num; 1443241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders num += (line_size * needed_lines) / sizeof(*num); 1444b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1445b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1446b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int tnum; 1447b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (tnum = 0; tnum < num_cpus; tnum++) { 1448b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuCacheCoherencyThread *thread = 1449b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson new CpuCacheCoherencyThread(cc_cacheline_data_, cc_cacheline_count_, 1450241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders tnum, num_cpus, cc_inc_count_); 1451b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1452b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1453b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Pin the thread to a particular core. 1454b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask_to_cpu(tnum); 1455b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1456b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Insert the thread into the vector. 1457b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_vector->insert(cc_vector->end(), thread); 1458b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1459b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kCCType, cc_vector)); 1460b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1461241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 1462241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (cpu_freq_test_) { 1463241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Create the frequency test thread. 1464241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders logprintf(5, "Log: Running cpu frequency test: threshold set to %dMHz.\n", 1465241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders cpu_freq_threshold_); 1466241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders CpuFreqThread *thread = new CpuFreqThread(CpuCount(), cpu_freq_threshold_, 1467241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders cpu_freq_round_); 1468241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // This thread should be paused when other threads are paused. 1469241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders thread->InitThread(total_threads_++, this, os_, NULL, 1470241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders &power_spike_status_); 1471241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 1472241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders WorkerVector *cpu_freq_vector = new WorkerVector(); 1473241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders cpu_freq_vector->insert(cpu_freq_vector->end(), thread); 1474241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders workers_map_.insert(make_pair(kCPUFreqType, cpu_freq_vector)); 1475241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 1476241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 1477b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1478b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1479b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1480b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Return the number of cpus actually present in the machine. 1481b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonint Sat::CpuCount() { 1482b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return sysconf(_SC_NPROCESSORS_CONF); 1483b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1484b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1485241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders// Return the worst case (largest) cache line size of the various levels of 1486241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders// cache actually prsent in the machine. 1487241f33a3e958842e3db803c03300764bd2ee9c19Nick Sandersint Sat::CacheLineSize() { 1488241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int max_linesize = sysconf(_SC_LEVEL1_DCACHE_LINESIZE); 1489241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int linesize = sysconf(_SC_LEVEL2_CACHE_LINESIZE); 1490241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (linesize > max_linesize) max_linesize = linesize; 1491241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders linesize = sysconf(_SC_LEVEL3_CACHE_LINESIZE); 1492241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (linesize > max_linesize) max_linesize = linesize; 1493241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders linesize = sysconf(_SC_LEVEL4_CACHE_LINESIZE); 1494241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders if (linesize > max_linesize) max_linesize = linesize; 1495241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return max_linesize; 1496241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders} 1497241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 1498b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Notify and reap worker threads. 1499b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::JoinThreads() { 1500b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Joining worker threads\n"); 1501b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.StopWorkers(); 1502b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continuous_status_.StopWorkers(); 1503b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1504b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1505b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1506b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1507b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1508b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1509b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Joining thread %d\n", (*it)->ThreadID()); 1510b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->JoinThread(); 1511b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1512b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1513b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1514b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1515b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson QueueStats(); 1516b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1517b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Finish up result checking. 1518b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn 4 check threads to minimize check time. 1519b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Finished countdown, begin to result check\n"); 1520b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus reap_check_status; 1521b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector reap_check_vector; 1522b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1523b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // No need for check threads for monitor mode. 1524b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!monitor_mode_) { 1525b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize the check threads. 1526b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < fill_threads_; i++) { 1527b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckThread *thread = new CheckThread(); 1528b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1529b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &reap_check_status); 1530b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Finished countdown, begin to result check\n"); 1531b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_vector.push_back(thread); 1532b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1533b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1534b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1535b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_status.Initialize(); 1536b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Check threads should be marked to stop ASAP. 1537b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_status.StopWorkers(); 1538b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1539b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn the check threads. 1540b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = reap_check_vector.begin(); 1541b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != reap_check_vector.end(); ++it) { 1542b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Spawning thread %d\n", (*it)->ThreadID()); 1543b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->SpawnThread(); 1544b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1545b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1546b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Join the check threads. 1547b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = reap_check_vector.begin(); 1548b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != reap_check_vector.end(); ++it) { 1549b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Joining thread %d\n", (*it)->ThreadID()); 1550b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->JoinThread(); 1551b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1552b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1553b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Reap all children. Stopped threads should have already ended. 1554b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Result checking threads will end when they have finished 1555b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // result checking. 1556b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Join all outstanding threads\n"); 1557b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1558b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Find all errors. 1559b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_ = GetTotalErrorCount(); 1560b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1561b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1562b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1563b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1564b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1565b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1566b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Reaping thread status %d\n", (*it)->ThreadID()); 1567b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetStatus() != 1) { 1568b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Thread %d failed with status %d at " 1569b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "%.2f seconds\n", 1570b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetStatus(), 1571b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->GetRunDurationUSec()*1.0/1000000); 1572b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 1573b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1574b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority = 12; 1575b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetErrorCount()) 1576b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson priority = 5; 1577b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(priority, "Log: Thread %d found %lld hardware incidents\n", 1578b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetErrorCount()); 1579b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1580b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1581b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1582b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1583b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1584b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Add in any errors from check threads. 1585b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = reap_check_vector.begin(); 1586b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != reap_check_vector.end(); ++it) { 1587b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Reaping thread status %d\n", (*it)->ThreadID()); 1588b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetStatus() != 1) { 1589b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Thread %d failed with status %d at " 1590b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "%.2f seconds\n", 1591b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetStatus(), 1592b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->GetRunDurationUSec()*1.0/1000000); 1593b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 1594b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1595b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_ += (*it)->GetErrorCount(); 1596b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority = 12; 1597b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetErrorCount()) 1598b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson priority = 5; 1599b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(priority, "Log: Thread %d found %lld hardware incidents\n", 1600b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetErrorCount()); 1601b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete (*it); 1602b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1603b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_vector.clear(); 1604b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_status.Destroy(); 1605b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1606b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1607b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Print queuing information. 1608b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::QueueStats() { 1609b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_->QueueAnalysis(); 1610b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1611b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1612b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AnalysisAllStats() { 1613b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float max_runtime_sec = 0.; 1614b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float total_data = 0.; 1615b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float total_bandwidth = 0.; 1616b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float thread_runtime_sec = 0.; 1617b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1618b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1619b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1620b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1621b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1622241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders thread_runtime_sec = (*it)->GetRunDurationUSec()*1.0/1000000.; 1623b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_data += (*it)->GetMemoryCopiedData(); 1624b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_data += (*it)->GetDeviceCopiedData(); 1625b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (thread_runtime_sec > max_runtime_sec) { 1626b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson max_runtime_sec = thread_runtime_sec; 1627b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1628b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1629b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1630b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1631b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_bandwidth = total_data / max_runtime_sec; 1632b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1633b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Stats: Completed: %.2fM in %.2fs %.2fMB/s, " 1634b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with %d hardware incidents, %d errors\n", 1635b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_data, 1636b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson max_runtime_sec, 1637b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_bandwidth, 1638b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_, 1639b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson statuscount_); 1640b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1641b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1642b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::MemoryStats() { 1643b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float memcopy_data = 0.; 1644b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float memcopy_bandwidth = 0.; 1645b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator mem_it = workers_map_.find( 1646b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kMemoryType)); 1647b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator file_it = workers_map_.find( 1648b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kFileIOType)); 1649b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(mem_it != workers_map_.end()); 1650b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(file_it != workers_map_.end()); 1651b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = mem_it->second->begin(); 1652b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != mem_it->second->end(); ++it) { 1653b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_data += (*it)->GetMemoryCopiedData(); 1654b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_bandwidth += (*it)->GetMemoryBandwidth(); 1655b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1656b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = file_it->second->begin(); 1657b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != file_it->second->end(); ++it) { 1658b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_data += (*it)->GetMemoryCopiedData(); 1659b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_bandwidth += (*it)->GetMemoryBandwidth(); 1660b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1661b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson GoogleMemoryStats(&memcopy_data, &memcopy_bandwidth); 1662b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Memory Copy: %.2fM at %.2fMB/s\n", 1663b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_data, 1664b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_bandwidth); 1665b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1666b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1667b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::GoogleMemoryStats(float *memcopy_data, 1668b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float *memcopy_bandwidth) { 1669b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do nothing, should be implemented by subclasses. 1670b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1671b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1672b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::FileStats() { 1673b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float file_data = 0.; 1674b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float file_bandwidth = 0.; 1675b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator file_it = workers_map_.find( 1676b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kFileIOType)); 1677b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(file_it != workers_map_.end()); 1678b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = file_it->second->begin(); 1679b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != file_it->second->end(); ++it) { 1680b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_data += (*it)->GetDeviceCopiedData(); 1681b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_bandwidth += (*it)->GetDeviceBandwidth(); 1682b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1683b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: File Copy: %.2fM at %.2fMB/s\n", 1684b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_data, 1685b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_bandwidth); 1686b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1687b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1688b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::CheckStats() { 1689b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float check_data = 0.; 1690b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float check_bandwidth = 0.; 1691b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator check_it = workers_map_.find( 1692b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kCheckType)); 1693b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(check_it != workers_map_.end()); 1694b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = check_it->second->begin(); 1695b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != check_it->second->end(); ++it) { 1696b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_data += (*it)->GetMemoryCopiedData(); 1697b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_bandwidth += (*it)->GetMemoryBandwidth(); 1698b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1699b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Data Check: %.2fM at %.2fMB/s\n", 1700b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_data, 1701b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_bandwidth); 1702b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1703b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1704b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::NetStats() { 1705b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float net_data = 0.; 1706b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float net_bandwidth = 0.; 1707b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator netio_it = workers_map_.find( 1708b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kNetIOType)); 1709b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator netslave_it = workers_map_.find( 1710b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kNetSlaveType)); 1711b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(netio_it != workers_map_.end()); 1712b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(netslave_it != workers_map_.end()); 1713b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = netio_it->second->begin(); 1714b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != netio_it->second->end(); ++it) { 1715b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_data += (*it)->GetDeviceCopiedData(); 1716b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_bandwidth += (*it)->GetDeviceBandwidth(); 1717b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1718b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = netslave_it->second->begin(); 1719b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != netslave_it->second->end(); ++it) { 1720b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_data += (*it)->GetDeviceCopiedData(); 1721b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_bandwidth += (*it)->GetDeviceBandwidth(); 1722b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1723b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Net Copy: %.2fM at %.2fMB/s\n", 1724b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_data, 1725b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_bandwidth); 1726b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1727b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1728b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::InvertStats() { 1729b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float invert_data = 0.; 1730b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float invert_bandwidth = 0.; 1731b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator invert_it = workers_map_.find( 1732b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kInvertType)); 1733b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(invert_it != workers_map_.end()); 1734b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = invert_it->second->begin(); 1735b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != invert_it->second->end(); ++it) { 1736b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_data += (*it)->GetMemoryCopiedData(); 1737b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_bandwidth += (*it)->GetMemoryBandwidth(); 1738b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1739b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Invert Data: %.2fM at %.2fMB/s\n", 1740b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_data, 1741b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_bandwidth); 1742b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1743b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1744b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::DiskStats() { 1745b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float disk_data = 0.; 1746b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float disk_bandwidth = 0.; 1747b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator disk_it = workers_map_.find( 1748b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kDiskType)); 1749b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator random_it = workers_map_.find( 1750b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kRandomDiskType)); 1751b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(disk_it != workers_map_.end()); 1752b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(random_it != workers_map_.end()); 1753b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = disk_it->second->begin(); 1754b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != disk_it->second->end(); ++it) { 1755b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_data += (*it)->GetDeviceCopiedData(); 1756b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_bandwidth += (*it)->GetDeviceBandwidth(); 1757b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1758b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = random_it->second->begin(); 1759b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != random_it->second->end(); ++it) { 1760b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_data += (*it)->GetDeviceCopiedData(); 1761b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_bandwidth += (*it)->GetDeviceBandwidth(); 1762b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1763b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1764b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Disk: %.2fM at %.2fMB/s\n", 1765b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_data, 1766b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_bandwidth); 1767b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1768b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1769b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Process worker thread data for bandwidth information, and error results. 1770b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// You can add more methods here just subclassing SAT. 1771b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::RunAnalysis() { 1772b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AnalysisAllStats(); 1773b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson MemoryStats(); 1774b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FileStats(); 1775b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetStats(); 1776b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckStats(); 1777b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InvertStats(); 1778b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DiskStats(); 1779b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1780b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1781b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Get total error count, summing across all threads.. 1782b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonint64 Sat::GetTotalErrorCount() { 1783b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 errors = 0; 1784b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1785b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1786b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1787b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1788b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1789b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1790b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errors += (*it)->GetErrorCount(); 1791b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1792b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1793b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1794b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return errors; 1795b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1796b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1797b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1798b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::SpawnThreads() { 1799b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Initializing WorkerStatus objects\n"); 1800b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.Initialize(); 1801b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continuous_status_.Initialize(); 1802b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Spawning worker threads\n"); 1803b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1804b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1805b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1806b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1807b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Spawning thread %d\n", (*it)->ThreadID()); 1808b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->SpawnThread(); 1809b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1810b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1811b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1812b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1813b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Delete used worker thread objects. 1814b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::DeleteThreads() { 1815b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Deleting worker threads\n"); 1816b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1817b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1818b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1819b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1820b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Deleting thread %d\n", (*it)->ThreadID()); 1821b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete (*it); 1822b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1823b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete map_it->second; 1824b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1825b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.clear(); 1826b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Destroying WorkerStatus objects\n"); 1827b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.Destroy(); 1828b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continuous_status_.Destroy(); 1829b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1830b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1831b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonnamespace { 1832b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Calculates the next time an action in Sat::Run() should occur, based on a 1833b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// schedule derived from a start point and a regular frequency. 1834b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 1835b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Using frequencies instead of intervals with their accompanying drift allows 1836b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// users to better predict when the actions will occur throughout a run. 1837b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 1838b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Arguments: 1839b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// frequency: seconds 1840b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// start: unixtime 1841b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// now: unixtime 1842b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 1843b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Returns: unixtime 1844b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersoninline time_t NextOccurance(time_t frequency, time_t start, time_t now) { 1845b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return start + frequency + (((now - start) / frequency) * frequency); 1846b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1847b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1848b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1849b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Run the actual test. 1850b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::Run() { 1851b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Install signal handlers to gracefully exit in the middle of a run. 1852b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1853b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Why go through this whole rigmarole? It's the only standards-compliant 1854b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // (C++ and POSIX) way to handle signals in a multithreaded program. 1855b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specifically: 1856b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1857b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1) (C++) The value of a variable not of type "volatile sig_atomic_t" is 1858b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // unspecified upon entering a signal handler and, if modified by the 1859b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // handler, is unspecified after leaving the handler. 1860b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1861b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 2) (POSIX) After the value of a variable is changed in one thread, another 1862b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // thread is only guaranteed to see the new value after both threads have 1863b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // acquired or released the same mutex or rwlock, synchronized to the 1864b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // same barrier, or similar. 1865b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1866b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // #1 prevents the use of #2 in a signal handler, so the signal handler must 1867b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // be called in the same thread that reads the "volatile sig_atomic_t" 1868b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // variable it sets. We enforce that by blocking the signals in question in 1869b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // the worker threads, forcing them to be handled by this thread. 1870b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Installing signal handlers\n"); 1871b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigset_t new_blocked_signals; 1872b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigemptyset(&new_blocked_signals); 1873b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigaddset(&new_blocked_signals, SIGINT); 1874b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigaddset(&new_blocked_signals, SIGTERM); 1875b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigset_t prev_blocked_signals; 1876b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_sigmask(SIG_BLOCK, &new_blocked_signals, &prev_blocked_signals); 1877b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sighandler_t prev_sigint_handler = signal(SIGINT, SatHandleBreak); 1878b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sighandler_t prev_sigterm_handler = signal(SIGTERM, SatHandleBreak); 1879b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1880b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Kick off all the worker threads. 1881b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Launching worker threads\n"); 1882b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InitializeThreads(); 1883b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson SpawnThreads(); 1884b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_sigmask(SIG_SETMASK, &prev_blocked_signals, NULL); 1885b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1886b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting countdown with %d seconds\n", runtime_seconds_); 1887b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1888b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // In seconds. 1889b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const time_t kSleepFrequency = 5; 1890b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // All of these are in seconds. You probably want them to be >= 1891b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // kSleepFrequency and multiples of kSleepFrequency, but neither is necessary. 1892b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const time_t kInjectionFrequency = 10; 1893241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // print_delay_ determines "seconds remaining" chatty update. 1894b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1895b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const time_t start = time(NULL); 1896b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const time_t end = start + runtime_seconds_; 1897b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t now = start; 1898241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders time_t next_print = start + print_delay_; 1899b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t next_pause = start + pause_delay_; 1900b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t next_resume = 0; 1901b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t next_injection; 1902b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (crazy_error_injection_) { 1903b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_injection = start + kInjectionFrequency; 1904b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1905b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_injection = 0; 1906b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1907b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1908b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson while (now < end) { 1909b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is an int because it's for logprintf(). 1910b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const int seconds_remaining = end - now; 1911b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1912b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (user_break_) { 1913b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Handle early exit. 1914b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: User exiting early (%d seconds remaining)\n", 1915b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson seconds_remaining); 1916b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson break; 1917b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1918b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1919b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // If we have an error limit, check it here and see if we should exit. 1920b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (max_errorcount_ != 0) { 1921b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 errors = GetTotalErrorCount(); 1922b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (errors > max_errorcount_) { 1923b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: Exiting early (%d seconds remaining) " 1924b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "due to excessive failures (%lld)\n", 1925b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson seconds_remaining, 1926b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errors); 1927b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson break; 1928b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1929b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1930b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1931b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (now >= next_print) { 1932b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Print a count down message. 1933b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Seconds remaining: %d\n", seconds_remaining); 1934241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders next_print = NextOccurance(print_delay_, start, now); 1935b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1936b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1937b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (next_injection && now >= next_injection) { 1938b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Inject an error. 1939b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Injecting error (%d seconds remaining)\n", 1940b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson seconds_remaining); 1941b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry src; 1942b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson GetValid(&src); 1943b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson src.pattern = patternlist_->GetPattern(0); 1944b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PutValid(&src); 1945b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_injection = NextOccurance(kInjectionFrequency, start, now); 1946b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1947b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1948b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (next_pause && now >= next_pause) { 1949b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tell worker threads to pause in preparation for a power spike. 1950b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Pausing worker threads in preparation for power spike " 1951b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "(%d seconds remaining)\n", seconds_remaining); 1952b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.PauseWorkers(); 1953b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Worker threads paused\n"); 1954b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_pause = 0; 1955b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_resume = now + pause_duration_; 1956b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1957b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1958b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (next_resume && now >= next_resume) { 1959b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tell worker threads to resume in order to cause a power spike. 1960b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Resuming worker threads to cause a power spike (%d " 1961b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "seconds remaining)\n", seconds_remaining); 1962b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.ResumeWorkers(); 1963b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Worker threads resumed\n"); 1964b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_pause = NextOccurance(pause_delay_, start, now); 1965b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_resume = 0; 1966b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1967b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1968b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_sleep(NextOccurance(kSleepFrequency, start, now) - now); 1969b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson now = time(NULL); 1970b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1971b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1972b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson JoinThreads(); 1973b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1974b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Stats: Found %lld hardware incidents\n", errorcount_); 1975b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1976b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!monitor_mode_) 1977b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson RunAnalysis(); 1978b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1979b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DeleteThreads(); 1980b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1981b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Uninstalling signal handlers\n"); 1982b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson signal(SIGINT, prev_sigint_handler); 1983b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson signal(SIGTERM, prev_sigterm_handler); 1984b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1985b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 1986b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1987b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1988b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Clean up all resources. 1989b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::Cleanup() { 1990b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson g_sat = NULL; 1991b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->StopThread(); 1992b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetStdoutOnly(); 1993b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (logfile_) { 1994b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson close(logfile_); 1995b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfile_ = 0; 1996b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1997b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (patternlist_) { 1998b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_->Destroy(); 1999b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete patternlist_; 2000b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_ = 0; 2001b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2002b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (os_) { 2003b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->FreeTestMem(); 2004b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete os_; 2005b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_ = 0; 2006b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2007b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (empty_) { 2008b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete empty_; 2009b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson empty_ = 0; 2010b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2011b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (valid_) { 2012b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete valid_; 2013b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_ = 0; 2014b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2015b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (finelock_q_) { 2016b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete finelock_q_; 2017b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_ = 0; 2018b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2019b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (page_bitmap_) { 2020b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete[] page_bitmap_; 2021b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2022b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2023b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (size_t i = 0; i < blocktables_.size(); i++) { 2024b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete blocktables_[i]; 2025b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2026b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2027b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cc_cacheline_data_) { 2028b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // The num integer arrays for all the cacheline structures are 2029b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // allocated as a single chunk. The pointers in the cacheline struct 2030b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // are populated accordingly. Hence calling free on the first 2031b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // cacheline's num's address is going to free the entire array. 2032b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // TODO(aganti): Refactor this to have a class for the cacheline 2033b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // structure (currently defined in worker.h) and clean this up 2034b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // in the destructor of that class. 2035b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cc_cacheline_data_[0].num) { 2036b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson free(cc_cacheline_data_[0].num); 2037b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2038b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson free(cc_cacheline_data_); 2039b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2040b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2041b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_destroy(&worker_lock_)); 2042b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2043b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 2044b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 2045b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2046b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2047b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Pretty print really obvious results. 2048b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PrintResults() { 2049b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = true; 2050b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2051b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "\n"); 2052b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (statuscount_) { 2053b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Status: FAIL - test encountered procedural errors\n"); 2054b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = false; 2055b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (errorcount_) { 2056b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Status: FAIL - test discovered HW problems\n"); 2057b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = false; 2058b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 2059b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Status: PASS - please verify no corrected errors\n"); 2060b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 2061b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "\n"); 2062b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2063b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return result; 2064b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 2065b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2066b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Helper functions. 2067b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AcquireWorkerLock() { 2068b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_lock(&worker_lock_)); 2069b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 2070b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::ReleaseWorkerLock() { 2071b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_unlock(&worker_lock_)); 2072b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 2073b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 2074b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid logprintf(int priority, const char *format, ...) { 2075b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson va_list args; 2076b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson va_start(args, format); 2077b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->VLogF(priority, format, args); 2078b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson va_end(args); 2079b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 2080241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 2081241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders// Stop the logging thread and verify any pending data is written to the log. 2082241f33a3e958842e3db803c03300764bd2ee9c19Nick Sandersvoid logstop() { 2083241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders Logger::GlobalLogger()->StopThread(); 2084241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders} 2085241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 2086