blob: 3a70bd120b2ba48dcf171f85d49148b67e7235e0 [file] [log] [blame]
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
// This file provides the PageFaultSimulation class.
#ifndef SYZYGY_SIMULATE_PAGE_FAULT_SIMULATION_H_
#define SYZYGY_SIMULATE_PAGE_FAULT_SIMULATION_H_
#include "syzygy/simulate/simulation_event_handler.h"
#include "syzygy/trace/parse/parser.h"
namespace simulate {
// An implementation of SimulationEventHandler. PageFaultSimulation simply
// counts the total number of page-faults that happen in the specified
// functions. Sample usage:
//
// PageFaultSimulation simulation;
//
// simulation.set_page_size(0x2000);
// simulation.set_pages_per_code_fault(10);
// simulation.OnProcessStarted(time, 0);
// simulation.OnFunctionEntry(time, 5);
// simulation.OnFunctionEntry(time, 200);
// simulator.SerializeToJSON(file, pretty_print);
//
// If the pages per code fault are not set, then the default value of
// 8 is used.
//
// If the page size is not set, then it's deduced from the trace file data
// or, if that's not possible, it's set to the default value of 0x1000 (4 KB).
class PageFaultSimulation : public SimulationEventHandler {
public:
typedef block_graph::BlockGraph::Block Block;
typedef std::set<uint32_t> PageSet;
// The default page size, in case neither the user nor the system
// provide one.
static const size_t kDefaultPageSize = 0x1000;
// The default number of pages loaded on each code-fault.
static const size_t kDefaultPagesPerCodeFault = 8;
// Constructs a new PageFaultSimulation instance.
PageFaultSimulation();
// @name Accessors
// @{
const PageSet& pages() const { return pages_; }
size_t fault_count() const { return fault_count_; }
size_t page_size() const { return page_size_; }
size_t pages_per_code_fault() const { return pages_per_code_fault_; }
// @}
// @name Mutators
// @{
void set_page_size(size_t page_size) {
DCHECK(page_size > 0);
page_size_ = page_size;
}
void set_pages_per_code_fault(size_t pages_per_code_fault) {
DCHECK(pages_per_code_fault > 0);
pages_per_code_fault_ = pages_per_code_fault;
}
// @}
// @name SimulationEventHandler implementation
// @{
// Sets the initial page size, if it's not set already.
void OnProcessStarted(base::Time time, size_t default_page_size) override;
// Registers the page faults, given a certain code block.
void OnFunctionEntry(base::Time time, const Block* block) override;
// The serialization consists of a single dictionary containing
// the block number of each block that pagefaulted.
bool SerializeToJSON(FILE* output, bool pretty_print) override;
// @}
protected:
// A set which contains the block number of the pages that
// were faulted in the trace files.
PageSet pages_;
// The total number of page-faults detected.
size_t fault_count_;
// The size of each page, in bytes. If not set, PageFaultSimulator will
// try to load the system value, or uses kDefaultPageSize
// if it's unavailable.
size_t page_size_;
// The number of pages each code-fault loads. If not set,
// PageFaultSimulator uses kDefaultPagesPerFault.
size_t pages_per_code_fault_;
};
} // namespace simulate
#endif // SYZYGY_SIMULATE_PAGE_FAULT_SIMULATION_H_