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