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// worker.h : worker thread interface 16b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 17b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This file contains the Worker Thread class interface 18b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// for the SAT test. Worker Threads implement a repetative 19b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// task used to test or stress the system. 20b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 21b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#ifndef STRESSAPPTEST_WORKER_H_ 22b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define STRESSAPPTEST_WORKER_H_ 23b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 24b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <pthread.h> 25b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 26b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <sys/time.h> 27b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <sys/types.h> 28b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 298f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#ifdef HAVE_LIBAIO_H 30b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <libaio.h> 318f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 32b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 33b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <queue> 34b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <set> 35b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <string> 36b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <vector> 37b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 38b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This file must work with autoconf on its public version, 39b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// so these includes are correct. 40b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "disk_blocks.h" 41b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "queue.h" 42b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "sattypes.h" 43b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 44b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 45b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Global Datastruture shared by the Cache Coherency Worker Threads. 46b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonstruct cc_cacheline_data { 47241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders char *num; 48b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 49b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 50b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Typical usage: 51b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// (Other workflows may be possible, see function comments for details.) 52b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread creates object. 53b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread calls AddWorkers(1) for each worker thread. 54b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread calls Initialize(). 55b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread launches worker threads. 56b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Every worker thread frequently calls ContinueRunning(). 57b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread periodically calls PauseWorkers(), effectively sleeps, and 58b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// then calls ResumeWorkers(). 59b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Some worker threads may exit early, before StopWorkers() is called. They 60b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// call RemoveSelf() after their last call to ContinueRunning(). 61b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread eventually calls StopWorkers(). 62b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Worker threads exit. 63b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread joins worker threads. 64b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread calls Destroy(). 65b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - Control thread destroys object. 66b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 67b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Threadsafety: 68b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - ContinueRunning() may be called concurrently by different workers, but not 69b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// by a single worker. 70b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - No other methods may ever be called concurrently, with themselves or 71b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// eachother. 72b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// - This object may be used by multiple threads only between Initialize() and 73b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Destroy(). 74b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 75b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// TODO(matthewb): Move this class and its unittest to their own files. 76b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass WorkerStatus { 77b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 78b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson //-------------------------------- 79b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Methods for the control thread. 80b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson //-------------------------------- 81b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 82b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus() : num_workers_(0), status_(RUN) {} 83b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 84b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by the control thread to increase the worker count. Must be called 85b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // before Initialize(). The worker count is 0 upon object initialization. 86b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void AddWorkers(int num_new_workers) { 87b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // No need to lock num_workers_mutex_ because this is before Initialize(). 88b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson num_workers_ += num_new_workers; 89b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 90b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 91b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by the control thread. May not be called multiple times. If 92b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // called, Destroy() must be called before destruction. 93b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void Initialize(); 94b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 95b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by the control thread after joining all worker threads. Must be 96b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // called iff Initialize() was called. No methods may be called after calling 97b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // this. 98b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void Destroy(); 99b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 100b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by the control thread to tell the workers to pause. Does not return 101b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // until all workers have called ContinueRunning() or RemoveSelf(). May only 102b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // be called between Initialize() and Stop(). Must not be called multiple 103b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // times without ResumeWorkers() having been called inbetween. 104b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void PauseWorkers(); 105b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 106b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by the control thread to tell the workers to resume from a pause. 107b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // May only be called between Initialize() and Stop(). May only be called 108b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // directly after PauseWorkers(). 109b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void ResumeWorkers(); 110b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 111b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by the control thread to tell the workers to stop. May only be 112b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // called between Initialize() and Destroy(). May only be called once. 113b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void StopWorkers(); 114b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 115b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson //-------------------------------- 116b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Methods for the worker threads. 117b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson //-------------------------------- 118b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 119b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by worker threads to decrease the worker count by one. May only be 120b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // called between Initialize() and Destroy(). May wait for ResumeWorkers() 121b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // when called after PauseWorkers(). 122b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void RemoveSelf(); 123b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 124b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Called by worker threads between Initialize() and Destroy(). May be called 125b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // any number of times. Return value is whether or not the worker should 126b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // continue running. When called after PauseWorkers(), does not return until 127b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // ResumeWorkers() or StopWorkers() has been called. Number of distinct 128b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // calling threads must match the worker count (see AddWorkers() and 129b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // RemoveSelf()). 130241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bool ContinueRunning(bool *paused); 131b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 132b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is a hack! It's like ContinueRunning(), except it won't pause. If 133b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // any worker threads use this exclusively in place of ContinueRunning() then 134b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // PauseWorkers() should never be used! 135b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool ContinueRunningNoPause(); 136b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 137b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 138b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson enum Status { RUN, PAUSE, STOP }; 139b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 140b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void WaitOnPauseBarrier() { 141241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders#ifdef HAVE_PTHREAD_BARRIERS 142b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int error = pthread_barrier_wait(&pause_barrier_); 143b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (error != PTHREAD_BARRIER_SERIAL_THREAD) 144b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(error == 0); 1458f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 146b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 147b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 148b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void AcquireNumWorkersLock() { 149b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_lock(&num_workers_mutex_)); 150b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 151b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 152b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void ReleaseNumWorkersLock() { 153b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_unlock(&num_workers_mutex_)); 154b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 155b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 156b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void AcquireStatusReadLock() { 157b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_rwlock_rdlock(&status_rwlock_)); 158b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 159b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 160b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void AcquireStatusWriteLock() { 161b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_rwlock_wrlock(&status_rwlock_)); 162b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 163b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 164b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void ReleaseStatusLock() { 165b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_rwlock_unlock(&status_rwlock_)); 166b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 167b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 168b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status GetStatus() { 169b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireStatusReadLock(); 170b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status status = status_; 171b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseStatusLock(); 172b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return status; 173b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 174b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 175b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns the previous status. 176b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status SetStatus(Status status) { 177b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireStatusWriteLock(); 178b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status prev_status = status_; 179b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson status_ = status; 180b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseStatusLock(); 181b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return prev_status; 182b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 183b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 184b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_mutex_t num_workers_mutex_; 185b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int num_workers_; 186b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 187b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_rwlock_t status_rwlock_; 188b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status status_; 189b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 190241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders#ifdef HAVE_PTHREAD_BARRIERS 191b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Guaranteed to not be in use when (status_ != PAUSE). 192b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_barrier_t pause_barrier_; 1938f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 194b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 195b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(WorkerStatus); 196b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 197b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 198b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 199b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This is a base class for worker threads. 200b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Each thread repeats a specific 201b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// task on various blocks of memory. 202b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass WorkerThread { 203b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 204b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Enum to mark a thread as low/med/high priority. 205b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson enum Priority { 206b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Low, 207b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Normal, 208b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson High, 209b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 210b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerThread(); 211b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual ~WorkerThread(); 212b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 213b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize values and thread ID number. 214b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void InitThread(int thread_num_init, 215b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class Sat *sat_init, 216b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class OsLayer *os_init, 217b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class PatternList *patternlist_init, 218b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus *worker_status); 219b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 220b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This function is DEPRECATED, it does nothing. 221b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetPriority(Priority priority) { priority_ = priority; } 222b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn the worker thread, by running Work(). 223b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int SpawnThread(); 224b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Only for ThreadSpawnerGeneric(). 225b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void StartRoutine(); 226b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool InitPriority(); 227b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 228b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Wait for the thread to complete its cleanup. 229b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool JoinThread(); 230b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Kill worker thread with SIGINT. 231b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool KillThread(); 232b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 233b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is the task function that the thread executes. 234b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is implemented per subclass. 235b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 236b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 237b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Starts per-WorkerThread timer. 238b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void StartThreadTimer() {gettimeofday(&start_time_, NULL);} 239b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Reads current timer value and returns run duration without recording it. 240b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 ReadThreadTimer() { 241b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct timeval end_time_; 242b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson gettimeofday(&end_time_, NULL); 243241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return (end_time_.tv_sec - start_time_.tv_sec)*1000000ULL + 244b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (end_time_.tv_usec - start_time_.tv_usec); 245b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 246b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Stops per-WorkerThread timer and records thread run duration. 247b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Start/Stop ThreadTimer repetitively has cumulative effect, ie the timer 248b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // is effectively paused and restarted, so runduration_usec accumulates on. 249b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void StopThreadTimer() { 250b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runduration_usec_ += ReadThreadTimer(); 251b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 252b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 253b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Acccess member variables. 254b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool GetStatus() {return status_;} 255b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetErrorCount() {return errorcount_;} 256b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetPageCount() {return pages_copied_;} 257b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetRunDurationUSec() {return runduration_usec_;} 258b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 259b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns bandwidth defined as pages_copied / thread_run_durations. 260b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetCopiedData(); 261b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific copied data. 262b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() {return 0;} 263b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() {return 0;} 264b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 265b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryBandwidth() 266b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetMemoryCopiedData() / ( 267241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders runduration_usec_ * 1.0 / 1000000.);} 268b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceBandwidth() 269b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetDeviceCopiedData() / ( 270241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders runduration_usec_ * 1.0 / 1000000.);} 271b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 272b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void set_cpu_mask(cpu_set_t *mask) { 273b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcpy(&cpu_mask_, mask, sizeof(*mask)); 274b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 275b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 276b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void set_cpu_mask_to_cpu(int cpu_num) { 277b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_set_ab(&cpu_mask_, cpu_num, cpu_num + 1); 278b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 279b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 280b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void set_tag(int32 tag) {tag_ = tag;} 281b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 282b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns CPU mask, where each bit represents a logical cpu. 283b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool AvailableCpus(cpu_set_t *cpuset); 284b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns CPU mask of CPUs this thread is bound to, 285b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool CurrentCpus(cpu_set_t *cpuset); 286b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns Current Cpus mask as string. 287b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string CurrentCpusFormat() { 288b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t current_cpus; 289b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CurrentCpus(¤t_cpus); 290b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return cpuset_format(¤t_cpus); 291b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 292b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 293b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int ThreadID() {return thread_num_;} 294b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 295b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Bind worker thread to specified CPU(s) 296b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool BindToCpus(const cpu_set_t *cpuset); 297b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 298b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 299b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This function dictates whether the main work loop 300b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // continues, waits, or terminates. 301b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // All work loops should be of the form: 302b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // do { 303b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // // work. 304b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // } while (IsReadyToRun()); 305241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders virtual bool IsReadyToRun(bool *paused = NULL) { 306241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders return worker_status_->ContinueRunning(paused); 307241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } 308241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 309b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Like IsReadyToRun(), except it won't pause. 310b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool IsReadyToRunNoPause() { 311b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return worker_status_->ContinueRunningNoPause(); 312b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 313b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 314b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // These are functions used by the various work loops. 315b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Pretty print and log a data miscompare. 316b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void ProcessError(struct ErrorRecord *er, 317b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority, 318b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 319b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 320b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Compare a region of memory with a known data patter, and report errors. 321b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CheckRegion(void *addr, 322b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class Pattern *pat, 323b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 length, 324b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int offset, 325b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 patternoffset); 326b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 327b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fast compare a block of memory. 328b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CrcCheckPage(struct page_entry *srcpe); 329b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 330b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fast copy a block of memory, while verifying correctness. 331b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CrcCopyPage(struct page_entry *dstpe, 332b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *srcpe); 333b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 334b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fast copy a block of memory, while verifying correctness, and heating CPU. 335b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CrcWarmCopyPage(struct page_entry *dstpe, 336b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *srcpe); 337b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 338b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fill a page with its specified pattern. 339b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool FillPage(struct page_entry *pe); 340b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 341b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Copy with address tagging. 342b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AdlerAddrMemcpyC(uint64 *dstmem64, 343b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 *srcmem64, 344b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes, 345b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AdlerChecksum *checksum, 346b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *pe); 347b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // SSE copy with address tagging. 348b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AdlerAddrMemcpyWarm(uint64 *dstmem64, 349b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 *srcmem64, 350b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes, 351b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AdlerChecksum *checksum, 352b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *pe); 353b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Crc data with address tagging. 354b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AdlerAddrCrcC(uint64 *srcmem64, 355b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes, 356b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AdlerChecksum *checksum, 357b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *pe); 358b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Setup tagging on an existing page. 359b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool TagAddrC(uint64 *memwords, 360b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes); 361b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Report a mistagged cacheline. 362b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReportTagError(uint64 *mem64, 363b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 actual, 364b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 tag); 365b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Print out the error record of the tag mismatch. 366b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void ProcessTagError(struct ErrorRecord *error, 367b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority, 368b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 369b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 370b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // A worker thread can yield itself to give up CPU until it's scheduled again 371b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool YieldSelf(); 372b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 373b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 374b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // General state variables that all subclasses need. 375b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int thread_num_; // Thread ID. 376b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile bool status_; // Error status. 377b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile int64 pages_copied_; // Recorded for memory bandwidth calc. 378b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile int64 errorcount_; // Miscompares seen by this thread. 379b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 380b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t cpu_mask_; // Cores this thread is allowed to run on. 381b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint32 tag_; // Tag hint for memory this thread can use. 382b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 383b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool tag_mode_; // Tag cachelines with vaddr. 384b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 385b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Thread timing variables. 386b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct timeval start_time_; // Worker thread start time. 387b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile int64 runduration_usec_; // Worker run duration in u-seconds. 388b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 389b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Function passed to pthread_create. 390b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *(*thread_spawner_)(void *args); 391b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_t thread_; // Pthread thread ID. 392b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Priority priority_; // Worker thread priority. 393b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class Sat *sat_; // Reference to parent stest object. 394b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class OsLayer *os_; // Os abstraction: put hacks here. 395b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class PatternList *patternlist_; // Reference to data patterns. 396b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 397b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Work around style guide ban on sizeof(int). 398b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const uint64 iamint_ = 0; 399b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int wordsize_ = sizeof(iamint_); 400b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 401b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 402b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus *worker_status_; 403b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 404b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(WorkerThread); 405b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 406b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 407b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform File IO. 408b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass FileThread : public WorkerThread { 409b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 410b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FileThread(); 411b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set filename to use for file IO. 412b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetFile(const char *filename_init); 413b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 414b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 415b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 416b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() 417b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*2;} 418b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData(); 419b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 420b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 421b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Record of where these pages were sourced from, and what 422b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // potentially broken components they passed through. 423b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct PageRec { 424241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders class Pattern *pattern; // This is the data it should contain. 425b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *src; // This is the memory location the data was sourced from. 426b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *dst; // This is where it ended up. 427b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 428b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 429b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // These are functions used by the various work loops. 430b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Pretty print and log a data miscompare. Disks require 431b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // slightly different error handling. 432b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void ProcessError(struct ErrorRecord *er, 433b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority, 434b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 435b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 436b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool OpenFile(int *pfile); 437b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CloseFile(int fd); 438b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 439b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Read and write whole file to disk. 440b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool WritePages(int fd); 441b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReadPages(int fd); 442b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 443b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Read and write pages to disk. 444b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool WritePageToFile(int fd, struct page_entry *src); 445b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReadPageFromFile(int fd, struct page_entry *dst); 446b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 447b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Sector tagging support. 448b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SectorTagPage(struct page_entry *src, int block); 449b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SectorValidatePage(const struct PageRec &page, 450b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *dst, 451b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int block); 452b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 453b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get memory for an incoming data transfer.. 454b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PagePrepare(); 455b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Remove memory allocated for data transfer. 456b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PageTeardown(); 457b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 458b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get memory for an incoming data transfer.. 459b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetEmptyPage(struct page_entry *dst); 460b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get memory for an outgoing data transfer.. 461b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetValidPage(struct page_entry *dst); 462b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Throw out a used empty page. 463b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PutEmptyPage(struct page_entry *src); 464b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Throw out a used, filled page. 465b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PutValidPage(struct page_entry *src); 466b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 467b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 468b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct PageRec *page_recs_; // Array of page records. 469b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int crc_page_; // Page currently being CRC checked. 470b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string filename_; // Name of file to access. 471b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string devicename_; // Name of device file is on. 472b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 473b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool page_io_; // Use page pool for IO. 474b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *local_page_; // malloc'd page fon non-pool IO. 475b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int pass_; // Number of writes to the file so far. 476b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 477b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tag to detect file corruption. 478b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct SectorTag { 479b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 magic; 480b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 block; 481b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 sector; 482b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 pass; 483b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char pad[512-4]; 484b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 485b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 486b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(FileThread); 487b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 488b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 489b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 490b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform Network IO. 491b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass NetworkThread : public WorkerThread { 492b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 493b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkThread(); 494b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set hostname to use for net IO. 495b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetIP(const char *ipaddr_init); 496b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 497b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 498b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 499b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() 500b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*2;} 501b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 502b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 503b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // IsReadyToRunNoPause() wrapper, for NetworkSlaveThread to override. 504b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool IsNetworkStopSet(); 505b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CreateSocket(int *psocket); 506b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CloseSocket(int sock); 507b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Connect(int sock); 508b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SendPage(int sock, struct page_entry *src); 509b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReceivePage(int sock, struct page_entry *dst); 510b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char ipaddr_[256]; 511b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int sock_; 512b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 513b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 514b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(NetworkThread); 515b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 516b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 517b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to reflect Network IO. 518b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass NetworkSlaveThread : public NetworkThread { 519b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 520b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkSlaveThread(); 521b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set socket for IO. 522b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetSock(int sock); 523b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 524b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 525b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 526b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool IsNetworkStopSet(); 527b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 528b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 529b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(NetworkSlaveThread); 530b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 531b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 532b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to detect incoming Network IO. 533b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass NetworkListenThread : public NetworkThread { 534b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 535b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkListenThread(); 536b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 537b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 538b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 539b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Listen(); 540b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Wait(); 541b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetConnection(int *pnewsock); 542b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SpawnSlave(int newsock, int threadid); 543b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReapSlaves(); 544b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 545b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // For serviced incoming connections. 546b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct ChildWorker { 547b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus status; 548b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkSlaveThread thread; 549b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 550b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson typedef vector<ChildWorker*> ChildVector; 551b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ChildVector child_workers_; 552b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 553b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(NetworkListenThread); 554b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 555b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 556b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform Memory Copy. 557b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CopyThread : public WorkerThread { 558b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 559b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CopyThread() {} 560b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 561b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 562b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 563b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*2;} 564b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 565b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 566b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CopyThread); 567b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 568b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 569b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform Memory Invert. 570b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass InvertThread : public WorkerThread { 571b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 572b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InvertThread() {} 573b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 574b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 575b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 576b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*4;} 577b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 578b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 579b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int InvertPageUp(struct page_entry *srcpe); 580b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int InvertPageDown(struct page_entry *srcpe); 581b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(InvertThread); 582b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 583b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 584b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to fill blank pages on startup. 585b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass FillThread : public WorkerThread { 586b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 587b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FillThread(); 588b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set how many pages this thread should fill before exiting. 589b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetFillPages(int64 num_pages_to_fill_init); 590b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 591b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 592b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 593b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fill a page with the data pattern in pe->pattern. 594b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool FillPageRandom(struct page_entry *pe); 595b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 num_pages_to_fill_; 596b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(FillThread); 597b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 598b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 599b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to verify page data matches pattern data. 600b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Thread will check and replace pages until "done" flag is set, 601b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// then it will check and discard pages until no more remain. 602b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CheckThread : public WorkerThread { 603b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 604b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckThread() {} 605b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 606b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 607b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 608b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData();} 609b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 610b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 611b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CheckThread); 612b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 613b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 614b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 615b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to poll for system error messages. 616b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Thread will check for messages until "done" flag is set. 617b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass ErrorPollThread : public WorkerThread { 618b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 619b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ErrorPollThread() {} 620b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 621b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 622b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 623b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(ErrorPollThread); 624b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 625b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 626b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Computation intensive worker thread to stress CPU. 627b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CpuStressThread : public WorkerThread { 628b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 629b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuStressThread() {} 630b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 631b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 632b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 633b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CpuStressThread); 634b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 635b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 636b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread that tests the correctness of the 637b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// CPU Cache Coherency Protocol. 638b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CpuCacheCoherencyThread : public WorkerThread { 639b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 640b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuCacheCoherencyThread(cc_cacheline_data *cc_data, 641b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_cacheline_count_, 642b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_thread_num_, 643241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int cc_thread_count_, 644b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_inc_count_); 645b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 646b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 647b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 648241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Used by the simple random number generator as a shift feedback; 649241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // this polynomial (x^64 + x^63 + x^61 + x^60 + 1) will produce a 650241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // psuedorandom cycle of period 2^64-1. 651241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static const uint64 kRandomPolynomial = 0xD800000000000000ULL; 652241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // A very simple psuedorandom generator that can be inlined and use 653241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // registers, to keep the CC test loop tight and focused. 654241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static uint64 SimpleRandom(uint64 seed); 655241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 656b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data *cc_cacheline_data_; // Datstructure for each cacheline. 657b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_local_num_; // Local counter for each thread. 658b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_cacheline_count_; // Number of cache lines to operate on. 659b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_thread_num_; // The integer id of the thread which is 660b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // used as an index into the integer array 661b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // of the cacheline datastructure. 662241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int cc_thread_count_; // Total number of threads being run, for 663241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // calculations mixing up cache line access. 664b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_inc_count_; // Number of times to increment the counter. 665b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 666b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 667b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CpuCacheCoherencyThread); 668b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 669b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 670b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform disk test. 671b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass DiskThread : public WorkerThread { 672b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 673b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson explicit DiskThread(DiskBlockTable *block_table); 674b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual ~DiskThread(); 675b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate disk thread specific bandwidth. 676b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() { 677b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return (blocks_written_ * write_block_size_ + 678b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_read_ * read_block_size_) / kMegabyte;} 679b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 680b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set filename for device file (in /dev). 681b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetDevice(const char *device_name); 682b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set various parameters that control the behaviour of the test. 683b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SetParameters(int read_block_size, 684b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int write_block_size, 685b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 segment_size, 686b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 cache_size, 687b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int blocks_per_segment, 688b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 read_threshold, 689b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 write_threshold, 690b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int non_destructive); 691b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 692b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 693b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 694b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() {return 0;} 695b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 696b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 697b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kSectorSize = 512; // Size of sector on disk. 698b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kBufferAlignment = 512; // Buffer alignment required by the 699b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // kernel. 700b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kBlockRetry = 100; // Number of retries to allocate 701b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // sectors. 702b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 703b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson enum IoOp { 704b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ASYNC_IO_READ = 0, 705b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ASYNC_IO_WRITE = 1 706b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 707b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 708b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool OpenDevice(int *pfile); 709b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CloseDevice(int fd); 710b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 711b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Retrieves the size (in bytes) of the disk/file. 712b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetDiskSize(int fd); 713b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 714b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Retrieves the current time in microseconds. 715b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int64 GetTime(); 716b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 717b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do an asynchronous disk I/O operation. 718b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AsyncDiskIO(IoOp op, int fd, void *buf, int64 size, 719b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 offset, int64 timeout); 720b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 721b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Write a block to disk. 722b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool WriteBlockToDisk(int fd, BlockData *block); 723b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 724b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Verify a block on disk. 725b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ValidateBlockOnDisk(int fd, BlockData *block); 726b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 727b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Main work loop. 728b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool DoWork(int fd); 729b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 730b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int read_block_size_; // Size of blocks read from disk, in bytes. 731b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int write_block_size_; // Size of blocks written to disk, in bytes. 732b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 blocks_read_; // Number of blocks read in work loop. 733b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 blocks_written_; // Number of blocks written in work loop. 734b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 segment_size_; // Size of disk segments (in bytes) that the disk 735b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // will be split into where testing can be 736b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // confined to a particular segment. 737b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allows for control of how evenly the disk will 738b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // be tested. Smaller segments imply more even 739b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // testing (less random). 740b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int blocks_per_segment_; // Number of blocks that will be tested per 741b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // segment. 742b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cache_size_; // Size of disk cache, in bytes. 743b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int queue_size_; // Length of in-flight-blocks queue, in blocks. 744b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int non_destructive_; // Use non-destructive mode or not. 745b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int update_block_table_; // If true, assume this is the thread 746b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // responsible for writing the data in the disk 747b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // for this block device and, therefore, 748b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // update the block table. If false, just use 749b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // the block table to get data. 750b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 751b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // read/write times threshold for reporting a problem 752b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 read_threshold_; // Maximum time a read should take (in us) before 753b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // a warning is given. 754b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 write_threshold_; // Maximum time a write should take (in us) before 755b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // a warning is given. 756b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 read_timeout_; // Maximum time a read can take before a timeout 757b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // and the aborting of the read operation. 758b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 write_timeout_; // Maximum time a write can take before a timeout 759b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // and the aborting of the write operation. 760b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 761b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string device_name_; // Name of device file to access. 762b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 device_sectors_; // Number of sectors on the device. 763b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 764b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson std::queue<BlockData*> in_flight_sectors_; // Queue of sectors written but 765b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // not verified. 766b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *block_buffer_; // Pointer to aligned block buffer. 767b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 7688f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#ifdef HAVE_LIBAIO_H 769b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson io_context_t aio_ctx_; // Asynchronous I/O context for Linux native AIO. 7708f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 771b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 772b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DiskBlockTable *block_table_; // Disk Block Table, shared by all disk 773b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // threads that read / write at the same 774b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // device 775b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 776b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(DiskThread); 777b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 778b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 779b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass RandomDiskThread : public DiskThread { 780b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 781b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson explicit RandomDiskThread(DiskBlockTable *block_table); 782b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual ~RandomDiskThread(); 783b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Main work loop. 784b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool DoWork(int fd); 785b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 786b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(RandomDiskThread); 787b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 788b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 789b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform checks in a specific memory region. 790b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass MemoryRegionThread : public WorkerThread { 791b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 792b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson MemoryRegionThread(); 793b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ~MemoryRegionThread(); 794b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 795b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void ProcessError(struct ErrorRecord *error, int priority, 796b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 797b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool SetRegion(void *region, int64 size); 798b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 799b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 800b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData();} 801b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() 802b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData() * 2;} 803b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetIdentifier(string identifier) { 804b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson identifier_ = identifier; 805b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 806b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 807b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 808b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Page queue for this particular memory region. 809b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char *region_; 810b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PageEntryQueue *pages_; 811b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool error_injection_; 812b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int phase_; 813b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string identifier_; 814b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kPhaseNoPhase = 0; 815b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kPhaseCopy = 1; 816b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kPhaseCheck = 2; 817b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 818b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 819b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(MemoryRegionThread); 820b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 821b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 822241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders// Worker thread to check that the frequency of every cpu does not go below a 823241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders// certain threshold. 824241f33a3e958842e3db803c03300764bd2ee9c19Nick Sandersclass CpuFreqThread : public WorkerThread { 825241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders public: 826241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders CpuFreqThread(int num_cpus, int freq_threshold, int round); 827241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders ~CpuFreqThread(); 828241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 829241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // This is the task function that the thread executes. 830241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders virtual bool Work(); 831241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 832241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Returns true if this test can run on the current machine. Otherwise, 833241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // returns false. 834241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static bool CanRun(); 835241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 836241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders private: 837241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static const int kIntervalPause = 10; // The number of seconds to pause 838241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // between acquiring the MSR data. 839241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static const int kStartupDelay = 5; // The number of seconds to wait 840241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // before acquiring MSR data. 841241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static const int kMsrTscAddr = 0x10; // The address of the TSC MSR. 842241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static const int kMsrAperfAddr = 0xE8; // The address of the APERF MSR. 843241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static const int kMsrMperfAddr = 0xE7; // The address of the MPERF MSR. 844241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 845241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // The index values into the CpuDataType.msr[] array. 846241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders enum MsrValues { 847241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders kMsrTsc = 0, // MSR index 0 = TSC. 848241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders kMsrAperf = 1, // MSR index 1 = APERF. 849241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders kMsrMperf = 2, // MSR index 2 = MPERF. 850241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders kMsrLast, // Last MSR index. 851241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders }; 852241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 853241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders typedef struct { 854241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders uint32 msr; // The address of the MSR. 855241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders const char *name; // A human readable string for the MSR. 856241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } CpuRegisterType; 857241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 858241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders typedef struct { 859241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders uint64 msrs[kMsrLast]; // The values of the MSRs. 860241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders struct timeval tv; // The time at which the MSRs were read. 861241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders } CpuDataType; 862241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 863241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // The set of MSR addresses and register names. 864241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders static const CpuRegisterType kCpuRegisters[kMsrLast]; 865241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 866241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Compute the change in values of the MSRs between current and previous, 867241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // set the frequency in MHz of the cpu. If there is an error computing 868241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // the delta, return false. Othewise, return true. 869241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bool ComputeFrequency(CpuDataType *current, CpuDataType *previous, 870241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int *frequency); 871241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 872241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Get the MSR values for this particular cpu and save them in data. If 873241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // any error is encountered, returns false. Otherwise, returns true. 874241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bool GetMsrs(int cpu, CpuDataType *data); 875241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 876241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Compute the difference between the currently read MSR values and the 877241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // previously read values and store the results in delta. If any of the 878241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // values did not increase, or the TSC value is too small, returns false. 879241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Otherwise, returns true. 880241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders bool ComputeDelta(CpuDataType *current, CpuDataType *previous, 881241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders CpuDataType *delta); 882241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 883241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // The total number of cpus on the system. 884241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int num_cpus_; 885241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 886241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // The minimum frequency that each cpu must operate at (in MHz). 887241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int freq_threshold_; 888241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 889241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // The value to round the computed frequency to. 890241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders int round_; 891241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 892241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders // Precomputed value to add to the frequency to do the rounding. 893241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders double round_value_; 894241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 895241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders DISALLOW_COPY_AND_ASSIGN(CpuFreqThread); 896241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders}; 897241f33a3e958842e3db803c03300764bd2ee9c19Nick Sanders 898b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#endif // STRESSAPPTEST_WORKER_H_ 899