sat.cc revision b0114cb9f332db144f65291211ae65f7f0e814e6
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_, 80b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson O_WRONLY | O_CREAT | O_DSYNC, 81b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 82b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (logfile_ < 0) { 83b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("Fatal Error: cannot open file %s for logging\n", 84b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfilename_); 85b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 86b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 87b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 88b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We seek to the end once instead of opening in append mode because no 89b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // other processes should be writing to it while this one exists. 90b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (lseek(logfile_, 0, SEEK_END) == -1) { 91b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("Fatal Error: cannot seek to end of logfile (%s)\n", 92b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfilename_); 93b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 94b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 95b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 96b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetLogFd(logfile_); 97b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 98b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 99b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 100b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 101b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Check that the environment is known and safe to run on. 102b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Return 1 if good, 0 if unsuppported. 103b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::CheckEnvironment() { 104b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Check that this is not a debug build. Debug builds lack 105b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // enough performance to stress the system. 106b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#if !defined NDEBUG 107b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (run_on_anything_) { 108b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Log: Running DEBUG version of SAT, " 109b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with significantly reduced coverage.\n"); 110b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 111b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Running DEBUG version of SAT, " 112b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with significantly reduced coverage.\n"); 113b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: Command line option '-A' bypasses this error.\n"); 114b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 115b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 116b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 117b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#elif !defined CHECKOPTS 118b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson #error Build system regression - COPTS disregarded. 119b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#endif 120b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 121b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Use all CPUs if nothing is specified. 122b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (memory_threads_ == -1) { 123b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memory_threads_ = os_->num_cpus(); 124b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(7, "Log: Defaulting to %d copy threads\n", memory_threads_); 125b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 126b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 127b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Use all memory if no size is specified. 128b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (size_mb_ == 0) 129b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_ = os_->FindFreeMemSize() / kMegabyte; 130b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = static_cast<int64>(size_mb_) * kMegabyte; 131b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 132b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Autodetect file locations. 133b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (findfiles_ && (file_threads_ == 0)) { 134b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get a space separated sting of disk locations. 135b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson list<string> locations = os_->FindFileDevices(); 136b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 137b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Extract each one. 138b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson while (!locations.empty()) { 139b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Copy and remove the disk name. 140b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string disk = locations.back(); 141b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson locations.pop_back(); 142b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 143b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: disk at %s\n", disk.c_str()); 144b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_++; 145b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson filename_.push_back(disk + "/sat_disk.a"); 146b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_++; 147b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson filename_.push_back(disk + "/sat_disk.b"); 148b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 149b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 150b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 151b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We'd better have some memory by this point. 152b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (size_ < 1) { 153b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: No memory found to test.\n"); 154b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 155b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 156b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 157b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 158b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (tag_mode_ && ((file_threads_ > 0) || 159b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (disk_threads_ > 0) || 160b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (net_threads_ > 0))) { 161b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Memory tag mode incompatible " 162b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with disk/network DMA.\n"); 163b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 164b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 165b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 166b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 167b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // If platform is 32 bit Xeon, floor memory size to multiple of 4. 168b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (address_mode_ == 32) { 169b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_ = (size_mb_ / 4) * 4; 170b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = size_mb_ * kMegabyte; 171b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Log: Flooring memory allocation to multiple of 4: %lldMB\n", 172b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_); 173b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 174b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 175b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Check if this system is on the whitelist for supported systems. 176b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!os_->IsSupported()) { 177b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (run_on_anything_) { 178b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Log: Unsupported system. Running with reduced coverage.\n"); 179b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is ok, continue on. 180b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 181b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Unsupported system, " 182b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "no error reporting available\n"); 183b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: Command line option '-A' bypasses this error.\n"); 184b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 185b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 186b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 187b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 188b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 189b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 190b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 191b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 192b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Allocates memory to run the test on 193b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::AllocateMemory() { 194b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate our test memory. 195b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = os_->AllocateTestMem(size_, paddr_base_); 196b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!result) { 197b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: failed to allocate memory\n"); 198b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 199b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 200b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 201b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 202b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 203b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 204b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Sets up access to data patterns 205b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::InitializePatterns() { 206b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize pattern data. 207b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_ = new PatternList(); 208b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!patternlist_) { 209b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: failed to allocate patterns\n"); 210b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 211b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 212b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 213b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!patternlist_->Initialize()) { 214b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: failed to initialize patternlist\n"); 215b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 216b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 217b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 218b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 219b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 220b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 221b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Get any valid page, no tag specified. 222b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetValid(struct page_entry *pe) { 223b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return GetValid(pe, kDontCareTag); 224b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 225b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 226b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 227b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Fetch and return empty and full pages into the empty and full pools. 228b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetValid(struct page_entry *pe, int32 tag) { 229b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = false; 230b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get valid page depending on implementation. 231b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 232b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = finelock_q_->GetValid(pe, tag); 233b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 234b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = valid_->PopRandom(pe); 235b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 236b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (result) { 237b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = os_->PrepareTestMem(pe->offset, page_length_); // Map it. 238b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 239b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tag this access and current pattern. 240b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->ts = os_->GetTimestamp(); 241b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->lastpattern = pe->pattern; 242b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 243b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return (pe->addr != 0); // Return success or failure. 244b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 245b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 246b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 247b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 248b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PutValid(struct page_entry *pe) { 249b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe->addr != 0) 250b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->ReleaseTestMem(pe->addr, pe->offset, page_length_); // Unmap the page. 251b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = 0; 252b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 253b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Put valid page depending on implementation. 254b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 255b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return finelock_q_->PutValid(pe); 256b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 257b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return valid_->Push(pe); 258b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else 259b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 260b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 261b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 262b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Get an empty page with any tag. 263b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetEmpty(struct page_entry *pe) { 264b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return GetEmpty(pe, kDontCareTag); 265b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 266b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 267b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::GetEmpty(struct page_entry *pe, int32 tag) { 268b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = false; 269b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get empty page depending on implementation. 270b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 271b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = finelock_q_->GetEmpty(pe, tag); 272b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 273b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = empty_->PopRandom(pe); 274b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 275b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (result) { 276b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = os_->PrepareTestMem(pe->offset, page_length_); // Map it. 277b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return (pe->addr != 0); // Return success or failure. 278b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 279b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 280b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 281b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 282b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PutEmpty(struct page_entry *pe) { 283b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe->addr != 0) 284b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->ReleaseTestMem(pe->addr, pe->offset, page_length_); // Unmap the page. 285b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe->addr = 0; 286b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 287b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Put empty page depending on implementation. 288b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 289b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return finelock_q_->PutEmpty(pe); 290b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else if (pe_q_implementation_ == SAT_ONELOCK) 291b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return empty_->Push(pe); 292b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else 293b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 294b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 295b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 296b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Set up the bitmap of physical pages in case we want to see which pages were 297b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// accessed under this run of SAT. 298b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AddrMapInit() { 299b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!do_page_map_) 300b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 301b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Find about how much physical mem is in the system. 302b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // TODO(nsanders): Find some way to get the max 303b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // and min phys addr in the system. 304b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 maxsize = os_->FindFreeMemSize() * 4; 305b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(maxsize != 0); 306b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 307b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Make a bitmask of this many pages. Assume that the memory is relatively 308b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // zero based. This is true on x86, typically. 309b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is one bit per page. 310b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 arraysize = maxsize / 4096 / 8; 311b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned char *bitmap = new unsigned char[arraysize]; 312b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(bitmap); 313b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 314b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Mark every page as 0, not seen. 315b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memset(bitmap, 0, arraysize); 316b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 317b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_size_ = maxsize; 318b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_ = bitmap; 319b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 320b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 321b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Add the 4k pages in this block to the array of pages SAT has seen. 322b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AddrMapUpdate(struct page_entry *pe) { 323b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!do_page_map_) 324b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 325b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 326b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Go through 4k page blocks. 327b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 arraysize = page_bitmap_size_ / 4096 / 8; 328b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 329b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char *base = reinterpret_cast<char*>(pe->addr); 330b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < page_length_; i += 4096) { 331b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 paddr = os_->VirtualToPhysical(base + i); 332b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 333b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint32 offset = paddr / 4096 / 8; 334b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned char mask = 1 << ((paddr / 4096) % 8); 335b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 336b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (offset >= arraysize) { 337b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Physical address %#llx is " 338b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "greater than expected %#llx.\n", 339b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson paddr, page_bitmap_size_); 340b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0); 341b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 342b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_[offset] |= mask; 343b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 344b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 345b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 346b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Print out the physical memory ranges that SAT has accessed. 347b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AddrMapPrint() { 348b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!do_page_map_) 349b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 350b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 351b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 pages = page_bitmap_size_ / 4096; 352b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 353b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 last_page = 0; 354b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool valid_range = false; 355b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 356b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Printing tested physical ranges.\n"); 357b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 358b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (uint64 i = 0; i < pages; i ++) { 359b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int offset = i / 8; 360b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned char mask = 1 << (i % 8); 361b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 362b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool touched = page_bitmap_[offset] & mask; 363b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (touched && !valid_range) { 364b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_range = true; 365b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson last_page = i * 4096; 366b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (!touched && valid_range) { 367b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_range = false; 368b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: %#016llx - %#016llx\n", last_page, (i * 4096) - 1); 369b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 370b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 371b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Done printing physical ranges.\n"); 372b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 373b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 374b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Initializes page lists and fills pages with data patterns. 375b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::InitializePages() { 376b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int result = 1; 377b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate needed page totals. 378b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 neededpages = memory_threads_ + 379b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_threads_ + 380b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_threads_ + 381b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_threads_ + 382b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_; 383b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 384b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Empty-valid page ratio is adjusted depending on queue implementation. 385b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // since fine-grain-locked queue keeps both valid and empty entries in the 386b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // same queue and randomly traverse to find pages, the empty-valid ratio 387b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // should be more even. 388b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) 389b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_ = pages_ / 5 * 2; // Mark roughly 2/5 of all pages as Empty. 390b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson else 391b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_ = (pages_ / 100) + (2 * neededpages); 392b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 393b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (freepages_ < neededpages) { 394b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: freepages < neededpages.\n"); 395b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Stats: Total: %lld, Needed: %lld, Marked free: %lld\n", 396b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(pages_), 397b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(neededpages), 398b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(freepages_)); 399b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 400b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 401b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 402b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 403b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (freepages_ > pages_/2) { 404b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: not enough pages for IO\n"); 405b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Stats: Total: %lld, Needed: %lld, Available: %lld\n", 406b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(pages_), 407b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(freepages_), 408b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int64>(pages_/2)); 409b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 410b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 411b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 412b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Allocating pages, Total: %lld Free: %lld\n", 413b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_, 414b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_); 415b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 416b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize page locations. 417b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int64 i = 0; i < pages_; i++) { 418b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry pe; 419b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson init_pe(&pe); 420b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe.offset = i * page_length_; 421b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result &= PutEmpty(&pe); 422b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 423b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 424b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!result) { 425b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: while initializing empty_ list\n"); 426b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 427b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 428b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 429b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 430b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fill valid pages with test patterns. 431b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Use fill threads to do this. 432b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus fill_status; 433b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector fill_vector; 434b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 435b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Starting Fill threads: %d threads, %d pages\n", 436b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_threads_, pages_); 437b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize the fill threads. 438b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < fill_threads_; i++) { 439b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FillThread *thread = new FillThread(); 440b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(i, this, os_, patternlist_, &fill_status); 441b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i != fill_threads_ - 1) { 442b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Starting Fill Threads %d: %d pages\n", 443b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i, pages_ / fill_threads_); 444b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetFillPages(pages_ / fill_threads_); 445b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // The last thread finishes up all the leftover pages. 446b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 447b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Starting Fill Threads %d: %d pages\n", 448b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i, pages_ - pages_ / fill_threads_ * i); 449b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetFillPages(pages_ - pages_ / fill_threads_ * i); 450b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 451b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_vector.push_back(thread); 452b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 453b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 454b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn the fill threads. 455b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_status.Initialize(); 456b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = fill_vector.begin(); 457b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != fill_vector.end(); ++it) 458b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->SpawnThread(); 459b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 460b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Reap the finished fill threads. 461b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = fill_vector.begin(); 462b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != fill_vector.end(); ++it) { 463b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->JoinThread(); 464b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetStatus() != 1) { 465b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Thread %d failed with status %d at %.2f seconds\n", 466b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetStatus(), 467b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->GetRunDurationUSec() * 1.0/1000000); 468b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 469b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 470b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 471b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete (*it); 472b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 473b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_vector.clear(); 474b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_status.Destroy(); 475b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Done filling pages.\n"); 476b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Allocating pages.\n"); 477b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 478b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AddrMapInit(); 479b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 480b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize page locations. 481b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int64 i = 0; i < pages_; i++) { 482b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry pe; 483b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Only get valid pages with uninitialized tags here. 484b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char buf[256]; 485b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (GetValid(&pe, kInvalidTag)) { 486b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 paddr = os_->VirtualToPhysical(pe.addr); 487b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int32 region = os_->FindRegion(paddr); 488b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 489b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->FindDimm(paddr, buf, sizeof(buf)); 490b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < 256) { 491b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: address: %#llx, %s\n", paddr, buf); 492b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 493b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_[region]++; 494b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe.paddr = paddr; 495b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe.tag = 1 << region; 496b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_mask_ |= pe.tag; 497b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 498b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Generate a physical region map 499b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AddrMapUpdate(&pe); 500b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 501b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Note: this does not allocate free pages among all regions 502b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // fairly. However, with large enough (thousands) random number 503b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // of pages being marked free in each region, the free pages 504b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // count in each region end up pretty balanced. 505b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < freepages_) { 506b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result &= PutEmpty(&pe); 507b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 508b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result &= PutValid(&pe); 509b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 510b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 511b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: didn't tag all pages. %d - %d = %d\n", 512b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_, i, pages_ - i); 513b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 514b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 515b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 516b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Done allocating pages.\n"); 517b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 518b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AddrMapPrint(); 519b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 520b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < 32; i++) { 521b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (region_mask_ & (1 << i)) { 522b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_count_++; 523b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Region %d: %d.\n", i, region_[i]); 524b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 525b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 526b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Region mask: 0x%x\n", region_mask_); 527b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 528b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 529b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 530b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 531b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Print SAT version info. 532b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PrintVersion() { 533b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(1, "Stats: SAT revision %s, %d bit binary\n", 534b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson kVersion, address_mode_); 535b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: %s from %s\n", Timestamp(), BuildChangelist()); 536b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 537b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 538b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 539b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 540b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 541b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Initializes the resources that SAT needs to run. 542b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This needs to be called before Run(), and after ParseArgs(). 543b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Returns true on success, false on error, and will exit() on help message. 544b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::Initialize() { 545b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson g_sat = this; 546b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 547b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initializes sync'd log file to ensure output is saved. 548b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!InitializeLogfile()) 549b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 550b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->StartThread(); 551b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 552b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Commandline - %s\n", cmdline_.c_str()); 553b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PrintVersion(); 554b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 555b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson std::map<std::string, std::string> options; 556b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 557b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson GoogleOsOptions(&options); 558b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 559b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize OS/Hardware interface. 560b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_ = OsLayerFactory(options); 561b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!os_) { 562b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 563b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 564b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 565b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 566b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (min_hugepages_mbytes_ > 0) 567b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->SetMinimumHugepagesSize(min_hugepages_mbytes_ * kMegabyte); 568b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 569b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!os_->Initialize()) { 570b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Failed to initialize OS layer\n"); 571b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 572b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete os_; 573b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 574b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 575b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 576b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Checks that OS/Build/Platform is supported. 577b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!CheckEnvironment()) 578b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 579b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 580b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (error_injection_) 581b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->set_error_injection(true); 582b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 583b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run SAT in monitor only mode, do not continue to allocate resources. 584b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (monitor_mode_) { 585b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Running in monitor-only mode. " 586b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "Will not allocate any memory nor run any stress test. " 587b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "Only polling ECC errors.\n"); 588b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 589b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 590b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 591b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate the memory to test. 592b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!AllocateMemory()) 593b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 594b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 595b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Stats: Starting SAT, %dM, %d seconds\n", 596b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(size_/kMegabyte), 597b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runtime_seconds_); 598b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 599b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!InitializePatterns()) 600b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 601b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 602b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize memory allocation. 603b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_ = size_ / page_length_; 604b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 605b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate page queue depending on queue implementation switch. 606b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (pe_q_implementation_ == SAT_FINELOCK) { 607b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_ = new FineLockPEQueue(pages_, page_length_); 608b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (finelock_q_ == NULL) 609b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 610b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_->set_os(os_); 611b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->set_err_log_callback(finelock_q_->get_err_log_callback()); 612b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (pe_q_implementation_ == SAT_ONELOCK) { 613b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson empty_ = new PageEntryQueue(pages_); 614b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_ = new PageEntryQueue(pages_); 615b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((empty_ == NULL) || (valid_ == NULL)) 616b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 617b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 618b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 619b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!InitializePages()) { 620b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Initialize Pages failed\n"); 621b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 622b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 623b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 624b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 625b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 626b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 627b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Constructor and destructor. 628b0114cb9f332db144f65291211ae65f7f0e814e6Scott AndersonSat::Sat() { 629b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set defaults, command line might override these. 630b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runtime_seconds_ = 20; 631b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_length_ = kSatPageSize; 632b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_pages_ = kSatDiskPage; 633b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pages_ = 0; 634b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_mb_ = 0; 635b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = size_mb_ * kMegabyte; 636b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson min_hugepages_mbytes_ = 0; 637b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson freepages_ = 0; 638b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson paddr_base_ = 0; 639b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 640b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson user_break_ = false; 641b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson verbosity_ = 8; 642b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetVerbosity(verbosity_); 643b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson strict_ = 1; 644b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson warm_ = 0; 645b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson run_on_anything_ = 0; 646b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson use_logfile_ = 0; 647b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfile_ = 0; 648b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Detect 32/64 bit binary. 649b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *pvoid = 0; 650b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson address_mode_ = sizeof(pvoid) * 8; 651b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_injection_ = false; 652b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson crazy_error_injection_ = false; 653b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson max_errorcount_ = 0; // Zero means no early exit. 654b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson stop_on_error_ = false; 655b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_poll_ = true; 656b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson findfiles_ = false; 657b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 658b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson do_page_map_ = false; 659b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_ = 0; 660b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_bitmap_size_ = 0; 661b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 662b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Cache coherency data initialization. 663b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_test_ = false; // Flag to trigger cc threads. 664b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_count_ = 2; // Two datastructures of cache line size. 665b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_inc_count_ = 1000; // Number of times to increment the shared variable. 666b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data_ = 0; // Cache Line size datastructure. 667b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 668b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_init(&worker_lock_, NULL)); 669b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_ = 0; 670b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_threads_ = 0; 671b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson listen_threads_ = 0; 672b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Default to autodetect number of cpus, and run that many threads. 673b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memory_threads_ = -1; 674b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_threads_ = 0; 675b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fill_threads_ = 8; 676b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_threads_ = 0; 677b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_stress_threads_ = 0; 678b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_threads_ = 0; 679b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_threads_ = 0; 680b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 681b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_mask_ = 0; 682b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_count_ = 0; 683b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < 32; i++) { 684b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_[i] = 0; 685b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 686b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson region_mode_ = 0; 687b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 688b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_ = 0; 689b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson statuscount_ = 0; 690b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 691b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_ = 0; 692b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson empty_ = 0; 693b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_ = 0; 694b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Default to use fine-grain lock for better performance. 695b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pe_q_implementation_ = SAT_FINELOCK; 696b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 697b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_ = 0; 698b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_ = 0; 699b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfilename_[0] = 0; 700b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 701b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_block_size_ = 512; 702b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson write_block_size_ = -1; 703b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson segment_size_ = -1; 704b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cache_size_ = -1; 705b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_per_segment_ = -1; 706b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_threshold_ = -1; 707b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson write_threshold_ = -1; 708b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson non_destructive_ = 1; 709b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson monitor_mode_ = 0; 710b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson tag_mode_ = 0; 711b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson random_threads_ = 0; 712b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 713b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pause_delay_ = 600; 714b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pause_duration_ = 15; 715b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 716b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 717b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Destructor. 718b0114cb9f332db144f65291211ae65f7f0e814e6Scott AndersonSat::~Sat() { 719b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We need to have called Cleanup() at this point. 720b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We should probably enforce this. 721b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 722b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 723b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 724b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define ARG_KVALUE(argument, variable, value) \ 725b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], argument)) { \ 726b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson variable = value; \ 727b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; \ 728b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 729b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 730b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define ARG_IVALUE(argument, variable) \ 731b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], argument)) { \ 732b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; \ 733b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) \ 734b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson variable = strtoull(argv[i], NULL, 0); \ 735b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; \ 736b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 737b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 738b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define ARG_SVALUE(argument, variable) \ 739b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], argument)) { \ 740b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; \ 741b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) \ 742b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson snprintf(variable, sizeof(variable), "%s", argv[i]); \ 743b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; \ 744b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 745b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 746b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Configures SAT from command line arguments. 747b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This will call exit() given a request for 748b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// self-documentation or unexpected args. 749b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::ParseArgs(int argc, char **argv) { 750b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int i; 751b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 filesize = page_length_ * disk_pages_; 752b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 753b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Parse each argument. 754b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (i = 1; i < argc; i++) { 755b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Switch to fall back to corase-grain-lock queue. (for benchmarking) 756b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--coarse_grain_lock", pe_q_implementation_, SAT_ONELOCK); 757b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 758b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of megabyte to use. 759b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-M", size_mb_); 760b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 761b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set minimum megabytes of hugepages to require. 762b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-H", min_hugepages_mbytes_); 763b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 764b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of seconds to run. 765b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-s", runtime_seconds_); 766b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 767b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of memory copy threads. 768b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-m", memory_threads_); 769b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 770b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of memory invert threads. 771b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-i", invert_threads_); 772b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 773b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of check-only threads. 774b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-c", check_threads_); 775b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 776b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of cache line size datastructures. 777b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--cc_inc_count", cc_inc_count_); 778b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 779b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of cache line size datastructures 780b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--cc_line_count", cc_cacheline_count_); 781b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 782b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Flag set when cache coherency tests need to be run 783b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--cc_test", cc_test_, 1); 784b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 785b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of CPU stress threads. 786b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-C", cpu_stress_threads_); 787b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 788b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set logfile name. 789b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_SVALUE("-l", logfilename_); 790b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 791b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Verbosity level. 792b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-v", verbosity_); 793b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 794b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set maximum number of errors to collect. Stop running after this many. 795b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--max_errors", max_errorcount_); 796b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 797b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set pattern block size. 798b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("-p", page_length_); 799b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 800b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set pattern block size. 801b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--filesize", filesize); 802b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 803b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // NUMA options. 804b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--local_numa", region_mode_, kLocalNuma); 805b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--remote_numa", region_mode_, kRemoteNuma); 806b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 807b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Autodetect tempfile locations. 808b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--findfiles", findfiles_, 1); 809b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 810b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Inject errors to force miscompare code paths 811b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--force_errors", error_injection_, true); 812b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--force_errors_like_crazy", crazy_error_injection_, true); 813b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (crazy_error_injection_) 814b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_injection_ = true; 815b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 816b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Stop immediately on any arror, for debugging HW problems. 817b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--stop_on_errors", stop_on_error_, 1); 818b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 819b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Don't use internal error polling, allow external detection. 820b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--no_errors", error_poll_, 0); 821b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 822b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Never check data as you go. 823b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("-F", strict_, 0); 824b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 825b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Warm the cpu as you go. 826b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("-W", warm_, 1); 827b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 828b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allow runnign on unknown systems with base unimplemented OsLayer 829b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("-A", run_on_anything_, 1); 830b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 831b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of read blocks for disk test. 832b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--read-block-size", read_block_size_); 833b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 834b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of write blocks for disk test. 835b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--write-block-size", write_block_size_); 836b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 837b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of segment for disk test. 838b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--segment-size", segment_size_); 839b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 840b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Size of disk cache size for disk test. 841b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--cache-size", cache_size_); 842b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 843b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Number of blocks to test per segment. 844b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--blocks-per-segment", blocks_per_segment_); 845b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 846b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Maximum time a block read should take before warning. 847b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--read-threshold", read_threshold_); 848b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 849b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Maximum time a block write should take before warning. 850b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--write-threshold", write_threshold_); 851b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 852b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do not write anything to disk in the disk test. 853b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--destructive", non_destructive_, 0); 854b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 855b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run SAT in monitor mode. No test load at all. 856b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--monitor_mode", monitor_mode_, true); 857b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 858b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run SAT in address mode. Tag all cachelines by virt addr. 859b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--tag_mode", tag_mode_, true); 860b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 861b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Dump range map of tested pages.. 862b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--do_page_map", do_page_map_, true); 863b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 864b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specify the physical address base to test. 865b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--paddr_base", paddr_base_); 866b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 867b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specify the frequency for power spikes. 868b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--pause_delay", pause_delay_); 869b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 870b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specify the duration of each pause (for power spikes). 871b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--pause_duration", pause_duration_); 872b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 873b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Disk device names 874b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], "-d")) { 875b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; 876b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) { 877b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_threads_++; 878b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson diskfilename_.push_back(string(argv[i])); 879b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocktables_.push_back(new DiskBlockTable()); 880b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 881b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 882b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 883b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 884b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set number of disk random threads for each disk write thread. 885b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_IVALUE("--random-threads", random_threads_); 886b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 887b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set a tempfile to use in a file thread. 888b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], "-f")) { 889b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; 890b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) { 891b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_threads_++; 892b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson filename_.push_back(string(argv[i])); 893b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 894b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 895b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 896b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 897b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set a hostname to use in a network thread. 898b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!strcmp(argv[i], "-n")) { 899b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson i++; 900b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i < argc) { 901b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_threads_++; 902b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ipaddrs_.push_back(string(argv[i])); 903b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 904b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 905b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 906b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 907b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Run threads that listen for incoming SAT net connections. 908b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ARG_KVALUE("--listen", listen_threads_, 1); 909b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 910b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (CheckGoogleSpecificArgs(argc, argv, &i)) { 911b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continue; 912b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 913b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 914b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Default: 915b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PrintVersion(); 916b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PrintHelp(); 917b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (strcmp(argv[i], "-h") && strcmp(argv[i], "--help")) { 918b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("\n Unknown argument %s\n", argv[i]); 919b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 920b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson exit(1); 921b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 922b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Forget it, we printed the help, just bail. 923b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We don't want to print test status, or any log parser stuff. 924b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson exit(0); 925b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 926b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 927b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetVerbosity(verbosity_); 928b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 929b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Update relevant data members with parsed input. 930b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Translate MB into bytes. 931b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson size_ = static_cast<int64>(size_mb_) * kMegabyte; 932b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 933b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set logfile flag. 934b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (strcmp(logfilename_, "")) 935b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson use_logfile_ = 1; 936b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Checks valid page length. 937b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (page_length_ && 938b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson !(page_length_ & (page_length_ - 1)) && 939b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (page_length_ > 1023)) { 940b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Prints if we have changed from default. 941b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (page_length_ != kSatPageSize) 942b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Updating page size to %d\n", page_length_); 943b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 944b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Revert to default page length. 945b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(6, "Process Error: " 946b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "Invalid page size %d\n", page_length_); 947b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson page_length_ = kSatPageSize; 948b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 949b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 950b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 951b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set disk_pages_ if filesize or page size changed. 952b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (filesize != static_cast<uint64>(page_length_) * 953b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<uint64>(disk_pages_)) { 954b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_pages_ = filesize / page_length_; 955b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (disk_pages_ == 0) 956b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_pages_ = 1; 957b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 958b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 959b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Print each argument. 960b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < argc; i++) { 961b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (i) 962b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cmdline_ += " "; 963b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cmdline_ += argv[i]; 964b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 965b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 966b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 967b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 968b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 969b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::PrintHelp() { 970b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson printf("Usage: ./sat(32|64) [options]\n" 971b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -M mbytes megabytes of ram to test\n" 972b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -H mbytes minimum megabytes of hugepages to require\n" 973b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -s seconds number of seconds to run\n" 974b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -m threads number of memory copy threads to run\n" 975b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -i threads number of memory invert threads to run\n" 976b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -C threads number of memory CPU stress threads to run\n" 977b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --findfiles find locations to do disk IO automatically\n" 978b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -d device add a direct write disk thread with block " 979b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "device (or file) 'device'\n" 980b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -f filename add a disk thread with " 981b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "tempfile 'filename'\n" 982b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -l logfile log output to file 'logfile'\n" 983b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --max_errors n exit early after finding 'n' errors\n" 984b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -v level verbosity (0-20), default is 8\n" 985b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -W Use more CPU-stressful memory copy\n" 986b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -A run in degraded mode on incompatible systems\n" 987b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -p pagesize size in bytes of memory chunks\n" 988b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --filesize size size of disk IO tempfiles\n" 989b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -n ipaddr add a network thread connecting to " 990b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "system at 'ipaddr'\n" 991b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --listen run a thread to listen for and respond " 992b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "to network threads.\n" 993b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --no_errors run without checking for ECC or other errors\n" 994b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --force_errors inject false errors to test error handling\n" 995b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --force_errors_like_crazy inject a lot of false errors " 996b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "to test error handling\n" 997b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " -F don't result check each transaction\n" 998b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --stop_on_errors Stop after finding the first error.\n" 999b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --read-block-size size of block for reading (-d)\n" 1000b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --write-block-size size of block for writing (-d). If not " 1001b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "defined, the size of block for writing will be defined as the " 1002b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "size of block for reading\n" 1003b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --segment-size size of segments to split disk into (-d)\n" 1004b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cache-size size of disk cache (-d)\n" 1005b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --blocks-per-segment number of blocks to read/write per " 1006b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "segment per iteration (-d)\n" 1007b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --read-threshold maximum time (in us) a block read should " 1008b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "take (-d)\n" 1009b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --write-threshold maximum time (in us) a block write " 1010b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "should take (-d)\n" 1011b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --random-threads number of random threads for each disk " 1012b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "write thread (-d)\n" 1013b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --destructive write/wipe disk partition (-d)\n" 1014b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --monitor_mode only do ECC error polling, no stress load.\n" 1015b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cc_test do the cache coherency testing\n" 1016b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cc_inc_count number of times to increment the " 1017b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "cacheline's member\n" 1018b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --cc_line_count number of cache line sized datastructures " 1019b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "to allocate for the cache coherency threads to operate\n" 1020b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --paddr_base allocate memory starting from this address\n" 1021b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --pause_delay delay (in seconds) between power spikes\n" 1022b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --pause_duration duration (in seconds) of each pause\n" 1023b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --local_numa : choose memory regions associated with " 1024b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "each CPU to be tested by that CPU\n" 1025b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson " --remote_numa : choose memory regions not associated with " 1026b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "each CPU to be tested by that CPU\n"); 1027b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1028b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1029b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::CheckGoogleSpecificArgs(int argc, char **argv, int *i) { 1030b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do nothing, no google-specific argument on public stressapptest 1031b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return false; 1032b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1033b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1034b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::GoogleOsOptions(std::map<std::string, std::string> *options) { 1035b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do nothing, no OS-specific argument on public stressapptest 1036b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1037b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1038b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Launch the SAT task threads. Returns 0 on error. 1039b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::InitializeThreads() { 1040b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Memory copy threads. 1041b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1042b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1043b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting worker threads\n"); 1044b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *memory_vector = new WorkerVector(); 1045b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1046b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Error polling thread. 1047b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This may detect ECC corrected errors, disk problems, or 1048b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // any other errors normally hidden from userspace. 1049b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *error_vector = new WorkerVector(); 1050b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (error_poll_) { 1051b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ErrorPollThread *thread = new ErrorPollThread(); 1052b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1053b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1054b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1055b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson error_vector->insert(error_vector->end(), thread); 1056b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1057b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Skipping error poll thread due to --no_errors flag\n"); 1058b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1059b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kErrorType, error_vector)); 1060b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1061b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Only start error poll threads for monitor-mode SAT, 1062b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // skip all other types of worker threads. 1063b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (monitor_mode_) { 1064b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1065b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return; 1066b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1067b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1068b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < memory_threads_; i++) { 1069b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CopyThread *thread = new CopyThread(); 1070b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1071b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1072b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1073b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((region_count_ > 1) && (region_mode_)) { 1074b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int32 region = region_find(i % region_count_); 1075b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t *cpuset = os_->FindCoreMask(region); 1076b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(cpuset); 1077b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (region_mode_ == kLocalNuma) { 1078b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Choose regions associated with this CPU. 1079b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask(cpuset); 1080b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_tag(1 << region); 1081b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (region_mode_ == kRemoteNuma) { 1082b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Choose regions not associated with this CPU.. 1083b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask(cpuset); 1084b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_tag(region_mask_ & ~(1 << region)); 1085b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1086b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1087b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t available_cpus; 1088b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->AvailableCpus(&available_cpus); 1089b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cores = cpuset_count(&available_cpus); 1090b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Don't restrict thread location if we have more than one 1091b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // thread per core. Not so good for performance. 1092b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cpu_stress_threads_ + memory_threads_ <= cores) { 1093b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Place a thread on alternating cores first. 1094b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This assures interleaved core use with no overlap. 1095b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int nthcore = i; 1096b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int nthbit = (((2 * nthcore) % cores) + 1097b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (((2 * nthcore) / cores) % 2)) % cores; 1098b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t all_cores; 1099b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_set_ab(&all_cores, 0, cores); 1100b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!cpuset_isequal(&available_cpus, &all_cores)) { 1101b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // We are assuming the bits are contiguous. 1102b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Complain if this is not so. 1103b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: cores = %s, expected %s\n", 1104b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&available_cpus).c_str(), 1105b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&all_cores).c_str()); 1106b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1107b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1108b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set thread affinity. 1109b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask_to_cpu(nthbit); 1110b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1111b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1112b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memory_vector->insert(memory_vector->end(), thread); 1113b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1114b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kMemoryType, memory_vector)); 1115b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1116b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // File IO threads. 1117b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *fileio_vector = new WorkerVector(); 1118b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < file_threads_; i++) { 1119b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FileThread *thread = new FileThread(); 1120b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1121b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1122b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetFile(filename_[i].c_str()); 1123b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set disk threads high priority. They don't take much processor time, 1124b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // but blocking them will delay disk IO. 1125b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetPriority(WorkerThread::High); 1126b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1127b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson fileio_vector->insert(fileio_vector->end(), thread); 1128b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1129b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kFileIOType, fileio_vector)); 1130b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1131b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Net IO threads. 1132b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *netio_vector = new WorkerVector(); 1133b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *netslave_vector = new WorkerVector(); 1134b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (listen_threads_ > 0) { 1135b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Create a network slave thread. This listens for connections. 1136b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkListenThread *thread = new NetworkListenThread(); 1137b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1138b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1139b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1140b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson netslave_vector->insert(netslave_vector->end(), thread); 1141b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1142b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < net_threads_; i++) { 1143b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkThread *thread = new NetworkThread(); 1144b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1145b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1146b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetIP(ipaddrs_[i].c_str()); 1147b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1148b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson netio_vector->insert(netio_vector->end(), thread); 1149b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1150b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kNetIOType, netio_vector)); 1151b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kNetSlaveType, netslave_vector)); 1152b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1153b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Result check threads. 1154b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *check_vector = new WorkerVector(); 1155b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < check_threads_; i++) { 1156b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckThread *thread = new CheckThread(); 1157b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1158b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1159b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1160b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_vector->insert(check_vector->end(), thread); 1161b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1162b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kCheckType, check_vector)); 1163b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1164b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Memory invert threads. 1165b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting invert threads\n"); 1166b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *invert_vector = new WorkerVector(); 1167b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < invert_threads_; i++) { 1168b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InvertThread *thread = new InvertThread(); 1169b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1170b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1171b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1172b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_vector->insert(invert_vector->end(), thread); 1173b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1174b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kInvertType, invert_vector)); 1175b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1176b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Disk stress threads. 1177b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *disk_vector = new WorkerVector(); 1178b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *random_vector = new WorkerVector(); 1179b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting disk stress threads\n"); 1180b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < disk_threads_; i++) { 1181b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Creating write threads 1182b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DiskThread *thread = new DiskThread(blocktables_[i]); 1183b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1184b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1185b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->SetDevice(diskfilename_[i].c_str()); 1186b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (thread->SetParameters(read_block_size_, write_block_size_, 1187b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson segment_size_, cache_size_, 1188b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_per_segment_, 1189b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_threshold_, write_threshold_, 1190b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson non_destructive_)) { 1191b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_vector->insert(disk_vector->end(), thread); 1192b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1193b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: DiskThread::SetParameters() failed\n"); 1194b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete thread; 1195b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1196b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1197b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int j = 0; j < random_threads_; j++) { 1198b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Creating random threads 1199b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson RandomDiskThread *rthread = new RandomDiskThread(blocktables_[i]); 1200b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson rthread->InitThread(total_threads_++, this, os_, patternlist_, 1201b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &power_spike_status_); 1202b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson rthread->SetDevice(diskfilename_[i].c_str()); 1203b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (rthread->SetParameters(read_block_size_, write_block_size_, 1204b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson segment_size_, cache_size_, 1205b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_per_segment_, 1206b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson read_threshold_, write_threshold_, 1207b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson non_destructive_)) { 1208b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson random_vector->insert(random_vector->end(), rthread); 1209b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1210b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: RandomDiskThread::SetParameters() failed\n"); 1211b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete rthread; 1212b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1213b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1214b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1215b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1216b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kDiskType, disk_vector)); 1217b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kRandomDiskType, random_vector)); 1218b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1219b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // CPU stress threads. 1220b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *cpu_vector = new WorkerVector(); 1221b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting cpu stress threads\n"); 1222b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < cpu_stress_threads_; i++) { 1223b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuStressThread *thread = new CpuStressThread(); 1224b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1225b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1226b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1227b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Don't restrict thread location if we have more than one 1228b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // thread per core. Not so good for performance. 1229b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t available_cpus; 1230b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->AvailableCpus(&available_cpus); 1231b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cores = cpuset_count(&available_cpus); 1232b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cpu_stress_threads_ + memory_threads_ <= cores) { 1233b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Place a thread on alternating cores first. 1234b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Go in reverse order for CPU stress threads. This assures interleaved 1235b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // core use with no overlap. 1236b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int nthcore = (cores - 1) - 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 logprintf(0, "Log: cores = %s, expected %s\n", 1243b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&available_cpus).c_str(), 1244b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_format(&all_cores).c_str()); 1245b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1246b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1247b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set thread affinity. 1248b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask_to_cpu(nthbit); 1249b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1250b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1251b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1252b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_vector->insert(cpu_vector->end(), thread); 1253b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1254b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kCPUType, cpu_vector)); 1255b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1256b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // CPU Cache Coherency Threads - one for each core available. 1257b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cc_test_) { 1258b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector *cc_vector = new WorkerVector(); 1259b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting cpu cache coherency threads\n"); 1260b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1261b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate the shared datastructure to be worked on by the threads. 1262b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data_ = reinterpret_cast<cc_cacheline_data*>( 1263b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson malloc(sizeof(cc_cacheline_data) * cc_cacheline_count_)); 1264b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(cc_cacheline_data_ != NULL); 1265b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1266b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize the strucutre. 1267b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memset(cc_cacheline_data_, 0, 1268b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sizeof(cc_cacheline_data) * cc_cacheline_count_); 1269b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1270b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int num_cpus = CpuCount(); 1271b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allocate all the nums once so that we get a single chunk 1272b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // of contiguous memory. 1273b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int *num; 1274b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int err_result = posix_memalign( 1275b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reinterpret_cast<void**>(&num), 1276b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson kCacheLineSize, sizeof(*num) * num_cpus * cc_cacheline_count_); 1277b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(err_result == 0); 1278b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1279b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cline; 1280b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (cline = 0; cline < cc_cacheline_count_; cline++) { 1281b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memset(num, 0, sizeof(num_cpus) * num_cpus); 1282b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data_[cline].num = num; 1283b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson num += num_cpus; 1284b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1285b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1286b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int tnum; 1287b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (tnum = 0; tnum < num_cpus; tnum++) { 1288b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuCacheCoherencyThread *thread = 1289b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson new CpuCacheCoherencyThread(cc_cacheline_data_, cc_cacheline_count_, 1290b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson tnum, cc_inc_count_); 1291b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1292b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &continuous_status_); 1293b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Pin the thread to a particular core. 1294b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->set_cpu_mask_to_cpu(tnum); 1295b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1296b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Insert the thread into the vector. 1297b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_vector->insert(cc_vector->end(), thread); 1298b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1299b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.insert(make_pair(kCCType, cc_vector)); 1300b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1301b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1302b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1303b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1304b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Return the number of cpus actually present in the machine. 1305b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonint Sat::CpuCount() { 1306b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return sysconf(_SC_NPROCESSORS_CONF); 1307b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1308b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1309b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Notify and reap worker threads. 1310b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::JoinThreads() { 1311b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Joining worker threads\n"); 1312b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.StopWorkers(); 1313b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continuous_status_.StopWorkers(); 1314b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1315b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1316b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1317b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1318b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1319b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1320b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Joining thread %d\n", (*it)->ThreadID()); 1321b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->JoinThread(); 1322b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1323b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1324b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1325b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1326b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson QueueStats(); 1327b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1328b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Finish up result checking. 1329b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn 4 check threads to minimize check time. 1330b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Finished countdown, begin to result check\n"); 1331b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus reap_check_status; 1332b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerVector reap_check_vector; 1333b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1334b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // No need for check threads for monitor mode. 1335b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!monitor_mode_) { 1336b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize the check threads. 1337b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (int i = 0; i < fill_threads_; i++) { 1338b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckThread *thread = new CheckThread(); 1339b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread->InitThread(total_threads_++, this, os_, patternlist_, 1340b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson &reap_check_status); 1341b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Finished countdown, begin to result check\n"); 1342b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_vector.push_back(thread); 1343b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1344b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1345b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1346b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_status.Initialize(); 1347b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Check threads should be marked to stop ASAP. 1348b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_status.StopWorkers(); 1349b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1350b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn the check threads. 1351b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = reap_check_vector.begin(); 1352b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != reap_check_vector.end(); ++it) { 1353b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Spawning thread %d\n", (*it)->ThreadID()); 1354b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->SpawnThread(); 1355b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1356b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1357b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Join the check threads. 1358b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = reap_check_vector.begin(); 1359b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != reap_check_vector.end(); ++it) { 1360b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Joining thread %d\n", (*it)->ThreadID()); 1361b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->JoinThread(); 1362b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1363b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1364b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Reap all children. Stopped threads should have already ended. 1365b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Result checking threads will end when they have finished 1366b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // result checking. 1367b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Join all outstanding threads\n"); 1368b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1369b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Find all errors. 1370b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_ = GetTotalErrorCount(); 1371b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1372b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1373b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1374b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1375b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1376b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1377b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Reaping thread status %d\n", (*it)->ThreadID()); 1378b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetStatus() != 1) { 1379b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Thread %d failed with status %d at " 1380b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "%.2f seconds\n", 1381b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetStatus(), 1382b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->GetRunDurationUSec()*1.0/1000000); 1383b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 1384b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1385b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority = 12; 1386b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetErrorCount()) 1387b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson priority = 5; 1388b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(priority, "Log: Thread %d found %lld hardware incidents\n", 1389b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetErrorCount()); 1390b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1391b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1392b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1393b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1394b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1395b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Add in any errors from check threads. 1396b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = reap_check_vector.begin(); 1397b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != reap_check_vector.end(); ++it) { 1398b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Reaping thread status %d\n", (*it)->ThreadID()); 1399b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetStatus() != 1) { 1400b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Process Error: Thread %d failed with status %d at " 1401b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "%.2f seconds\n", 1402b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetStatus(), 1403b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->GetRunDurationUSec()*1.0/1000000); 1404b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bad_status(); 1405b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1406b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_ += (*it)->GetErrorCount(); 1407b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority = 12; 1408b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if ((*it)->GetErrorCount()) 1409b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson priority = 5; 1410b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(priority, "Log: Thread %d found %lld hardware incidents\n", 1411b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->ThreadID(), (*it)->GetErrorCount()); 1412b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete (*it); 1413b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1414b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_vector.clear(); 1415b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson reap_check_status.Destroy(); 1416b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1417b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1418b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Print queuing information. 1419b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::QueueStats() { 1420b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_->QueueAnalysis(); 1421b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1422b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1423b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AnalysisAllStats() { 1424b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float max_runtime_sec = 0.; 1425b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float total_data = 0.; 1426b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float total_bandwidth = 0.; 1427b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float thread_runtime_sec = 0.; 1428b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1429b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1430b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1431b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1432b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1433b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson thread_runtime_sec = (*it)->GetRunDurationUSec()*1.0/1000000; 1434b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_data += (*it)->GetMemoryCopiedData(); 1435b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_data += (*it)->GetDeviceCopiedData(); 1436b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (thread_runtime_sec > max_runtime_sec) { 1437b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson max_runtime_sec = thread_runtime_sec; 1438b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1439b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1440b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1441b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1442b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_bandwidth = total_data / max_runtime_sec; 1443b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1444b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Stats: Completed: %.2fM in %.2fs %.2fMB/s, " 1445b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "with %d hardware incidents, %d errors\n", 1446b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_data, 1447b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson max_runtime_sec, 1448b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson total_bandwidth, 1449b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errorcount_, 1450b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson statuscount_); 1451b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1452b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1453b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::MemoryStats() { 1454b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float memcopy_data = 0.; 1455b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float memcopy_bandwidth = 0.; 1456b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator mem_it = workers_map_.find( 1457b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kMemoryType)); 1458b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator file_it = workers_map_.find( 1459b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kFileIOType)); 1460b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(mem_it != workers_map_.end()); 1461b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(file_it != workers_map_.end()); 1462b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = mem_it->second->begin(); 1463b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != mem_it->second->end(); ++it) { 1464b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_data += (*it)->GetMemoryCopiedData(); 1465b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_bandwidth += (*it)->GetMemoryBandwidth(); 1466b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1467b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = file_it->second->begin(); 1468b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != file_it->second->end(); ++it) { 1469b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_data += (*it)->GetMemoryCopiedData(); 1470b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_bandwidth += (*it)->GetMemoryBandwidth(); 1471b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1472b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson GoogleMemoryStats(&memcopy_data, &memcopy_bandwidth); 1473b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Memory Copy: %.2fM at %.2fMB/s\n", 1474b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_data, 1475b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcopy_bandwidth); 1476b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1477b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1478b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::GoogleMemoryStats(float *memcopy_data, 1479b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float *memcopy_bandwidth) { 1480b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do nothing, should be implemented by subclasses. 1481b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1482b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1483b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::FileStats() { 1484b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float file_data = 0.; 1485b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float file_bandwidth = 0.; 1486b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator file_it = workers_map_.find( 1487b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kFileIOType)); 1488b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(file_it != workers_map_.end()); 1489b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = file_it->second->begin(); 1490b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != file_it->second->end(); ++it) { 1491b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_data += (*it)->GetDeviceCopiedData(); 1492b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_bandwidth += (*it)->GetDeviceBandwidth(); 1493b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1494b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: File Copy: %.2fM at %.2fMB/s\n", 1495b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_data, 1496b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson file_bandwidth); 1497b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1498b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1499b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::CheckStats() { 1500b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float check_data = 0.; 1501b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float check_bandwidth = 0.; 1502b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator check_it = workers_map_.find( 1503b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kCheckType)); 1504b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(check_it != workers_map_.end()); 1505b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = check_it->second->begin(); 1506b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != check_it->second->end(); ++it) { 1507b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_data += (*it)->GetMemoryCopiedData(); 1508b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_bandwidth += (*it)->GetMemoryBandwidth(); 1509b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1510b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Data Check: %.2fM at %.2fMB/s\n", 1511b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_data, 1512b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson check_bandwidth); 1513b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1514b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1515b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::NetStats() { 1516b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float net_data = 0.; 1517b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float net_bandwidth = 0.; 1518b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator netio_it = workers_map_.find( 1519b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kNetIOType)); 1520b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator netslave_it = workers_map_.find( 1521b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kNetSlaveType)); 1522b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(netio_it != workers_map_.end()); 1523b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(netslave_it != workers_map_.end()); 1524b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = netio_it->second->begin(); 1525b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != netio_it->second->end(); ++it) { 1526b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_data += (*it)->GetDeviceCopiedData(); 1527b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_bandwidth += (*it)->GetDeviceBandwidth(); 1528b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1529b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = netslave_it->second->begin(); 1530b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != netslave_it->second->end(); ++it) { 1531b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_data += (*it)->GetDeviceCopiedData(); 1532b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_bandwidth += (*it)->GetDeviceBandwidth(); 1533b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1534b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Net Copy: %.2fM at %.2fMB/s\n", 1535b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_data, 1536b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson net_bandwidth); 1537b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1538b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1539b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::InvertStats() { 1540b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float invert_data = 0.; 1541b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float invert_bandwidth = 0.; 1542b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator invert_it = workers_map_.find( 1543b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kInvertType)); 1544b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(invert_it != workers_map_.end()); 1545b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = invert_it->second->begin(); 1546b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != invert_it->second->end(); ++it) { 1547b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_data += (*it)->GetMemoryCopiedData(); 1548b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_bandwidth += (*it)->GetMemoryBandwidth(); 1549b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1550b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Invert Data: %.2fM at %.2fMB/s\n", 1551b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_data, 1552b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson invert_bandwidth); 1553b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1554b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1555b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::DiskStats() { 1556b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float disk_data = 0.; 1557b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson float disk_bandwidth = 0.; 1558b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator disk_it = workers_map_.find( 1559b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kDiskType)); 1560b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerMap::const_iterator random_it = workers_map_.find( 1561b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static_cast<int>(kRandomDiskType)); 1562b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(disk_it != workers_map_.end()); 1563b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(random_it != workers_map_.end()); 1564b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = disk_it->second->begin(); 1565b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != disk_it->second->end(); ++it) { 1566b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_data += (*it)->GetDeviceCopiedData(); 1567b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_bandwidth += (*it)->GetDeviceBandwidth(); 1568b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1569b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = random_it->second->begin(); 1570b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != random_it->second->end(); ++it) { 1571b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_data += (*it)->GetDeviceCopiedData(); 1572b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_bandwidth += (*it)->GetDeviceBandwidth(); 1573b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1574b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1575b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Stats: Disk: %.2fM at %.2fMB/s\n", 1576b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_data, 1577b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson disk_bandwidth); 1578b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1579b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1580b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Process worker thread data for bandwidth information, and error results. 1581b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// You can add more methods here just subclassing SAT. 1582b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::RunAnalysis() { 1583b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AnalysisAllStats(); 1584b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson MemoryStats(); 1585b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FileStats(); 1586b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetStats(); 1587b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckStats(); 1588b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InvertStats(); 1589b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DiskStats(); 1590b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1591b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1592b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Get total error count, summing across all threads.. 1593b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonint64 Sat::GetTotalErrorCount() { 1594b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 errors = 0; 1595b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1596b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireWorkerLock(); 1597b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1598b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1599b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1600b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1601b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errors += (*it)->GetErrorCount(); 1602b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1603b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1604b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseWorkerLock(); 1605b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return errors; 1606b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1607b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1608b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1609b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::SpawnThreads() { 1610b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Initializing WorkerStatus objects\n"); 1611b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.Initialize(); 1612b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continuous_status_.Initialize(); 1613b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Spawning worker threads\n"); 1614b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1615b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1616b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1617b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1618b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Spawning thread %d\n", (*it)->ThreadID()); 1619b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (*it)->SpawnThread(); 1620b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1621b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1622b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1623b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1624b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Delete used worker thread objects. 1625b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::DeleteThreads() { 1626b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Deleting worker threads\n"); 1627b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerMap::const_iterator map_it = workers_map_.begin(); 1628b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson map_it != workers_map_.end(); ++map_it) { 1629b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (WorkerVector::const_iterator it = map_it->second->begin(); 1630b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson it != map_it->second->end(); ++it) { 1631b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Deleting thread %d\n", (*it)->ThreadID()); 1632b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete (*it); 1633b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1634b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete map_it->second; 1635b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1636b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson workers_map_.clear(); 1637b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Destroying WorkerStatus objects\n"); 1638b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.Destroy(); 1639b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson continuous_status_.Destroy(); 1640b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1641b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1642b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonnamespace { 1643b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Calculates the next time an action in Sat::Run() should occur, based on a 1644b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// schedule derived from a start point and a regular frequency. 1645b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 1646b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Using frequencies instead of intervals with their accompanying drift allows 1647b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// users to better predict when the actions will occur throughout a run. 1648b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 1649b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Arguments: 1650b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// frequency: seconds 1651b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// start: unixtime 1652b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// now: unixtime 1653b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 1654b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Returns: unixtime 1655b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersoninline time_t NextOccurance(time_t frequency, time_t start, time_t now) { 1656b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return start + frequency + (((now - start) / frequency) * frequency); 1657b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1658b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1659b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1660b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Run the actual test. 1661b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::Run() { 1662b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Install signal handlers to gracefully exit in the middle of a run. 1663b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1664b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Why go through this whole rigmarole? It's the only standards-compliant 1665b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // (C++ and POSIX) way to handle signals in a multithreaded program. 1666b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Specifically: 1667b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1668b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1) (C++) The value of a variable not of type "volatile sig_atomic_t" is 1669b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // unspecified upon entering a signal handler and, if modified by the 1670b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // handler, is unspecified after leaving the handler. 1671b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1672b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 2) (POSIX) After the value of a variable is changed in one thread, another 1673b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // thread is only guaranteed to see the new value after both threads have 1674b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // acquired or released the same mutex or rwlock, synchronized to the 1675b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // same barrier, or similar. 1676b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 1677b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // #1 prevents the use of #2 in a signal handler, so the signal handler must 1678b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // be called in the same thread that reads the "volatile sig_atomic_t" 1679b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // variable it sets. We enforce that by blocking the signals in question in 1680b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // the worker threads, forcing them to be handled by this thread. 1681b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Installing signal handlers\n"); 1682b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigset_t new_blocked_signals; 1683b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigemptyset(&new_blocked_signals); 1684b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigaddset(&new_blocked_signals, SIGINT); 1685b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigaddset(&new_blocked_signals, SIGTERM); 1686b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sigset_t prev_blocked_signals; 1687b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_sigmask(SIG_BLOCK, &new_blocked_signals, &prev_blocked_signals); 1688b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sighandler_t prev_sigint_handler = signal(SIGINT, SatHandleBreak); 1689b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sighandler_t prev_sigterm_handler = signal(SIGTERM, SatHandleBreak); 1690b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1691b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Kick off all the worker threads. 1692b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Launching worker threads\n"); 1693b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InitializeThreads(); 1694b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson SpawnThreads(); 1695b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_sigmask(SIG_SETMASK, &prev_blocked_signals, NULL); 1696b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1697b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Starting countdown with %d seconds\n", runtime_seconds_); 1698b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1699b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // In seconds. 1700b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const time_t kSleepFrequency = 5; 1701b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // All of these are in seconds. You probably want them to be >= 1702b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // kSleepFrequency and multiples of kSleepFrequency, but neither is necessary. 1703b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const time_t kInjectionFrequency = 10; 1704b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const time_t kPrintFrequency = 10; 1705b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1706b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const time_t start = time(NULL); 1707b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const time_t end = start + runtime_seconds_; 1708b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t now = start; 1709b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t next_print = start + kPrintFrequency; 1710b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t next_pause = start + pause_delay_; 1711b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t next_resume = 0; 1712b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson time_t next_injection; 1713b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (crazy_error_injection_) { 1714b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_injection = start + kInjectionFrequency; 1715b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1716b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_injection = 0; 1717b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1718b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1719b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson while (now < end) { 1720b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is an int because it's for logprintf(). 1721b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const int seconds_remaining = end - now; 1722b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1723b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (user_break_) { 1724b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Handle early exit. 1725b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: User exiting early (%d seconds remaining)\n", 1726b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson seconds_remaining); 1727b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson break; 1728b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1729b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1730b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // If we have an error limit, check it here and see if we should exit. 1731b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (max_errorcount_ != 0) { 1732b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 errors = GetTotalErrorCount(); 1733b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (errors > max_errorcount_) { 1734b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Log: Exiting early (%d seconds remaining) " 1735b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "due to excessive failures (%lld)\n", 1736b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson seconds_remaining, 1737b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson errors); 1738b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson break; 1739b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1740b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1741b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1742b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (now >= next_print) { 1743b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Print a count down message. 1744b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(5, "Log: Seconds remaining: %d\n", seconds_remaining); 1745b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_print = NextOccurance(kPrintFrequency, start, now); 1746b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1747b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1748b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (next_injection && now >= next_injection) { 1749b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Inject an error. 1750b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Injecting error (%d seconds remaining)\n", 1751b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson seconds_remaining); 1752b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry src; 1753b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson GetValid(&src); 1754b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson src.pattern = patternlist_->GetPattern(0); 1755b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PutValid(&src); 1756b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_injection = NextOccurance(kInjectionFrequency, start, now); 1757b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1758b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1759b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (next_pause && now >= next_pause) { 1760b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tell worker threads to pause in preparation for a power spike. 1761b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Pausing worker threads in preparation for power spike " 1762b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "(%d seconds remaining)\n", seconds_remaining); 1763b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.PauseWorkers(); 1764b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Worker threads paused\n"); 1765b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_pause = 0; 1766b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_resume = now + pause_duration_; 1767b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1768b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1769b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (next_resume && now >= next_resume) { 1770b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tell worker threads to resume in order to cause a power spike. 1771b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Log: Resuming worker threads to cause a power spike (%d " 1772b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson "seconds remaining)\n", seconds_remaining); 1773b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson power_spike_status_.ResumeWorkers(); 1774b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Worker threads resumed\n"); 1775b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_pause = NextOccurance(pause_delay_, start, now); 1776b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson next_resume = 0; 1777b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1778b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1779b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_sleep(NextOccurance(kSleepFrequency, start, now) - now); 1780b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson now = time(NULL); 1781b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1782b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1783b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson JoinThreads(); 1784b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1785b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(0, "Stats: Found %lld hardware incidents\n", errorcount_); 1786b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1787b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (!monitor_mode_) 1788b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson RunAnalysis(); 1789b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1790b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DeleteThreads(); 1791b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1792b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(12, "Log: Uninstalling signal handlers\n"); 1793b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson signal(SIGINT, prev_sigint_handler); 1794b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson signal(SIGTERM, prev_sigterm_handler); 1795b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1796b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 1797b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1798b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1799b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Clean up all resources. 1800b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::Cleanup() { 1801b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson g_sat = NULL; 1802b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->StopThread(); 1803b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->SetStdoutOnly(); 1804b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (logfile_) { 1805b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson close(logfile_); 1806b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logfile_ = 0; 1807b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1808b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (patternlist_) { 1809b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_->Destroy(); 1810b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete patternlist_; 1811b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson patternlist_ = 0; 1812b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1813b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (os_) { 1814b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_->FreeTestMem(); 1815b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete os_; 1816b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson os_ = 0; 1817b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1818b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (empty_) { 1819b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete empty_; 1820b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson empty_ = 0; 1821b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1822b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (valid_) { 1823b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete valid_; 1824b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson valid_ = 0; 1825b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1826b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (finelock_q_) { 1827b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete finelock_q_; 1828b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson finelock_q_ = 0; 1829b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1830b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (page_bitmap_) { 1831b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete[] page_bitmap_; 1832b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1833b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1834b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson for (size_t i = 0; i < blocktables_.size(); i++) { 1835b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson delete blocktables_[i]; 1836b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1837b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1838b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cc_cacheline_data_) { 1839b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // The num integer arrays for all the cacheline structures are 1840b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // allocated as a single chunk. The pointers in the cacheline struct 1841b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // are populated accordingly. Hence calling free on the first 1842b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // cacheline's num's address is going to free the entire array. 1843b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // TODO(aganti): Refactor this to have a class for the cacheline 1844b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // structure (currently defined in worker.h) and clean this up 1845b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // in the destructor of that class. 1846b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (cc_cacheline_data_[0].num) { 1847b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson free(cc_cacheline_data_[0].num); 1848b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1849b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson free(cc_cacheline_data_); 1850b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1851b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1852b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_destroy(&worker_lock_)); 1853b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1854b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return true; 1855b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1856b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1857b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1858b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Pretty print really obvious results. 1859b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonbool Sat::PrintResults() { 1860b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool result = true; 1861b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1862b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "\n"); 1863b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (statuscount_) { 1864b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Status: FAIL - test encountered procedural errors\n"); 1865b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = false; 1866b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else if (errorcount_) { 1867b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Status: FAIL - test discovered HW problems\n"); 1868b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson result = false; 1869b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } else { 1870b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "Status: PASS - please verify no corrected errors\n"); 1871b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 1872b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson logprintf(4, "\n"); 1873b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1874b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return result; 1875b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1876b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1877b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Helper functions. 1878b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::AcquireWorkerLock() { 1879b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_lock(&worker_lock_)); 1880b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1881b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid Sat::ReleaseWorkerLock() { 1882b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_unlock(&worker_lock_)); 1883b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1884b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1885b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonvoid logprintf(int priority, const char *format, ...) { 1886b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson va_list args; 1887b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson va_start(args, format); 1888b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Logger::GlobalLogger()->VLogF(priority, format, args); 1889b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson va_end(args); 1890b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson} 1891