xref: /aosp_15_r20/external/stressapptest/src/finelock_queue.h (revision 424fb153c814cbcb3e8904974796228774b3229a)
1*424fb153SAndroid Build Coastguard Worker // Copyright 2007 Google Inc. All Rights Reserved.
2*424fb153SAndroid Build Coastguard Worker 
3*424fb153SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
4*424fb153SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
5*424fb153SAndroid Build Coastguard Worker // You may obtain a copy of the License at
6*424fb153SAndroid Build Coastguard Worker 
7*424fb153SAndroid Build Coastguard Worker //      http://www.apache.org/licenses/LICENSE-2.0
8*424fb153SAndroid Build Coastguard Worker 
9*424fb153SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
10*424fb153SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
11*424fb153SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*424fb153SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
13*424fb153SAndroid Build Coastguard Worker // limitations under the License.
14*424fb153SAndroid Build Coastguard Worker 
15*424fb153SAndroid Build Coastguard Worker // This page entry queue implementation with fine grain locks aim to ease
16*424fb153SAndroid Build Coastguard Worker // lock contention over previous queue implementation (with one lock protecting
17*424fb153SAndroid Build Coastguard Worker // the entire queue).
18*424fb153SAndroid Build Coastguard Worker 
19*424fb153SAndroid Build Coastguard Worker #ifndef STRESSAPPTEST_FINELOCK_QUEUE_H_
20*424fb153SAndroid Build Coastguard Worker #define STRESSAPPTEST_FINELOCK_QUEUE_H_
21*424fb153SAndroid Build Coastguard Worker 
22*424fb153SAndroid Build Coastguard Worker #include <string>
23*424fb153SAndroid Build Coastguard Worker 
24*424fb153SAndroid Build Coastguard Worker // This file must work with autoconf on its public version,
25*424fb153SAndroid Build Coastguard Worker // so these includes are correct.
26*424fb153SAndroid Build Coastguard Worker #include "sattypes.h"
27*424fb153SAndroid Build Coastguard Worker #include "pattern.h"
28*424fb153SAndroid Build Coastguard Worker #include "queue.h"     // Using page_entry struct.
29*424fb153SAndroid Build Coastguard Worker #include "os.h"
30*424fb153SAndroid Build Coastguard Worker 
31*424fb153SAndroid Build Coastguard Worker // This is a threadsafe randomized queue of pages with per-page entry lock
32*424fb153SAndroid Build Coastguard Worker // for worker threads to use.
33*424fb153SAndroid Build Coastguard Worker class FineLockPEQueue {
34*424fb153SAndroid Build Coastguard Worker  public:
35*424fb153SAndroid Build Coastguard Worker   FineLockPEQueue(uint64 queuesize, int64 pagesize);
36*424fb153SAndroid Build Coastguard Worker   ~FineLockPEQueue();
37*424fb153SAndroid Build Coastguard Worker 
38*424fb153SAndroid Build Coastguard Worker   // Put and get functions for page entries.
39*424fb153SAndroid Build Coastguard Worker   bool GetEmpty(struct page_entry *pe);
40*424fb153SAndroid Build Coastguard Worker   bool GetValid(struct page_entry *pe);
41*424fb153SAndroid Build Coastguard Worker   bool PutEmpty(struct page_entry *pe);
42*424fb153SAndroid Build Coastguard Worker   bool PutValid(struct page_entry *pe);
43*424fb153SAndroid Build Coastguard Worker 
44*424fb153SAndroid Build Coastguard Worker   // Put and get functions for page entries, selecting on tags.
45*424fb153SAndroid Build Coastguard Worker   bool GetEmpty(struct page_entry *pe, int32 tag);
46*424fb153SAndroid Build Coastguard Worker   bool GetValid(struct page_entry *pe, int32 tag);
47*424fb153SAndroid Build Coastguard Worker 
48*424fb153SAndroid Build Coastguard Worker   bool QueueAnalysis();
49*424fb153SAndroid Build Coastguard Worker   bool GetPageFromPhysical(uint64 paddr, struct page_entry *pe);
50*424fb153SAndroid Build Coastguard Worker   void set_os(OsLayer *os);
51*424fb153SAndroid Build Coastguard Worker   OsLayer::ErrCallback get_err_log_callback();
52*424fb153SAndroid Build Coastguard Worker   bool ErrorLogCallback(uint64 paddr, string *buf);
53*424fb153SAndroid Build Coastguard Worker 
54*424fb153SAndroid Build Coastguard Worker  private:
55*424fb153SAndroid Build Coastguard Worker   // Not that much blocking random number generator.
56*424fb153SAndroid Build Coastguard Worker   uint64 GetRandom64();
57*424fb153SAndroid Build Coastguard Worker   uint64 GetRandom64FromSlot(int slot);
58*424fb153SAndroid Build Coastguard Worker 
59*424fb153SAndroid Build Coastguard Worker   // Helper function to check index range, returns true if index is valid.
valid_index(int64 index)60*424fb153SAndroid Build Coastguard Worker   bool valid_index(int64 index) {
61*424fb153SAndroid Build Coastguard Worker     return index >= 0 && static_cast<uint64>(index) < q_size_;
62*424fb153SAndroid Build Coastguard Worker   }
63*424fb153SAndroid Build Coastguard Worker 
64*424fb153SAndroid Build Coastguard Worker   // Returns true if page entry is valid, false otherwise.
page_is_valid(struct page_entry * pe)65*424fb153SAndroid Build Coastguard Worker   static bool page_is_valid(struct page_entry *pe) {
66*424fb153SAndroid Build Coastguard Worker     return pe->pattern != NULL;
67*424fb153SAndroid Build Coastguard Worker   }
68*424fb153SAndroid Build Coastguard Worker   // Returns true if page entry is empty, false otherwise.
page_is_empty(struct page_entry * pe)69*424fb153SAndroid Build Coastguard Worker   static bool page_is_empty(struct page_entry *pe) {
70*424fb153SAndroid Build Coastguard Worker     return pe->pattern == NULL;
71*424fb153SAndroid Build Coastguard Worker   }
72*424fb153SAndroid Build Coastguard Worker 
73*424fb153SAndroid Build Coastguard Worker   // Helper function to get a random page entry with given predicate,
74*424fb153SAndroid Build Coastguard Worker   // ie, page_is_valid() or page_is_empty() as defined above.
75*424fb153SAndroid Build Coastguard Worker   bool GetRandomWithPredicate(struct page_entry *pe,
76*424fb153SAndroid Build Coastguard Worker                               bool (*pred_func)(struct page_entry*));
77*424fb153SAndroid Build Coastguard Worker 
78*424fb153SAndroid Build Coastguard Worker   // Helper function to get a random page entry with given predicate,
79*424fb153SAndroid Build Coastguard Worker   // ie, page_is_valid() or page_is_empty() as defined above.
80*424fb153SAndroid Build Coastguard Worker   bool GetRandomWithPredicateTag(struct page_entry *pe,
81*424fb153SAndroid Build Coastguard Worker                                  bool (*pred_func)(struct page_entry*),
82*424fb153SAndroid Build Coastguard Worker                                  int32 tag);
83*424fb153SAndroid Build Coastguard Worker 
84*424fb153SAndroid Build Coastguard Worker   // Used to make a linear congruential path through the queue.
85*424fb153SAndroid Build Coastguard Worker   int64 getA(int64 m);
86*424fb153SAndroid Build Coastguard Worker   int64 getC(int64 m);
87*424fb153SAndroid Build Coastguard Worker 
88*424fb153SAndroid Build Coastguard Worker   pthread_mutex_t *pagelocks_;  // Per-page-entry locks.
89*424fb153SAndroid Build Coastguard Worker   struct page_entry *pages_;     // Where page entries are held.
90*424fb153SAndroid Build Coastguard Worker   uint64 q_size_;                // Size of the queue.
91*424fb153SAndroid Build Coastguard Worker   int64 page_size_;              // For calculating array index from offset.
92*424fb153SAndroid Build Coastguard Worker 
93*424fb153SAndroid Build Coastguard Worker   enum {
94*424fb153SAndroid Build Coastguard Worker     kTries = 1,     // Measure the number of attempts in the queue
95*424fb153SAndroid Build Coastguard Worker                     // before getting a matching page.
96*424fb153SAndroid Build Coastguard Worker     kTouch = 2 }    // Measure the number of touches on each page.
97*424fb153SAndroid Build Coastguard Worker     queue_metric_;  // What to measure in the 'tries' field.
98*424fb153SAndroid Build Coastguard Worker 
99*424fb153SAndroid Build Coastguard Worker   // Progress pseudorandomly through the queue. It's required that we can find
100*424fb153SAndroid Build Coastguard Worker   // every value in the list, but progressing through the same order each time
101*424fb153SAndroid Build Coastguard Worker   // causes bunching of pages, leading to long seach times for the correct
102*424fb153SAndroid Build Coastguard Worker   // type of pages.
103*424fb153SAndroid Build Coastguard Worker   int64 a_;                      // 'a' multiplicative value for progressing
104*424fb153SAndroid Build Coastguard Worker                                  // linear congruentially through the list.
105*424fb153SAndroid Build Coastguard Worker   int64 c_;                      // 'c' additive value for prgressing randomly
106*424fb153SAndroid Build Coastguard Worker                                  // through the list.
107*424fb153SAndroid Build Coastguard Worker   int64 modlength_;              // 'm' mod value for linear congruential
108*424fb153SAndroid Build Coastguard Worker                                  // generator. Used when q_size_ doesn't
109*424fb153SAndroid Build Coastguard Worker                                  // generate a good progression through the
110*424fb153SAndroid Build Coastguard Worker                                  // list.
111*424fb153SAndroid Build Coastguard Worker 
112*424fb153SAndroid Build Coastguard Worker   uint64 rand_seed_[4];          // Random number state for 4 generators.
113*424fb153SAndroid Build Coastguard Worker   pthread_mutex_t randlocks_[4];  // Per-random-generator locks.
114*424fb153SAndroid Build Coastguard Worker 
115*424fb153SAndroid Build Coastguard Worker   DISALLOW_COPY_AND_ASSIGN(FineLockPEQueue);
116*424fb153SAndroid Build Coastguard Worker };
117*424fb153SAndroid Build Coastguard Worker 
118*424fb153SAndroid Build Coastguard Worker #endif  // STRESSAPPTEST_FINELOCK_QUEUE_H_
119