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