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(&current_cpus);
290b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson    return cpuset_format(&current_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