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