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// pattern.h : global pattern references and initialization
16b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
17b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This file implements easy access to statically declared
18b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// data patterns.
19b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
20b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#ifndef STRESSAPPTEST_PATTERN_H_
21b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#define STRESSAPPTEST_PATTERN_H_
22b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
23b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <vector>
24b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include <string>
25b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
26b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This file must work with autoconf on its public version,
27b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// so these includes are correct.
28b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "adler32memcpy.h"
29b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#include "sattypes.h"
30b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
31b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// 2 = 128 bit bus, 1 = 64 bit bus, 0 = 32 bit bus
32b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonconst int kBusShift = 2;
33b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
34b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Pattern and CRC data structure
35b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonstruct PatternData {
36b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  const char *name;          // Name of this pattern.
37b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  unsigned int *pat;         // Data array.
38b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  unsigned int mask;         // Size - 1. data[index & mask] is always valid.
39b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  unsigned char weight[4];   // Weighted frequency of this pattern.
40b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                             // Each pattern has 32,64,128,256 width versions.
41b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                             // All weights are added up, a random number is
42b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                             // chosen between 0-sum(weights), and the
43b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                             // appropriate pattern is chosen. Thus a weight of
44b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                             // 1 is rare, a weight of 10 is 2x as likely to be
45b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                             // chosen as a weight of 5.
46b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson};
47b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
48b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Data structure to access data patterns.
49b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass Pattern {
50b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public:
51b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  Pattern();
52b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  ~Pattern();
53b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // Fill pattern data and calculate CRC.
54b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int Initialize(const struct PatternData &pattern_init,
55b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                 int buswidth,
56b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                 bool invert,
57b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                 int weight);
58b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
59b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // Access data members.
60b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // "busshift_" allows for repeating each pattern word 1, 2, 4, etc. times.
61b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // in order to create patterns of different width.
62b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  unsigned int pattern(unsigned int offset) {
63b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson    unsigned int data = pattern_->pat[(offset >> busshift_) & pattern_->mask];
64b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson    if (inverse_)
65b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson      data = ~data;
66b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson    return data;
67b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  }
68b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  const AdlerChecksum *crc() {return crc_;}
69b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  unsigned int mask() {return pattern_->mask;}
70b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  unsigned int weight() {return weight_;}
71b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  const char *name() {return name_.c_str();}
72b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
73b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private:
74b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int CalculateCrc();
75b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  const struct PatternData *pattern_;
76b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int busshift_;        // Target data bus width.
77b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  bool inverse_;        // Invert the data from the original pattern.
78b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  AdlerChecksum *crc_;  // CRC of this pattern.
79b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  string name_;         // The human readable pattern name.
80b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int weight_;          // This is the likelihood that this
81b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson                        // pattern will be chosen.
82b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // We want to copy this!
83b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // DISALLOW_COPY_AND_ASSIGN(Pattern);
84b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson};
85b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
86b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// Object used to access global pattern list.
87b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonclass PatternList {
88b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson public:
89b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  PatternList();
90b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  ~PatternList();
91b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // Initialize pointers to global data patterns, and calculate CRC.
92b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int Initialize();
93b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int Destroy();
94b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
95b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // Return the pattern designated by index i.
96b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  Pattern *GetPattern(int i);
97b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // Return a random pattern according to the specified weighted probability.
98b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  Pattern *GetRandomPattern();
99b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  // Return the number of patterns available.
100b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int Size() {return size_;}
101b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
102b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson private:
103b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  vector<class Pattern> patterns_;
104b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int weightcount_;  // Total count of pattern weights.
105b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  unsigned int size_;
106b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  int initialized_;
107b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  DISALLOW_COPY_AND_ASSIGN(PatternList);
108b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson};
109b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
110b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// CrcIncrement allows an abstracted way to add a 32bit
111b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// value into a running CRC. This function should be fast, and
112b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// generate meaningful CRCs for the types of data patterns that
113b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// we are using here.
114b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// This CRC formula may not be optimal, but it does work.
115b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson// It may be improved in the future.
116b0114cb9f332db144f65291211ae65f7f0e814e6Scott Andersonstatic inline uint32 CrcIncrement(uint32 crc, uint32 expected, int index) {
117b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  uint32 addition = (expected ^ index);
118b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  uint32 carry = (addition & crc) >> 31;
119b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
120b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson  return crc + addition + carry;
121b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson}
122b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
123b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson
124b0114cb9f332db144f65291211ae65f7f0e814e6Scott Anderson#endif  // STRESSAPPTEST_PATTERN_H_
125