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 { 47b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int *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()). 130b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool ContinueRunning(); 131b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 132b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // TODO(matthewb): Is this functionality really necessary? Remove it if not. 133b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 134b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is a hack! It's like ContinueRunning(), except it won't pause. If 135b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // any worker threads use this exclusively in place of ContinueRunning() then 136b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // PauseWorkers() should never be used! 137b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool ContinueRunningNoPause(); 138b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 139b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 140b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson enum Status { RUN, PAUSE, STOP }; 141b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 142b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void WaitOnPauseBarrier() { 1438f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#ifdef _POSIX_BARRIERS 144b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int error = pthread_barrier_wait(&pause_barrier_); 145b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson if (error != PTHREAD_BARRIER_SERIAL_THREAD) 146b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(error == 0); 1478f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 148b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 149b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 150b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void AcquireNumWorkersLock() { 151b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_lock(&num_workers_mutex_)); 152b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 153b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 154b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void ReleaseNumWorkersLock() { 155b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_mutex_unlock(&num_workers_mutex_)); 156b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 157b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 158b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void AcquireStatusReadLock() { 159b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_rwlock_rdlock(&status_rwlock_)); 160b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 161b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 162b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void AcquireStatusWriteLock() { 163b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_rwlock_wrlock(&status_rwlock_)); 164b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 165b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 166b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void ReleaseStatusLock() { 167b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson sat_assert(0 == pthread_rwlock_unlock(&status_rwlock_)); 168b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 169b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 170b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status GetStatus() { 171b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireStatusReadLock(); 172b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status status = status_; 173b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseStatusLock(); 174b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return status; 175b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 176b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 177b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns the previous status. 178b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status SetStatus(Status status) { 179b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AcquireStatusWriteLock(); 180b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status prev_status = status_; 181b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson status_ = status; 182b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ReleaseStatusLock(); 183b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return prev_status; 184b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 185b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 186b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_mutex_t num_workers_mutex_; 187b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int num_workers_; 188b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 189b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_rwlock_t status_rwlock_; 190b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Status status_; 191b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 1928f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#ifdef _POSIX_BARRIERS 193b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Guaranteed to not be in use when (status_ != PAUSE). 194b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_barrier_t pause_barrier_; 1958f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 196b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 197b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(WorkerStatus); 198b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 199b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 200b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 201b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This is a base class for worker threads. 202b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Each thread repeats a specific 203b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// task on various blocks of memory. 204b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass WorkerThread { 205b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 206b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Enum to mark a thread as low/med/high priority. 207b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson enum Priority { 208b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Low, 209b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Normal, 210b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson High, 211b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 212b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerThread(); 213b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual ~WorkerThread(); 214b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 215b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Initialize values and thread ID number. 216b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void InitThread(int thread_num_init, 217b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class Sat *sat_init, 218b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class OsLayer *os_init, 219b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class PatternList *patternlist_init, 220b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus *worker_status); 221b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 222b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This function is DEPRECATED, it does nothing. 223b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetPriority(Priority priority) { priority_ = priority; } 224b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Spawn the worker thread, by running Work(). 225b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int SpawnThread(); 226b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Only for ThreadSpawnerGeneric(). 227b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void StartRoutine(); 228b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool InitPriority(); 229b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 230b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Wait for the thread to complete its cleanup. 231b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool JoinThread(); 232b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Kill worker thread with SIGINT. 233b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool KillThread(); 234b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 235b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is the task function that the thread executes. 236b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This is implemented per subclass. 237b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 238b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 239b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Starts per-WorkerThread timer. 240b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void StartThreadTimer() {gettimeofday(&start_time_, NULL);} 241b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Reads current timer value and returns run duration without recording it. 242b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 ReadThreadTimer() { 243b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct timeval end_time_; 244b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson gettimeofday(&end_time_, NULL); 245b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return (end_time_.tv_sec - start_time_.tv_sec)*1000000 + 246b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson (end_time_.tv_usec - start_time_.tv_usec); 247b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 248b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Stops per-WorkerThread timer and records thread run duration. 249b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Start/Stop ThreadTimer repetitively has cumulative effect, ie the timer 250b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // is effectively paused and restarted, so runduration_usec accumulates on. 251b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void StopThreadTimer() { 252b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runduration_usec_ += ReadThreadTimer(); 253b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 254b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 255b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Acccess member variables. 256b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool GetStatus() {return status_;} 257b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetErrorCount() {return errorcount_;} 258b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetPageCount() {return pages_copied_;} 259b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 GetRunDurationUSec() {return runduration_usec_;} 260b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 261b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns bandwidth defined as pages_copied / thread_run_durations. 262b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetCopiedData(); 263b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific copied data. 264b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() {return 0;} 265b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() {return 0;} 266b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 267b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryBandwidth() 268b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetMemoryCopiedData() / ( 269b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runduration_usec_ * 1.0 / 1000000);} 270b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceBandwidth() 271b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetDeviceCopiedData() / ( 272b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson runduration_usec_ * 1.0 / 1000000);} 273b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 274b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void set_cpu_mask(cpu_set_t *mask) { 275b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson memcpy(&cpu_mask_, mask, sizeof(*mask)); 276b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 277b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 278b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void set_cpu_mask_to_cpu(int cpu_num) { 279b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpuset_set_ab(&cpu_mask_, cpu_num, cpu_num + 1); 280b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 281b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 282b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void set_tag(int32 tag) {tag_ = tag;} 283b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 284b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns CPU mask, where each bit represents a logical cpu. 285b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool AvailableCpus(cpu_set_t *cpuset); 286b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns CPU mask of CPUs this thread is bound to, 287b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool CurrentCpus(cpu_set_t *cpuset); 288b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Returns Current Cpus mask as string. 289b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string CurrentCpusFormat() { 290b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t current_cpus; 291b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CurrentCpus(¤t_cpus); 292b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return cpuset_format(¤t_cpus); 293b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 294b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 295b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int ThreadID() {return thread_num_;} 296b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 297b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Bind worker thread to specified CPU(s) 298b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool BindToCpus(const cpu_set_t *cpuset); 299b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 300b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 301b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // This function dictates whether the main work loop 302b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // continues, waits, or terminates. 303b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // All work loops should be of the form: 304b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // do { 305b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // // work. 306b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // } while (IsReadyToRun()); 307b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool IsReadyToRun() { return worker_status_->ContinueRunning(); } 308b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // TODO(matthewb): Is this function really necessary? Remove it if not. 309b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // 310b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Like IsReadyToRun(), except it won't pause. 311b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool IsReadyToRunNoPause() { 312b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return worker_status_->ContinueRunningNoPause(); 313b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 314b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 315b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // These are functions used by the various work loops. 316b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Pretty print and log a data miscompare. 317b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void ProcessError(struct ErrorRecord *er, 318b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority, 319b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 320b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 321b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Compare a region of memory with a known data patter, and report errors. 322b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CheckRegion(void *addr, 323b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class Pattern *pat, 324b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 length, 325b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int offset, 326b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 patternoffset); 327b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 328b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fast compare a block of memory. 329b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CrcCheckPage(struct page_entry *srcpe); 330b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 331b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fast copy a block of memory, while verifying correctness. 332b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CrcCopyPage(struct page_entry *dstpe, 333b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *srcpe); 334b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 335b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fast copy a block of memory, while verifying correctness, and heating CPU. 336b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int CrcWarmCopyPage(struct page_entry *dstpe, 337b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *srcpe); 338b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 339b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fill a page with its specified pattern. 340b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool FillPage(struct page_entry *pe); 341b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 342b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Copy with address tagging. 343b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AdlerAddrMemcpyC(uint64 *dstmem64, 344b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 *srcmem64, 345b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes, 346b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AdlerChecksum *checksum, 347b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *pe); 348b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // SSE copy with address tagging. 349b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AdlerAddrMemcpyWarm(uint64 *dstmem64, 350b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 *srcmem64, 351b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes, 352b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AdlerChecksum *checksum, 353b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *pe); 354b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Crc data with address tagging. 355b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AdlerAddrCrcC(uint64 *srcmem64, 356b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes, 357b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson AdlerChecksum *checksum, 358b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *pe); 359b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Setup tagging on an existing page. 360b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool TagAddrC(uint64 *memwords, 361b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson unsigned int size_in_bytes); 362b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Report a mistagged cacheline. 363b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReportTagError(uint64 *mem64, 364b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 actual, 365b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson uint64 tag); 366b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Print out the error record of the tag mismatch. 367b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void ProcessTagError(struct ErrorRecord *error, 368b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority, 369b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 370b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 371b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // A worker thread can yield itself to give up CPU until it's scheduled again 372b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool YieldSelf(); 373b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 374b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 375b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // General state variables that all subclasses need. 376b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int thread_num_; // Thread ID. 377b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile bool status_; // Error status. 378b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile int64 pages_copied_; // Recorded for memory bandwidth calc. 379b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile int64 errorcount_; // Miscompares seen by this thread. 380b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 381b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cpu_set_t cpu_mask_; // Cores this thread is allowed to run on. 382b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint32 tag_; // Tag hint for memory this thread can use. 383b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 384b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool tag_mode_; // Tag cachelines with vaddr. 385b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 386b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Thread timing variables. 387b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct timeval start_time_; // Worker thread start time. 388b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile int64 runduration_usec_; // Worker run duration in u-seconds. 389b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 390b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Function passed to pthread_create. 391b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *(*thread_spawner_)(void *args); 392b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson pthread_t thread_; // Pthread thread ID. 393b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson Priority priority_; // Worker thread priority. 394b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class Sat *sat_; // Reference to parent stest object. 395b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class OsLayer *os_; // Os abstraction: put hacks here. 396b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson class PatternList *patternlist_; // Reference to data patterns. 397b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 398b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Work around style guide ban on sizeof(int). 399b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const uint64 iamint_ = 0; 400b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int wordsize_ = sizeof(iamint_); 401b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 402b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 403b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus *worker_status_; 404b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 405b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(WorkerThread); 406b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 407b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 408b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform File IO. 409b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass FileThread : public WorkerThread { 410b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 411b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FileThread(); 412b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set filename to use for file IO. 413b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetFile(const char *filename_init); 414b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 415b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 416b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 417b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() 418b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*2;} 419b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData(); 420b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 421b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 422b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Record of where these pages were sourced from, and what 423b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // potentially broken components they passed through. 424b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct PageRec { 425b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct Pattern *pattern; // This is the data it should contain. 426b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *src; // This is the memory location the data was sourced from. 427b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *dst; // This is where it ended up. 428b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 429b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 430b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // These are functions used by the various work loops. 431b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Pretty print and log a data miscompare. Disks require 432b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // slightly different error handling. 433b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void ProcessError(struct ErrorRecord *er, 434b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int priority, 435b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 436b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 437b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool OpenFile(int *pfile); 438b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CloseFile(int fd); 439b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 440b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Read and write whole file to disk. 441b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool WritePages(int fd); 442b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReadPages(int fd); 443b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 444b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Read and write pages to disk. 445b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool WritePageToFile(int fd, struct page_entry *src); 446b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReadPageFromFile(int fd, struct page_entry *dst); 447b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 448b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Sector tagging support. 449b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SectorTagPage(struct page_entry *src, int block); 450b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SectorValidatePage(const struct PageRec &page, 451b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct page_entry *dst, 452b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int block); 453b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 454b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get memory for an incoming data transfer.. 455b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PagePrepare(); 456b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Remove memory allocated for data transfer. 457b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PageTeardown(); 458b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 459b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get memory for an incoming data transfer.. 460b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetEmptyPage(struct page_entry *dst); 461b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Get memory for an outgoing data transfer.. 462b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetValidPage(struct page_entry *dst); 463b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Throw out a used empty page. 464b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PutEmptyPage(struct page_entry *src); 465b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Throw out a used, filled page. 466b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool PutValidPage(struct page_entry *src); 467b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 468b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 469b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct PageRec *page_recs_; // Array of page records. 470b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int crc_page_; // Page currently being CRC checked. 471b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string filename_; // Name of file to access. 472b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string devicename_; // Name of device file is on. 473b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 474b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool page_io_; // Use page pool for IO. 475b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *local_page_; // malloc'd page fon non-pool IO. 476b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int pass_; // Number of writes to the file so far. 477b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 478b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Tag to detect file corruption. 479b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct SectorTag { 480b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 magic; 481b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 block; 482b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 sector; 483b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson volatile uint8 pass; 484b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char pad[512-4]; 485b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 486b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 487b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(FileThread); 488b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 489b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 490b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 491b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform Network IO. 492b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass NetworkThread : public WorkerThread { 493b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 494b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkThread(); 495b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set hostname to use for net IO. 496b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetIP(const char *ipaddr_init); 497b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 498b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 499b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 500b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() 501b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*2;} 502b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 503b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 504b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // IsReadyToRunNoPause() wrapper, for NetworkSlaveThread to override. 505b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool IsNetworkStopSet(); 506b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CreateSocket(int *psocket); 507b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CloseSocket(int sock); 508b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Connect(int sock); 509b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SendPage(int sock, struct page_entry *src); 510b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReceivePage(int sock, struct page_entry *dst); 511b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char ipaddr_[256]; 512b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int sock_; 513b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 514b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 515b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(NetworkThread); 516b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 517b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 518b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to reflect Network IO. 519b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass NetworkSlaveThread : public NetworkThread { 520b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 521b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkSlaveThread(); 522b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set socket for IO. 523b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetSock(int sock); 524b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 525b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 526b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 527b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool IsNetworkStopSet(); 528b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 529b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 530b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(NetworkSlaveThread); 531b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 532b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 533b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to detect incoming Network IO. 534b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass NetworkListenThread : public NetworkThread { 535b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 536b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkListenThread(); 537b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 538b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 539b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 540b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Listen(); 541b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Wait(); 542b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetConnection(int *pnewsock); 543b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SpawnSlave(int newsock, int threadid); 544b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ReapSlaves(); 545b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 546b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // For serviced incoming connections. 547b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson struct ChildWorker { 548b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson WorkerStatus status; 549b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson NetworkSlaveThread thread; 550b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 551b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson typedef vector<ChildWorker*> ChildVector; 552b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ChildVector child_workers_; 553b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 554b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(NetworkListenThread); 555b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 556b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 557b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform Memory Copy. 558b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CopyThread : public WorkerThread { 559b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 560b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CopyThread() {} 561b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 562b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 563b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 564b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*2;} 565b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 566b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 567b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CopyThread); 568b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 569b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 570b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform Memory Invert. 571b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass InvertThread : public WorkerThread { 572b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 573b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson InvertThread() {} 574b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 575b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 576b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 577b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData()*4;} 578b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 579b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 580b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int InvertPageUp(struct page_entry *srcpe); 581b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int InvertPageDown(struct page_entry *srcpe); 582b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(InvertThread); 583b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 584b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 585b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to fill blank pages on startup. 586b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass FillThread : public WorkerThread { 587b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 588b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson FillThread(); 589b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set how many pages this thread should fill before exiting. 590b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetFillPages(int64 num_pages_to_fill_init); 591b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 592b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 593b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 594b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Fill a page with the data pattern in pe->pattern. 595b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool FillPageRandom(struct page_entry *pe); 596b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 num_pages_to_fill_; 597b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(FillThread); 598b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 599b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 600b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to verify page data matches pattern data. 601b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Thread will check and replace pages until "done" flag is set, 602b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// then it will check and discard pages until no more remain. 603b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CheckThread : public WorkerThread { 604b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 605b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CheckThread() {} 606b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 607b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 608b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 609b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData();} 610b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 611b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 612b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CheckThread); 613b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 614b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 615b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 616b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to poll for system error messages. 617b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Thread will check for messages until "done" flag is set. 618b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass ErrorPollThread : public WorkerThread { 619b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 620b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ErrorPollThread() {} 621b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 622b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 623b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 624b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(ErrorPollThread); 625b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 626b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 627b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Computation intensive worker thread to stress CPU. 628b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CpuStressThread : public WorkerThread { 629b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 630b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuStressThread() {} 631b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 632b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 633b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 634b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CpuStressThread); 635b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 636b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 637b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread that tests the correctness of the 638b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// CPU Cache Coherency Protocol. 639b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass CpuCacheCoherencyThread : public WorkerThread { 640b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 641b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson CpuCacheCoherencyThread(cc_cacheline_data *cc_data, 642b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_cacheline_count_, 643b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_thread_num_, 644b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_inc_count_); 645b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 646b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 647b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 648b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson cc_cacheline_data *cc_cacheline_data_; // Datstructure for each cacheline. 649b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_local_num_; // Local counter for each thread. 650b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_cacheline_count_; // Number of cache lines to operate on. 651b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_thread_num_; // The integer id of the thread which is 652b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // used as an index into the integer array 653b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // of the cacheline datastructure. 654b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cc_inc_count_; // Number of times to increment the counter. 655b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 656b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 657b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(CpuCacheCoherencyThread); 658b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 659b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 660b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform disk test. 661b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass DiskThread : public WorkerThread { 662b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 663b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson explicit DiskThread(DiskBlockTable *block_table); 664b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual ~DiskThread(); 665b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate disk thread specific bandwidth. 666b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() { 667b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson return (blocks_written_ * write_block_size_ + 668b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson blocks_read_ * read_block_size_) / kMegabyte;} 669b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 670b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set filename for device file (in /dev). 671b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual void SetDevice(const char *device_name); 672b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Set various parameters that control the behaviour of the test. 673b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool SetParameters(int read_block_size, 674b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int write_block_size, 675b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 segment_size, 676b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 cache_size, 677b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int blocks_per_segment, 678b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 read_threshold, 679b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 write_threshold, 680b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int non_destructive); 681b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 682b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 683b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 684b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() {return 0;} 685b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 686b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 687b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kSectorSize = 512; // Size of sector on disk. 688b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kBufferAlignment = 512; // Buffer alignment required by the 689b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // kernel. 690b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kBlockRetry = 100; // Number of retries to allocate 691b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // sectors. 692b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 693b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson enum IoOp { 694b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ASYNC_IO_READ = 0, 695b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ASYNC_IO_WRITE = 1 696b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson }; 697b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 698b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool OpenDevice(int *pfile); 699b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool CloseDevice(int fd); 700b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 701b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Retrieves the size (in bytes) of the disk/file. 702b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool GetDiskSize(int fd); 703b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 704b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Retrieves the current time in microseconds. 705b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual int64 GetTime(); 706b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 707b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Do an asynchronous disk I/O operation. 708b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool AsyncDiskIO(IoOp op, int fd, void *buf, int64 size, 709b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 offset, int64 timeout); 710b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 711b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Write a block to disk. 712b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool WriteBlockToDisk(int fd, BlockData *block); 713b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 714b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Verify a block on disk. 715b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool ValidateBlockOnDisk(int fd, BlockData *block); 716b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 717b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Main work loop. 718b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool DoWork(int fd); 719b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 720b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int read_block_size_; // Size of blocks read from disk, in bytes. 721b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int write_block_size_; // Size of blocks written to disk, in bytes. 722b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 blocks_read_; // Number of blocks read in work loop. 723b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 blocks_written_; // Number of blocks written in work loop. 724b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 segment_size_; // Size of disk segments (in bytes) that the disk 725b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // will be split into where testing can be 726b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // confined to a particular segment. 727b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Allows for control of how evenly the disk will 728b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // be tested. Smaller segments imply more even 729b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // testing (less random). 730b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int blocks_per_segment_; // Number of blocks that will be tested per 731b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // segment. 732b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int cache_size_; // Size of disk cache, in bytes. 733b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int queue_size_; // Length of in-flight-blocks queue, in blocks. 734b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int non_destructive_; // Use non-destructive mode or not. 735b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int update_block_table_; // If true, assume this is the thread 736b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // responsible for writing the data in the disk 737b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // for this block device and, therefore, 738b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // update the block table. If false, just use 739b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // the block table to get data. 740b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 741b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // read/write times threshold for reporting a problem 742b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 read_threshold_; // Maximum time a read should take (in us) before 743b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // a warning is given. 744b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 write_threshold_; // Maximum time a write should take (in us) before 745b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // a warning is given. 746b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 read_timeout_; // Maximum time a read can take before a timeout 747b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // and the aborting of the read operation. 748b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 write_timeout_; // Maximum time a write can take before a timeout 749b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // and the aborting of the write operation. 750b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 751b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string device_name_; // Name of device file to access. 752b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int64 device_sectors_; // Number of sectors on the device. 753b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 754b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson std::queue<BlockData*> in_flight_sectors_; // Queue of sectors written but 755b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // not verified. 756b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void *block_buffer_; // Pointer to aligned block buffer. 757b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 7588f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#ifdef HAVE_LIBAIO_H 759b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson io_context_t aio_ctx_; // Asynchronous I/O context for Linux native AIO. 7608f1c60d605d31447b4f9ccf86029790bed3fb3f3Scott Anderson#endif 761b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 762b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DiskBlockTable *block_table_; // Disk Block Table, shared by all disk 763b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // threads that read / write at the same 764b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // device 765b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 766b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(DiskThread); 767b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 768b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 769b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass RandomDiskThread : public DiskThread { 770b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 771b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson explicit RandomDiskThread(DiskBlockTable *block_table); 772b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual ~RandomDiskThread(); 773b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Main work loop. 774b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool DoWork(int fd); 775b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 776b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(RandomDiskThread); 777b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 778b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 779b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Worker thread to perform checks in a specific memory region. 780b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass MemoryRegionThread : public WorkerThread { 781b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public: 782b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson MemoryRegionThread(); 783b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson ~MemoryRegionThread(); 784b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual bool Work(); 785b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void ProcessError(struct ErrorRecord *error, int priority, 786b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson const char *message); 787b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool SetRegion(void *region, int64 size); 788b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Calculate worker thread specific bandwidth. 789b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetMemoryCopiedData() 790b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData();} 791b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson virtual float GetDeviceCopiedData() 792b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson {return GetCopiedData() * 2;} 793b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson void SetIdentifier(string identifier) { 794b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson identifier_ = identifier; 795b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson } 796b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 797b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson protected: 798b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson // Page queue for this particular memory region. 799b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson char *region_; 800b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson PageEntryQueue *pages_; 801b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson bool error_injection_; 802b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson int phase_; 803b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson string identifier_; 804b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kPhaseNoPhase = 0; 805b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kPhaseCopy = 1; 806b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson static const int kPhaseCheck = 2; 807b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 808b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private: 809b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson DISALLOW_COPY_AND_ASSIGN(MemoryRegionThread); 810b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}; 811b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson 812b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#endif // STRESSAPPTEST_WORKER_H_ 813