* Copyright (c) 2015-2023 Google, Inc. All rights reserved.
* **********************************************************/
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* * Neither the name of Google, Inc. nor the names of its contributors may be
* used to endorse or promote products derived from this software without
* specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL VMWARE, INC. OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
* DAMAGE.
*/
*/
#ifndef _SIMULATOR_H_
#define _SIMULATOR_H_ 1
#include <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <unordered_map>
#include <vector>
#include "analysis_tool.h"
#include "caching_device.h"
#include "caching_device_stats.h"
#include "memref.h"
#include "trace_entry.h"
namespace dynamorio {
namespace drmemtrace {
class simulator_t : public analysis_tool_t {
public:
simulator_t()
{
}
simulator_t(unsigned int num_cores, uint64_t skip_refs, uint64_t warmup_refs,
double warmup_fraction, uint64_t sim_refs, bool cpu_scheduling,
bool use_physical, unsigned int verbose);
virtual ~simulator_t() = 0;
bool
process_memref(const memref_t &memref) override;
protected:
void
init_knobs(unsigned int num_cores, uint64_t skip_refs, uint64_t warmup_refs,
double warmup_fraction, uint64_t sim_refs, bool cpu_scheduling,
bool use_physical, unsigned int verbose);
void
print_core(int core) const;
int
find_emptiest_core(std::vector<int> &counts) const;
virtual int
core_for_thread(memref_tid_t tid);
virtual void
handle_thread_exit(memref_tid_t tid);
addr_t
virt2phys(addr_t virt) const;
memref_t
memref2phys(memref_t memref) const;
addr_t
page_start(addr_t addr) const
{
assert(page_size_ > 0);
return addr & ~(page_size_ - 1);
}
addr_t
synthetic_virt2phys(addr_t virt) const;
unsigned int knob_num_cores_;
uint64_t knob_skip_refs_;
uint64_t knob_warmup_refs_;
double knob_warmup_fraction_;
uint64_t knob_sim_refs_;
bool knob_cpu_scheduling_;
bool knob_use_physical_;
unsigned int knob_verbose_;
memref_tid_t last_thread_;
int last_core_;
std::unordered_map<int, int> cpu2core_;
std::unordered_map<memref_tid_t, int> thread2core_;
std::vector<int> cpu_counts_;
std::vector<int> thread_counts_;
std::vector<int> thread_ever_counts_;
size_t page_size_ = 0;
std::unordered_map<addr_t, addr_t> virt2phys_;
addr_t prior_phys_addr_ = 0;
};
}
}
#endif