<commit_before>#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <functional>

using namespace std;

namespace {

namespace io {

enum token_type {
  REG,
  NN
};

ofstream outfile;
ifstream infile;

void exit_ok() {
  infile.close();
  outfile.close();
  exit(0);
}

void exit_err(string const& error) {
  cerr << error;
  infile.close();
  outfile.close();
  exit(1);
}

void write_bins(char lhs, char rhs) {
  outfile.write(static_cast<char*>(&lhs), 1);
  outfile.write(static_cast<char*>(&rhs), 1);
  if (outfile.fail()) {
    exit_err("Error writing to disk");
  }
}

int xtoi(string const& x) {
  try {
    return stoi(x, 0, 16);
  } catch (exception &e) {
    return -1;
  }
}

string next_token() {
  string value;
  io::infile >> value;
  if (!io::infile) {
    io::exit_ok();
  }
  return value;
}

void tok2n(string const& name, string&& value, char& n) {
  int target = xtoi(value);
  if (0 > target || 0xF < target) {
    exit_err("Error: " + name + " needs to be supplied with a value [0-F]\n");
  }
  n = target;
}

void tok2nn(string const& name, string&& value, char& nn) {
  int target = xtoi(value);
  if (0 > target || 0xFF < target) {
    exit_err("Error: " + name + " needs to be supplied with a value [0-FF]\n");
  }
  nn = target;
}

void tok2nnn(string const& name, string&& value, char& lhs, char& rhs) {
  int target = xtoi(value);
  if (0 > target || 0xFFF < target) {
    exit_err("Error: " + name + " needs to be supplied with a value [0-FFF]\n");
  }
  lhs = target >> 8;
  rhs = target & 0xFF;
}

void tok2reg(string const& name, string&& value, char& reg) {
  if (value.at(0) != 'r') {
    exit_err("Error: " + name + " needs to be supplied with a register r[0-F]\n");
  }

  int target = xtoi(value.substr(1));
  if (0 > target || 0xF < target) {
    exit_err("Error: " + name + " needs to be supplied with a register r[0-F]\n");
  }
  reg = target;
}

void tok2reg_or_nn(string const& name, string&& value, char& reg_or_nn, io::token_type& t) {
  if (value.at(0) == 'r') {
    t = REG;
    tok2reg(name, forward<string>(value), reg_or_nn);
  } else {
    t = NN;
    tok2nn(name, forward<string>(value), reg_or_nn);
  }
}

} // io

namespace op {

// These variables are shared between all below functions
char lhs;
char rhs;
char rhs2;
io::token_type t;

void CLS() { io::write_bins(0x00, 0xE0); }

void RET() { io::write_bins(0x00, 0xEE); }

void JMP() {
  io::tok2nnn("JMP", io::next_token(), lhs, rhs);
  io::write_bins(0x10 + lhs, rhs);
}

void CALL() {
  io::tok2nnn("CALL", io::next_token(), lhs, rhs);
  io::write_bins(0x20 + lhs, rhs);
}

void IFN() {
  io::tok2reg("IFN", io::next_token(), lhs);
  io::tok2reg_or_nn("IFN", io::next_token(), rhs, t);
  if (t == io::NN)       { io::write_bins(0x30 + lhs, rhs); }
  else if (t == io::REG) { io::write_bins(0x50 + lhs, rhs << 4); }
  else                   { io::exit_err("IFN: Unknown type\n"); }
}

void IF() {
  io::tok2reg("IF", io::next_token(), lhs);
  io::tok2reg_or_nn("IF", io::next_token(), rhs, t);
  if (t == io::NN)       { io::write_bins(0x40 + lhs, rhs); }
  else if (t == io::REG) { io::write_bins(0x90 + lhs, (rhs << 4) + 0x04); }
  else                   { io::exit_err("IF: Unknown type\n"); }
}

void SET() {
  io::tok2reg("SET", io::next_token(), lhs);
  io::tok2reg_or_nn("SET", io::next_token(), rhs, t);
  if (t == io::NN)       { io::write_bins(0x60 + lhs, rhs); }
  else if (t == io::REG) { io::write_bins(0x80 + lhs, rhs << 4); }
  else                   { io::exit_err("SET: Unknown type\n");
  }
}

void ADD() {
  io::tok2reg("ADD", io::next_token(), lhs);
  io::tok2reg_or_nn("ADD", io::next_token(), rhs, t);
  if (t == io::NN)       { io::write_bins(0x70 + lhs, rhs); }
  else if (t == io::REG) { io::write_bins(0x80 + lhs, (rhs << 4) + 0x04); }
  else                   { io::exit_err("ADD: Unknown type\n"); }
}

void OR() {
  io::tok2reg("OR", io::next_token(), lhs);
  io::tok2reg("OR", io::next_token(), rhs);
  io::write_bins(0x80 + lhs, (rhs << 4) + 0x01);
}

void AND() {
  io::tok2reg("AND", io::next_token(), lhs);
  io::tok2reg("AND", io::next_token(), rhs);
  io::write_bins(0x80 + lhs, (rhs << 4) + 0x02);
}

void XOR() {
  io::tok2reg("XOR", io::next_token(), lhs);
  io::tok2reg("XOR", io::next_token(), rhs);
  io::write_bins(0x80 + lhs, (rhs << 4) + 0x03);
}

void SUB() {
  io::tok2reg("SUB", io::next_token(), lhs);
  io::tok2reg("SUB", io::next_token(), rhs);
  io::write_bins(0x80 + lhs, (rhs << 4) + 0x05);
}

void SHR() {
  io::tok2reg("SHR", io::next_token(), lhs);
  io::tok2reg("SHR", io::next_token(), rhs);
  io::write_bins(0x80 + lhs, (rhs << 4) + 0x06);
}

void RSUB() {
  io::tok2reg("RSUB", io::next_token(), lhs);
  io::tok2reg("RSUB", io::next_token(), rhs);
  io::write_bins(0x80 + lhs, (rhs << 4) + 0x07);
}

void SHL() {
  io::tok2reg("SHL", io::next_token(), lhs);
  io::tok2reg("SHL", io::next_token(), rhs);
  io::write_bins(0x80 + lhs, (rhs << 4) + 0x0E);
}

void IDX() {
  io::tok2nnn("IDX", io::next_token(), lhs, rhs);
  io::write_bins(0xA0 + lhs, rhs);
}

void JMP0() {
  io::tok2nnn("JMP0", io::next_token(), lhs, rhs);
  io::write_bins(0xB0 + lhs, rhs);
}

void RND() {
  io::tok2reg("RND", io::next_token(), lhs);
  io::tok2nn("RND", io::next_token(), rhs);
  io::write_bins(0xC0 + lhs, rhs);
}

void DRAW() {
  io::tok2reg("DRAW", io::next_token(), lhs);
  io::tok2reg("DRAW", io::next_token(), rhs);
  io::tok2n("DRAW", io::next_token(), rhs2);
  io::write_bins(0xD0 + lhs, (rhs << 4) + rhs2);
}

void IFK() {
  io::tok2reg("IFK", io::next_token(), lhs);
  io::write_bins(0xE0 + lhs, 0x9E);
}

void IFNK() {
  io::tok2reg("IFNK", io::next_token(), lhs);
  io::write_bins(0xE0 + lhs, 0xA1);
}

void GDEL() {
  io::tok2reg("GDEL", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x07);
}

void WKEY() {
  io::tok2reg("WKEY", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x0A);
}

void SDEL() {
  io::tok2reg("SDEL", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x15);
}

void SAUD() {
  io::tok2reg("SAUD", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x18);
}

void IADD() {
  io::tok2reg("IADD", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x1E);
}

void CHAR() {
  io::tok2reg("CHAR", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x29);
}

void SEP() {
  io::tok2reg("SEP", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x33);
}

void STOR() {
  io::tok2reg("STOR", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x55);
}

void LOAD() {
  io::tok2reg("LOAD", io::next_token(), lhs);
  io::write_bins(0xF0 + lhs, 0x65);
}

} // op

int help(string program_name) {
  cerr
    << "Usage: " << program_name << " FILE\n\n"
    << "Available commands\n"
    << "CLS          - 0x00E0\n"
    << "RET          - 0x00EE\n"
    << "JMP  NNN     - 0x1NNN\n"
    << "CALL NNN     - 0x2NNN\n"
    << "IFN  rX  NN  - 0x3XNN\n"
    << "IF   rX  NN  - 0x4XNN\n"
    << "IFN  rX  rY  - 0x5XY0\n"
    << "SET  rX  NN  - 0x6XNN\n"
    << "ADD  rX  NN  - 0x7XNN\n"
    << "SET  rX  rY  - 0x8XY0\n"
    << "OR   rX  rY  - 0x8XY1\n"
    << "AND  rX  rY  - 0x8XY2\n"
    << "XOR  rX  rY  - 0x8XY3\n"
    << "ADD  rX  rY  - 0x8XY4\n"
    << "SUB  rX  rY  - 0x8XY5\n"
    << "SHR  rX  rY  - 0x8XY6\n"
    << "RSUB rX  rY  - 0x8XY7\n"
    << "SHL  rX  rY  - 0x8XYE\n"
    << "IF   rX  rY  - 0x9XY0\n"
    << "IDX  NNN     - 0xANNN\n"
    << "JMP0 NNN     - 0xBNNN\n"
    << "RND  rX NN   - 0xCXNN\n"
    << "DRAW rX rY N - 0xDXYN\n"
    << "IFK  rX      - 0xEX9E\n"
    << "IFNK rX      - 0xEXA1\n"
    << "GDEL rX      - 0xFX07\n"
    << "WKEY rX      - 0xFX0A\n"
    << "SDEL rX      - 0xFX15\n"
    << "SAUD rX      - 0xFX18\n"
    << "IADD rX      - 0xFX1E\n"
    << "CHAR rX      - 0xFX29\n"
    << "SEP  rX      - 0xFX33\n"
    << "STOR rX  rY  - 0xFX55\n"
    << "LOAD rX  rY  - 0xFX65\n";

  return 1;
}

} // anonymous namespace

int main(int argc, char* argv[]) {
  if (argc != 2 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
    return help(argv[0]);
  }

  io::infile = ifstream(argv[1], ios::binary);
  if (!io::infile) {
    cerr << argv[0] << ": Unable to open " << argv[1] << "\n";
    return 1;
  }

  stringstream ss;
  ss << argv[1] << ".out";
  string const outfile_name{ss.str()};
  io::outfile = ofstream(outfile_name, ios::binary);
  if (!io::outfile) {
    cerr << argv[0] << ": Unable to open " << outfile_name << "\n";
    return 1;
  }

  map<string const, function<void()>> const op2fun {
    {"CLS",  op::CLS},
    {"RET",  op::RET},
    {"JMP",  op::JMP},
    {"CALL", op::CALL},
    {"IFN",  op::IFN},
    {"IF",   op::IF},
    {"SET",  op::SET},
    {"ADD",  op::ADD},
    {"OR",   op::OR},
    {"AND",  op::AND},
    {"XOR",  op::XOR},
    {"SUB",  op::SUB},
    {"SHR",  op::SHR},
    {"RSUB", op::RSUB},
    {"SHL",  op::SHL},
    {"IDX",  op::IDX},
    {"JMP0", op::JMP0},
    {"RND",  op::RND},
    {"DRAW", op::DRAW},
    {"IFK",  op::IFK},
    {"IFNK", op::IFNK},
    {"GDEL", op::GDEL},
    {"WKEY", op::WKEY},
    {"SDEL", op::SDEL},
    {"SAUD", op::SAUD},
    {"IADD", op::IADD},
    {"CHAR", op::CHAR},
    {"SEP",  op::SEP},
    {"STOR", op::STOR},
    {"LOAD", op::LOAD},
  };

  for (;;) {
    // This constructor will exit when no more input is received
    string const tok{io::next_token()};

    auto const fun{op2fun.find(tok)};
    if (fun == op2fun.end()) {
      io::exit_err("Unknown command '" + tok + "'\n");
    }

    fun->second();
  }

  // Not reached
}
<commit_msg>Use of bind for less code reuse<commit_after>#include <iostream>
#include <fstream>
#include <sstream>
#include <map>
#include <functional>

using namespace std;

namespace {

namespace io {

enum token_type {
  REG,
  NN
};

ofstream outfile;
ifstream infile;

void exit_ok() {
  infile.close();
  outfile.close();
  exit(0);
}

void exit_err(string const& error) {
  cerr << error;
  infile.close();
  outfile.close();
  exit(1);
}

void write_bins(char lhs, char rhs) {
  outfile.write(static_cast<char*>(&lhs), 1);
  outfile.write(static_cast<char*>(&rhs), 1);
  if (outfile.fail()) {
    exit_err("Error writing to disk");
  }
}

int xtoi(string const& x) {
  try {
    return stoi(x, 0, 16);
  } catch (exception &e) {
    return -1;
  }
}

string next_token() {
  string value;
  io::infile >> value;
  if (!io::infile) {
    io::exit_ok();
  }
  return value;
}

void tok2n(string const& name, string&& value, char& n) {
  int target = xtoi(value);
  if (0 > target || 0xF < target) {
    exit_err("Error: " + name + " needs to be supplied with a value [0-F]\n");
  }
  n = target;
}

void tok2nn(string const& name, string&& value, char& nn) {
  int target = xtoi(value);
  if (0 > target || 0xFF < target) {
    exit_err("Error: " + name + " needs to be supplied with a value [0-FF]\n");
  }
  nn = target;
}

void tok2nnn(string const& name, string&& value, char& lhs, char& rhs) {
  int target = xtoi(value);
  if (0 > target || 0xFFF < target) {
    exit_err("Error: " + name + " needs to be supplied with a value [0-FFF]\n");
  }
  lhs = target >> 8;
  rhs = target & 0xFF;
}

void tok2reg(string const& name, string&& value, char& reg) {
  if (value.at(0) != 'r') {
    exit_err("Error: " + name + " needs to be supplied with a register r[0-F]\n");
  }

  int target = xtoi(value.substr(1));
  if (0 > target || 0xF < target) {
    exit_err("Error: " + name + " needs to be supplied with a register r[0-F]\n");
  }
  reg = target;
}

void tok2reg_or_nn(string const& name, string&& value, char& reg_or_nn, io::token_type& t) {
  if (value.at(0) == 'r') {
    t = REG;
    tok2reg(name, forward<string>(value), reg_or_nn);
  } else {
    t = NN;
    tok2nn(name, forward<string>(value), reg_or_nn);
  }
}

} // io

namespace op {

// These variables are shared between all below functions
char lhs;
char rhs;
char rhs2;
io::token_type t;

inline void OP(char lhs, char rhs) { io::write_bins(lhs, rhs); }

inline void R(string const& name, char lop, char rop) {
  io::tok2reg(name, io::next_token(), lhs);
  io::write_bins(lop + lhs, rop);
}

inline void RR(string const& name, char lop, char rop) {
  io::tok2reg(name, io::next_token(), lhs);
  io::tok2reg(name, io::next_token(), rhs);
  io::write_bins(lop + lhs, (rhs << 4) + rop);
}

inline void NNN(string const& name, char op) {
  io::tok2nnn(name, io::next_token(), lhs, rhs);
  io::write_bins(op + lhs, rhs);
}

inline void RNN(string const& name, char lop) {
  io::tok2reg(name, io::next_token(), lhs);
  io::tok2nn(name, io::next_token(), rhs);
  io::write_bins(lop + lhs, rhs);
}

inline void RRN(string const& name, char lop) {
  io::tok2reg(name, io::next_token(), lhs);
  io::tok2reg(name, io::next_token(), rhs);
  io::tok2n(name, io::next_token(), rhs2);
  io::write_bins(lop + lhs, (rhs << 4) + rhs2);
}

inline void RV(string const& name, char nnop, char rlop, char rrop) {
  io::tok2reg(name, io::next_token(), lhs);
  io::tok2reg_or_nn(name, io::next_token(), rhs, t);
  if (t == io::NN)       { io::write_bins(nnop + lhs, rhs); }
  else if (t == io::REG) { io::write_bins(rlop + lhs, (rhs << 4) + rrop); }
  else                   { io::exit_err(name + ": Unknown type\n"); }
}

} // op

int help(string program_name) {
  cerr
    << "Usage: " << program_name << " FILE\n\n"
    << "Available commands\n"
    << "CLS          - 0x00E0\n"
    << "RET          - 0x00EE\n"
    << "JMP  NNN     - 0x1NNN\n"
    << "CALL NNN     - 0x2NNN\n"
    << "IFN  rX  NN  - 0x3XNN\n"
    << "IF   rX  NN  - 0x4XNN\n"
    << "IFN  rX  rY  - 0x5XY0\n"
    << "SET  rX  NN  - 0x6XNN\n"
    << "ADD  rX  NN  - 0x7XNN\n"
    << "SET  rX  rY  - 0x8XY0\n"
    << "OR   rX  rY  - 0x8XY1\n"
    << "AND  rX  rY  - 0x8XY2\n"
    << "XOR  rX  rY  - 0x8XY3\n"
    << "ADD  rX  rY  - 0x8XY4\n"
    << "SUB  rX  rY  - 0x8XY5\n"
    << "SHR  rX  rY  - 0x8XY6\n"
    << "RSUB rX  rY  - 0x8XY7\n"
    << "SHL  rX  rY  - 0x8XYE\n"
    << "IF   rX  rY  - 0x9XY0\n"
    << "IDX  NNN     - 0xANNN\n"
    << "JMP0 NNN     - 0xBNNN\n"
    << "RND  rX NN   - 0xCXNN\n"
    << "DRAW rX rY N - 0xDXYN\n"
    << "IFK  rX      - 0xEX9E\n"
    << "IFNK rX      - 0xEXA1\n"
    << "GDEL rX      - 0xFX07\n"
    << "WKEY rX      - 0xFX0A\n"
    << "SDEL rX      - 0xFX15\n"
    << "SAUD rX      - 0xFX18\n"
    << "IADD rX      - 0xFX1E\n"
    << "CHAR rX      - 0xFX29\n"
    << "SEP  rX      - 0xFX33\n"
    << "STOR rX      - 0xFX55\n"
    << "LOAD rX      - 0xFX65\n";

  return 1;
}

} // anonymous namespace

int main(int argc, char* argv[]) {
  if (argc != 2 || !strcmp(argv[1], "--help") || !strcmp(argv[1], "-h")) {
    return help(argv[0]);
  }

  io::infile = ifstream(argv[1], ios::binary);
  if (!io::infile) {
    cerr << argv[0] << ": Unable to open " << argv[1] << "\n";
    return 1;
  }

  stringstream ss;
  ss << argv[1] << ".out";
  string const outfile_name{ss.str()};
  io::outfile = ofstream(outfile_name, ios::binary);
  if (!io::outfile) {
    cerr << argv[0] << ": Unable to open " << outfile_name << "\n";
    return 1;
  }

  map<string const, function<void()>> const op2fun {
    {"CLS",  bind(op::OP,   0x00, 0xE0) },
    {"RET",  bind(op::OP,   0x00, 0xEE) },
    {"JMP",  bind(op::NNN, "JMP", 0x10)},
    {"CALL", bind(op::NNN,"CALL", 0x20)},
    {"IFN",  bind(op::RV,  "IFN", 0x30, 0x50, 0x00)},
    {"IF",   bind(op::RV,  "IFN", 0x40, 0x90, 0x00)},
    {"SET",  bind(op::RV,  "IFN", 0x60, 0x80, 0x00)},
    {"ADD",  bind(op::RV,  "IFN", 0x70, 0x80, 0x04)},
    {"OR",   bind(op::RR,   "OR", 0x80, 0x01)},
    {"AND",  bind(op::RR,  "AND", 0x80, 0x02)},
    {"XOR",  bind(op::RR,  "XOR", 0x80, 0x03)},
    {"SUB",  bind(op::RR,  "SUB", 0x80, 0x05)},
    {"SHR",  bind(op::RR,  "SHR", 0x80, 0x06)},
    {"RSUB", bind(op::RR, "RSUB", 0x80, 0x07)},
    {"SHL",  bind(op::RR,  "SHL", 0x80, 0x0E)},
    {"IDX",  bind(op::NNN, "IDX", 0xA0)},
    {"JMP0", bind(op::NNN,"JMP0", 0xB0)},
    {"RND",  bind(op::RNN, "RND", 0xC0)},
    {"DRAW", bind(op::RRN,"DRAW", 0xD0)},
    {"IFK",  bind(op::R,   "IFK", 0xE0, 0x9E)},
    {"IFNK", bind(op::R,  "IFNK", 0xE0, 0xA1)},
    {"GDEL", bind(op::R,  "GDEL", 0xF0, 0x07)},
    {"WKEY", bind(op::R,  "WKEY", 0xF0, 0x0A)},
    {"SDEL", bind(op::R,  "SDEL", 0xF0, 0x15)},
    {"SAUD", bind(op::R,  "SAUD", 0xF0, 0x18)},
    {"IADD", bind(op::R,  "IADD", 0xF0, 0x1E)},
    {"CHAR", bind(op::R,  "CHAR", 0xF0, 0x29)},
    {"SEP",  bind(op::R,   "SEP", 0xF0, 0x33)},
    {"STOR", bind(op::R,  "STOR", 0xF0, 0x55)},
    {"LOAD", bind(op::R,  "LOAD", 0xF0, 0x65)},
  };

  for (;;) {
    // This constructor will exit when no more input is received
    string const tok{io::next_token()};

    auto const fun{op2fun.find(tok)};
    if (fun == op2fun.end()) {
      io::exit_err("Unknown command '" + tok + "'\n");
    }

    fun->second();
  }

  // Not reached
}
<|endoftext|>


<commit_before>//GP.cpp
#include "../headers/GP.hpp"

#include <cstdlib>
#include <iostream>

GP::GP(int popSize, int maxDepth, int numberOfXs){

    this->popSize = popSize;
    this->maxDepth = maxDepth;
    this->numberOfXs = numberOfXs;

    ramped_halfhalf();
}

GP::~GP(){
    for(int i=population.size() -1; i>=0; i--) {
        population.pop_back();
    }
}

void GP::ramped_halfhalf(){

    for (int i=1; i< (popSize+1); i++){
        population.push_back(new Individual(i%2==0, maxDepth, numberOfXs));
        if (i % (popSize/5)==0) this->maxDepth= this->maxDepth + 1;
    }
}

void GP::print_GP_d(){
    for (int i=0; i<population.size(); i++){
        population[i]->print_expression_d();
        std::cout << std::endl;
    }
}

void GP::print_GP_fitness_d(){
    for (int i=0; i<popSize; i++){
        population[i]->print_fitness_d();
    }
}

void GP::calculate_fitness(std::vector<utils::DataPoint> points){
    for (int i=0; i<popSize; i++){
        population[i]->fitness(points);
    }
}
<commit_msg>1.3 Mutação e crossover<commit_after>//GP.cpp
#include <cstdlib>
#include <iostream>
#include <math.h>

#include "../headers/GP.hpp"

using namespace utils;

    //--------------------CONSTRUTOR E DESTRUTOR--------------------------//

GP::GP(int popSize, int maxDepth, int numberOfXs){

    //construtor salva internamente as configurações da população e
    //chama o método que cria a população ramped_halfhalf
    this->popSize = popSize;
    this->maxDepth = maxDepth;
    this->numberOfXs = numberOfXs;

    ramped_halfhalf();

    this->bestOfAllTimes = population[0]->get_copy();
}

GP::~GP(){

    //destrutor. precisa limpar o conjunto inteiro de individuos da
    //população. o pop_back chama o destrutor dos itens retirados
    //automaticamente.

    for(int i=population.size() -1; i>=0; i--) {
        population.pop_back();
    }
}

    //---------------MÉTODOS DE MANIPULAÇÃO DA POPULAÇÃO//----------------//

void GP::ramped_halfhalf(){

    //cria a população no modo ramped_halfhalf. Nesse esquema, metade
    //da população é criada no estilo grow e metade no estilo full; e
    //a cada N/5 individuos a profundidade máxima é aumentada em 1.
    int auxMaxDepth = this->maxDepth;

    for (int i=1; i< (popSize+1); i++){
        population.push_back(new Individual(i%2==0, auxMaxDepth, numberOfXs));
        if (i % (popSize/5)==0) auxMaxDepth++;
    }
}

void GP::calculate_fitness(std::vector<utils::DataPoint> points){

    //recebe o vector que contém os pontos utilizados no fitness e
    //atualiza os valores dos fitness de todos os individuos.

    for (int i=0; i<popSize; i++){
        population[i]->fitness(points);
        if (population[i]->get_fitness() < bestOfAllTimes->get_fitness()){
            delete bestOfAllTimes;
            bestOfAllTimes = population[i]->get_copy();
        }
    }
}

void GP::mutate_population(double mutation_rate){
    for (int i=0; i<popSize; i++){
        population[i]->mutation(mutation_rate);
    }
}

void GP::tournament_selection_tester(std::vector<utils::DataPoint> points){
    //tournament de teste

    vector<Individual *> selectedPop;
    vector<Individual *> Pfilhos;

    int auxMaxDepth = this->maxDepth;

    for (int i=1; i< (popSize+1); i++){
        Pfilhos.push_back(new Individual(i%2==0, auxMaxDepth, numberOfXs));
        if (i % (popSize/5)==0) auxMaxDepth++;
    }

    calculate_fitness(points);

    for (int i=0; i<popSize; i++){
        Pfilhos[i]->fitness(points);
    }

    for (int i=0; i<popSize; i++){

        int index1, index2;
        double fit1, fit2;

        do {
            index1 = random()% population.size();
            index2 = random()% Pfilhos.size();

            fit1 = population[index1]->get_fitness();
            fit2 = Pfilhos[index2]->get_fitness();
        } while ( (fit1 !=fit1) && (fit2 != fit2) );

        if (fit1<fit2)
            selectedPop.push_back(population[index1]->get_copy());
        else
            selectedPop.push_back(Pfilhos[index2]->get_copy());
    }
    population.clear();
    Pfilhos.clear();

    for (int i=0; i<popSize; i++){
        population.push_back(selectedPop[i]->get_copy());
    }
    selectedPop.clear();
}

void GP::tournament_selection(std::vector<utils::DataPoint> points){
    vector<Individual *> selectedPop;

    calculate_fitness(points);

    for (int i=0; i<popSize; i++){

        int index1, index2;
        double fit1, fit2;

        do {
            index1 = random()% population.size();
            index2 = random()% population.size();

            fit1 = population[index1]->get_fitness();
            fit2 = population[index2]->get_fitness();
        } while ( (fit1 !=fit1) && (fit2 != fit2) );

        if (fit1<fit2)
            selectedPop.push_back(population[index1]->get_copy());
        else
            selectedPop.push_back(population[index2]->get_copy());
    }
    population.clear();

    for (int i=0; i<popSize; i++){
        population.push_back(selectedPop[i]->get_copy());
    }
    selectedPop.clear();
}

void GP::crossover_halfhalf(double crossover_rate){
    vector<Individual *> crossedPop;

    while (crossedPop.size()<popSize){
        crossedPop.push_back(population[random()%popSize]->crossover(crossover_rate, population[random()%popSize]));
    }

    population.clear();

    for (int i=0; i<popSize; i++){
        population.push_back(crossedPop[i]->get_copy());
    }
    crossedPop.clear();
}

    //----------------------MÉTODOS DE DEBUG------------------------------//

void GP::print_GP_d(){

    //imprime a expressão de cada um dos individuos da população.

    for (int i=0; i<population.size(); i++){
        population[i]->print_expression_d();
        std::cout << std::endl;
    }
}

void GP::print_GP_fitness_d(){

    //imprime o fitness de daca um dos individuos da população.

    for (int i=0; i<popSize; i++){
        std::cout << population[i]->get_fitness() << std::endl;
    }
}

void GP::print_GP_best_fitness_d(){

    double best_mse = this->population[0]->get_fitness();
    int best_eq = 0;

    for (int i=1; i<popSize; i++){
        if (population[i]->get_fitness() < best_mse) {
            best_mse = population[i]->get_fitness();
            best_eq = i ;
        }
    }
    cout << best_mse << "; expressão: ";
    population[best_eq]->expression->print_node_d();
    cout << endl;
}

void GP::printAndCompare_GP_bestOfAllTimes(std::vector<utils::DataPoint> points){
    cout << "O melhor de todos:";
    bestOfAllTimes->print_expression_d();
    cout << "VALOR DA ENTRADA\tVALOR DO MELHOR DE TODOS OS TEMPOS" << endl;
    for (int i=0; i<points.size(); i++){
        cout << points[i].y << "\t" << bestOfAllTimes->expression->eval(points[i]) << endl;
    }
}
<|endoftext|>


<commit_before>// Copyright Daniel Wallin 2008. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP
#  define LUABIND_DEDUCE_SIGNATURE_080911_HPP

#  include <luabind/detail/most_derived.hpp>

#  include <boost/function_types/components.hpp>
#  include <boost/function_types/is_callable_builtin.hpp>
#  include <boost/function_types/is_member_function_pointer.hpp>
#  include <boost/type_traits/add_reference.hpp>
#  include <boost/utility/enable_if.hpp>

namespace luabind { namespace detail {

namespace mpl = boost::mpl;
namespace fty = boost::function_types;

template <class F, class Enable=void>
struct signature_aux
{
    typedef F type;
};

// Handle boost::function and std::function:
template <template<class> class F, class S>
struct signature_aux<
    F<S>,
    typename mpl::apply< // Enable only if F<S>::result_type exists.
        mpl::always<void>, typename F<S>::result_type>::type >
{
    typedef S type;
};

template <typename F>
struct is_function:
    fty::is_callable_builtin<typename signature_aux<F>::type>
{};

template <class F>
typename boost::enable_if<
    is_function<F>,
    fty::components<typename signature_aux<F>::type> >::type
deduce_signature(F const&, ...)
{
    return fty::components<typename signature_aux<F>::type>();
}

template <class F, class Wrapped>
typename boost::enable_if<
    fty::is_member_function_pointer<typename signature_aux<F>::type>,
    fty::components<
        typename signature_aux<F>::type,
        boost::add_reference<most_derived<mpl::_1, Wrapped> > > >::type
deduce_signature(F, Wrapped*)
{
    return fty::components<
        typename signature_aux<F>::type,
        boost::add_reference<most_derived<mpl::_1, Wrapped> > >();
}

} } // namespace luabind::detail

#endif  // LUABIND_DEDUCE_SIGNATURE_080911_HPP
<commit_msg>Fix recognition of const std::/boost::functions.<commit_after>// Copyright Daniel Wallin 2008. Use, modification and distribution is
// subject to the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

# ifndef LUABIND_DEDUCE_SIGNATURE_080911_HPP
#  define LUABIND_DEDUCE_SIGNATURE_080911_HPP

#  include <luabind/detail/most_derived.hpp>

#  include <boost/function_types/components.hpp>
#  include <boost/function_types/is_callable_builtin.hpp>
#  include <boost/function_types/is_member_function_pointer.hpp>
#  include <boost/type_traits/add_reference.hpp>
#  include <boost/utility/enable_if.hpp>

namespace luabind { namespace detail {

namespace mpl = boost::mpl;
namespace fty = boost::function_types;

template <class F, class Enable=void>
struct signature_aux
{
    typedef F type;
};

// Handle boost::function and std::function:
template <template<class> class F, class S>
struct signature_aux<
    F<S>,
    typename mpl::apply< // Enable only if F<S>::result_type exists.
        mpl::always<void>, typename F<S>::result_type>::type >
{
    typedef S type;
};

template <class F>
struct signature_aux<const F>: signature_aux<F> {};

template <typename F>
struct is_function:
    fty::is_callable_builtin<typename signature_aux<F>::type>
{};

template <class F>
typename boost::enable_if<
    is_function<F>,
    fty::components<typename signature_aux<F>::type> >::type
deduce_signature(F const&, ...)
{
    return fty::components<typename signature_aux<F>::type>();
}

template <class F, class Wrapped>
typename boost::enable_if<
    fty::is_member_function_pointer<typename signature_aux<F>::type>,
    fty::components<
        typename signature_aux<F>::type,
        boost::add_reference<most_derived<mpl::_1, Wrapped> > > >::type
deduce_signature(F, Wrapped*)
{
    return fty::components<
        typename signature_aux<F>::type,
        boost::add_reference<most_derived<mpl::_1, Wrapped> > >();
}

} } // namespace luabind::detail

#endif  // LUABIND_DEDUCE_SIGNATURE_080911_HPP
<|endoftext|>


<commit_before>#include "html.h"
#include "stylesheet.h"
#include <algorithm>
#include "document.h"

void litehtml::css::parse_stylesheet(const tchar_t* str, const tchar_t* baseurl, const std::shared_ptr<document>& doc, const media_query_list::ptr& media)
{
	tstring text = str;

	// remove comments
	tstring::size_type c_start = text.find(_t("/*"));
	while(c_start != tstring::npos)
	{
		tstring::size_type c_end = text.find(_t("*/"), c_start + 2);
		text.erase(c_start, c_end - c_start + 2);
		c_start = text.find(_t("/*"));
	}

	tstring::size_type pos = text.find_first_not_of(_t(" \n\r\t"));
	while(pos != tstring::npos)
	{
		while(pos != tstring::npos && text[pos] == _t('@'))
		{
			tstring::size_type sPos = pos;
			pos = text.find_first_of(_t("{"), pos);
			if(pos != tstring::npos && text[pos] == _t('{'))
			{
				pos = find_close_bracket(text, pos, _t('{'), _t('}'));
			}
			if(pos != tstring::npos)
			{
				parse_atrule(text.substr(sPos, pos - sPos + 1), baseurl, doc, media);
			} else
			{
				parse_atrule(text.substr(sPos), baseurl, doc, media);
			}

			if(pos != tstring::npos)
			{
				pos = text.find_first_not_of(_t(" \n\r\t"), pos + 1);
			}
		}

		if(pos == tstring::npos)
		{
			break;
		}

		tstring::size_type style_start = text.find(_t("{"), pos);
		tstring::size_type style_end	= text.find(_t("}"), pos);
		if(style_start != tstring::npos && style_end != tstring::npos)
		{
			style::ptr st = std::make_shared<style>();
			st->add(text.substr(style_start + 1, style_end - style_start - 1).c_str(), baseurl);

			parse_selectors(text.substr(pos, style_start - pos), st, media);

			if(media && doc)
			{
				doc->add_media_list(media);
			}

			pos = style_end + 1;
		} else
		{
			pos = tstring::npos;
		}

		if(pos != tstring::npos)
		{
			pos = text.find_first_not_of(_t(" \n\r\t"), pos);
		}
	}
}

void litehtml::css::parse_css_url( const tstring& str, tstring& url )
{
	url = _t("");
	size_t pos1 = str.find(_t('('));
	size_t pos2 = str.find(_t(')'));
	if(pos1 != tstring::npos && pos2 != tstring::npos)
	{
		url = str.substr(pos1 + 1, pos2 - pos1 - 1);
		if(url.length())
		{
			if(url[0] == _t('\'') || url[0] == _t('"'))
			{
				url.erase(0, 1);
			}
		}
		if(url.length())
		{
			if(url[url.length() - 1] == _t('\'') || url[url.length() - 1] == _t('"'))
			{
				url.erase(url.length() - 1, 1);
			}
		}
	}
}

bool litehtml::css::parse_selectors( const tstring& txt, const litehtml::style::ptr& styles, const media_query_list::ptr& media )
{
	tstring selector = txt;
	trim(selector);
	string_vector tokens;
	split_string(selector, tokens, _t(","));

	bool added_something = false;

	for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)
	{
		css_selector::ptr selector = std::make_shared<css_selector>(media);
		selector->m_style = styles;
		trim(*tok);
		if(selector->parse(*tok))
		{
			selector->calc_specificity();
			add_selector(selector);
			added_something = true;
		}
	}

	return added_something;
}

void litehtml::css::sort_selectors()
{
	std::sort(m_selectors.begin(), m_selectors.end(),
		 [](const css_selector::ptr& v1, const css_selector::ptr& v2)
		 {
			 return (*v1) < (*v2);
		 }
	);
}

void litehtml::css::parse_atrule(const tstring& text, const tchar_t* baseurl, const std::shared_ptr<document>& doc, const media_query_list::ptr& media)
{
	if(text.substr(0, 7) == _t("@import"))
	{
		int sPos = 7;
		tstring iStr;
		iStr = text.substr(sPos);
		if(iStr[iStr.length() - 1] == _t(';'))
		{
			iStr.erase(iStr.length() - 1);
		}
		trim(iStr);
		string_vector tokens;
		split_string(iStr, tokens, _t(" "), _t(""), _t("(\""));
		if(!tokens.empty())
		{
			tstring url;
			parse_css_url(tokens.front(), url);
			if(url.empty())
			{
				url = tokens.front();
			}
			tokens.erase(tokens.begin());
			if(doc)
			{
				document_container* doc_cont = doc->container();
				if(doc_cont)
				{
					tstring css_text;
					tstring css_baseurl;
					if(baseurl)
					{
						css_baseurl = baseurl;
					}
					doc_cont->import_css(css_text, url, css_baseurl);
					if(!css_text.empty())
					{
						media_query_list::ptr new_media = media;
						if(!tokens.empty())
						{
							tstring media_str;
							for(string_vector::iterator iter = tokens.begin(); iter != tokens.end(); iter++)
							{
								if(iter != tokens.begin())
								{
									media_str += _t(" ");
								}
								media_str += (*iter);
							}
							new_media = media_query_list::create_from_string(media_str, doc);
							if(!new_media)
							{
								new_media = media;
							}
						}
						parse_stylesheet(css_text.c_str(), css_baseurl.c_str(), doc, new_media);
					}
				}
			}
		}
	} else if(text.substr(0, 6) == _t("@media"))
	{
		tstring::size_type b1 = text.find_first_of(_t('{'));
		tstring::size_type b2 = text.find_last_of(_t('}'));
		if(b1 != tstring::npos)
		{
			tstring media_type = text.substr(6, b1 - 6);
			trim(media_type);
			media_query_list::ptr new_media = media_query_list::create_from_string(media_type, doc);

			tstring media_style;
			if(b2 != tstring::npos)
			{
				media_style = text.substr(b1 + 1, b2 - b1 - 1);
			} else
			{
				media_style = text.substr(b1 + 1);
			}

			parse_stylesheet(media_style.c_str(), baseurl, doc, new_media);
		}
	}
}
<commit_msg>Fixed parsing CSS at-rules Closes #74<commit_after>#include "html.h"
#include "stylesheet.h"
#include <algorithm>
#include "document.h"

void litehtml::css::parse_stylesheet(const tchar_t* str, const tchar_t* baseurl, const std::shared_ptr<document>& doc, const media_query_list::ptr& media)
{
	tstring text = str;

	// remove comments
	tstring::size_type c_start = text.find(_t("/*"));
	while(c_start != tstring::npos)
	{
		tstring::size_type c_end = text.find(_t("*/"), c_start + 2);
		text.erase(c_start, c_end - c_start + 2);
		c_start = text.find(_t("/*"));
	}

	tstring::size_type pos = text.find_first_not_of(_t(" \n\r\t"));
	while(pos != tstring::npos)
	{
		while(pos != tstring::npos && text[pos] == _t('@'))
		{
			tstring::size_type sPos = pos;
			pos = text.find_first_of(_t("{;"), pos);
			if(pos != tstring::npos && text[pos] == _t('{'))
			{
				pos = find_close_bracket(text, pos, _t('{'), _t('}'));
			}
			if(pos != tstring::npos)
			{
				parse_atrule(text.substr(sPos, pos - sPos + 1), baseurl, doc, media);
			} else
			{
				parse_atrule(text.substr(sPos), baseurl, doc, media);
			}

			if(pos != tstring::npos)
			{
				pos = text.find_first_not_of(_t(" \n\r\t"), pos + 1);
			}
		}

		if(pos == tstring::npos)
		{
			break;
		}

		tstring::size_type style_start = text.find(_t("{"), pos);
		tstring::size_type style_end	= text.find(_t("}"), pos);
		if(style_start != tstring::npos && style_end != tstring::npos)
		{
			style::ptr st = std::make_shared<style>();
			st->add(text.substr(style_start + 1, style_end - style_start - 1).c_str(), baseurl);

			parse_selectors(text.substr(pos, style_start - pos), st, media);

			if(media && doc)
			{
				doc->add_media_list(media);
			}

			pos = style_end + 1;
		} else
		{
			pos = tstring::npos;
		}

		if(pos != tstring::npos)
		{
			pos = text.find_first_not_of(_t(" \n\r\t"), pos);
		}
	}
}

void litehtml::css::parse_css_url( const tstring& str, tstring& url )
{
	url = _t("");
	size_t pos1 = str.find(_t('('));
	size_t pos2 = str.find(_t(')'));
	if(pos1 != tstring::npos && pos2 != tstring::npos)
	{
		url = str.substr(pos1 + 1, pos2 - pos1 - 1);
		if(url.length())
		{
			if(url[0] == _t('\'') || url[0] == _t('"'))
			{
				url.erase(0, 1);
			}
		}
		if(url.length())
		{
			if(url[url.length() - 1] == _t('\'') || url[url.length() - 1] == _t('"'))
			{
				url.erase(url.length() - 1, 1);
			}
		}
	}
}

bool litehtml::css::parse_selectors( const tstring& txt, const litehtml::style::ptr& styles, const media_query_list::ptr& media )
{
	tstring selector = txt;
	trim(selector);
	string_vector tokens;
	split_string(selector, tokens, _t(","));

	bool added_something = false;

	for(string_vector::iterator tok = tokens.begin(); tok != tokens.end(); tok++)
	{
		css_selector::ptr selector = std::make_shared<css_selector>(media);
		selector->m_style = styles;
		trim(*tok);
		if(selector->parse(*tok))
		{
			selector->calc_specificity();
			add_selector(selector);
			added_something = true;
		}
	}

	return added_something;
}

void litehtml::css::sort_selectors()
{
	std::sort(m_selectors.begin(), m_selectors.end(),
		 [](const css_selector::ptr& v1, const css_selector::ptr& v2)
		 {
			 return (*v1) < (*v2);
		 }
	);
}

void litehtml::css::parse_atrule(const tstring& text, const tchar_t* baseurl, const std::shared_ptr<document>& doc, const media_query_list::ptr& media)
{
	if(text.substr(0, 7) == _t("@import"))
	{
		int sPos = 7;
		tstring iStr;
		iStr = text.substr(sPos);
		if(iStr[iStr.length() - 1] == _t(';'))
		{
			iStr.erase(iStr.length() - 1);
		}
		trim(iStr);
		string_vector tokens;
		split_string(iStr, tokens, _t(" "), _t(""), _t("(\""));
		if(!tokens.empty())
		{
			tstring url;
			parse_css_url(tokens.front(), url);
			if(url.empty())
			{
				url = tokens.front();
			}
			tokens.erase(tokens.begin());
			if(doc)
			{
				document_container* doc_cont = doc->container();
				if(doc_cont)
				{
					tstring css_text;
					tstring css_baseurl;
					if(baseurl)
					{
						css_baseurl = baseurl;
					}
					doc_cont->import_css(css_text, url, css_baseurl);
					if(!css_text.empty())
					{
						media_query_list::ptr new_media = media;
						if(!tokens.empty())
						{
							tstring media_str;
							for(string_vector::iterator iter = tokens.begin(); iter != tokens.end(); iter++)
							{
								if(iter != tokens.begin())
								{
									media_str += _t(" ");
								}
								media_str += (*iter);
							}
							new_media = media_query_list::create_from_string(media_str, doc);
							if(!new_media)
							{
								new_media = media;
							}
						}
						parse_stylesheet(css_text.c_str(), css_baseurl.c_str(), doc, new_media);
					}
				}
			}
		}
	} else if(text.substr(0, 6) == _t("@media"))
	{
		tstring::size_type b1 = text.find_first_of(_t('{'));
		tstring::size_type b2 = text.find_last_of(_t('}'));
		if(b1 != tstring::npos)
		{
			tstring media_type = text.substr(6, b1 - 6);
			trim(media_type);
			media_query_list::ptr new_media = media_query_list::create_from_string(media_type, doc);

			tstring media_style;
			if(b2 != tstring::npos)
			{
				media_style = text.substr(b1 + 1, b2 - b1 - 1);
			} else
			{
				media_style = text.substr(b1 + 1);
			}

			parse_stylesheet(media_style.c_str(), baseurl, doc, new_media);
		}
	}
}
<|endoftext|>


<commit_before>/* maestro.cpp - management of multiple trials for dubins_traffic
 *
 * SCL; 2016
 */

#include <ros/ros.h>
#include "std_srvs/Empty.h"
#include "gazebo_msgs/ModelState.h"
#include "geometry_msgs/Pose.h"
#include "geometry_msgs/Twist.h"

#include <Eigen/Dense>

#include "integrator_chains_msgs/ProblemInstanceJSON.h"
#include "dubins_traffic_msgs/MMode.h"
#include "roadnet.hpp"
#include "problem.hpp"

using namespace dubins_traffic;

class Maestro {
public:
    Maestro( ros::NodeHandle &nh_, Problem &problem_ );

    bool mode_request( dubins_traffic_msgs::MMode::Request &req,
                       dubins_traffic_msgs::MMode::Response &res );

    void perform_trial();
    void main();

private:
    ros::NodeHandle &nh;
    Problem &problem;
    ros::Publisher problemJSONpub;

    ros::Publisher set_model_state;
    ros::ServiceClient gazebo_toggle;
    bool gazebo_paused;

    ros::ServiceServer mode_srv;
    enum MMode { ready, waiting, running, resetting };
    MMode mmode;

    /* (copied from domains/integrator_chains/dynamaestro/src/main.cpp to avoid dependency.) */
    bool parse_range_str( const std::string param_name, Eigen::Vector2i &range );
};

bool Maestro::parse_range_str( const std::string param_name, Eigen::Vector2i &range )
{
    std::string range_str;
    if (!nh.getParam( param_name, range_str ))
        return false;

    char *endptr;
    errno = 0;
    range(0) = strtol( range_str.data(), &endptr, 10 );
    if (errno || endptr == range_str.data()) {
        std::cerr << "dubins_traffic_maestro: Malformed range string in \""
                  << param_name << "\"" << std::endl;
        return false;
    }
    char *prev_endptr = endptr;
    errno = 0;
    range(1) = strtol( prev_endptr, &endptr, 10 );
    if (errno || endptr == prev_endptr) {
        std::cerr << "dubins_traffic_maestro: Malformed range string in \""
                  << param_name << "\"" << std::endl;
        return false;
    }

    return true;
}

Maestro::Maestro( ros::NodeHandle &nh_, Problem &problem_ )
    : nh(nh_), problem(problem_), gazebo_paused( true ), mmode(resetting)
{
    problemJSONpub = nh.advertise<integrator_chains_msgs::ProblemInstanceJSON>( "probleminstance_JSON", 1, true );
    mode_srv = nh.advertiseService( "mode", &Maestro::mode_request, this );
    set_model_state = nh.advertise<gazebo_msgs::ModelState>( "/gazebo/set_model_state", 1, false );
}

bool Maestro::mode_request( dubins_traffic_msgs::MMode::Request &req,
                            dubins_traffic_msgs::MMode::Response &res )
{
    switch (req.mode) {
    case dubins_traffic_msgs::MMode::Request::READY:
        if (!gazebo_paused) {
            gazebo_toggle = nh.serviceClient<std_srvs::Empty>( "/gazebo/pause_physics" );
            std_srvs::Empty empty;
            if (gazebo_toggle.call( empty ))
                gazebo_paused = true;
        }
        if (mmode == ready && gazebo_paused) {
            res.result = true;
        } else {
            res.result = false;
        }
        break;

    case dubins_traffic_msgs::MMode::Request::START:
        if (gazebo_paused) {
            gazebo_toggle = nh.serviceClient<std_srvs::Empty>( "/gazebo/unpause_physics" );
            std_srvs::Empty empty;
            if (gazebo_toggle.call( empty ))
                gazebo_paused = false;
        }
        if (mmode == ready && !gazebo_paused) {
            mmode = waiting;
            res.result = true;
        } else {
            res.result = false;
        }
        break;

    case dubins_traffic_msgs::MMode::Request::RESET:
        mmode = resetting;
        ROS_INFO( "dubins_traffic_maestro: Stopping current trial and generating a new instance..." );
        res.result = true;
        break;

    default:
        return false;
    }

    return true;
}

void Maestro::perform_trial()
{
    Eigen::Vector2i duration_bounds;
    if (!parse_range_str( "duration_bounds", duration_bounds )) {
        duration_bounds << 30, 90;
    }
    ROS_INFO( "dubins_traffic_maestro: Using [%d, %d] as range of integers for sampling "
              "the trial duration.",
              duration_bounds(0), duration_bounds(1) );

    int nominal_duration = duration_bounds(0);
    if (duration_bounds(0) != duration_bounds(1))
        nominal_duration += std::rand() % (1+duration_bounds(1)-duration_bounds(0));

    ros::Duration trial_duration;

    mmode = ready;
    while (mmode == ready) {
        if (!ros::ok())
            return;
        ros::spinOnce();
    }
    assert( mmode == waiting );

    integrator_chains_msgs::ProblemInstanceJSON probinstance_msg;
    probinstance_msg.stamp = ros::Time::now();
    probinstance_msg.problemjson = problem.dumpJSON();
    problemJSONpub.publish( probinstance_msg );
    ros::Time startt( probinstance_msg.stamp.sec,
                      probinstance_msg.stamp.nsec );
    ros::spinOnce();

    ros::Rate polling_rate( 1000 );
    while (ros::ok() && mmode != resetting && (trial_duration = ros::Time::now() - startt).toSec() < nominal_duration) {
        if (mmode == waiting) {
            mmode = running;
        }
        ros::spinOnce();
        polling_rate.sleep();
    }
    mmode = resetting;

    // Handle special cases of trial termination:
    if (ros::ok() && trial_duration.toSec() >= nominal_duration) {
        // The trial end because the nominal (hidden) duration was reached
        ROS_INFO( "dubins_traffic_maestro: Trial ended after %f s (threshold is %d s).",
                  trial_duration.toSec(), nominal_duration );
    }
}

void Maestro::main()
{
    int number_trials = 0;
    bool counting_trials = nh.getParam( "/number_trials", number_trials );
    if (counting_trials)
        ROS_INFO( "dubins_traffic_maestro: Initiated with request for %d trials.",
                  number_trials );
    int trial_counter = 0;
    while ((!counting_trials || trial_counter < number_trials)
           && ros::ok()) {
        perform_trial();
        if (counting_trials)
            trial_counter++;
    }

    if (counting_trials && ros::ok()) {
        ROS_INFO( "dubins_traffic_maestro: Completed %d trials.", trial_counter );
    }
}

int main( int argc, char **argv )
{
    ros::init( argc, argv, "dubins_traffic_maestro" );
    ros::NodeHandle nh( "~" );

    std::string rndjson;
    while (!nh.getParam( "/dubins_traffic/rnd", rndjson )) {
        ROS_INFO( "dubins_traffic_maestro: RND JSON string not present; will try again soon..." );
        sleep( 1 );
        if (!ros::ok())
            return 0;
    }
    RoadNetwork rnd( rndjson );
    Problem problem( rnd );

    Maestro maestro( nh, problem );
    maestro.main();
    nh.shutdown();

    return 0;
}
<commit_msg>dubins_traffic maestro uses new Problem::random()<commit_after>/* maestro.cpp - management of multiple trials for dubins_traffic
 *
 * SCL; 2016
 */

#include <ros/ros.h>
#include "std_srvs/Empty.h"
#include "gazebo_msgs/ModelState.h"
#include "geometry_msgs/Pose.h"
#include "geometry_msgs/Twist.h"

#include <Eigen/Dense>

#include "integrator_chains_msgs/ProblemInstanceJSON.h"
#include "dubins_traffic_msgs/MMode.h"
#include "roadnet.hpp"
#include "problem.hpp"

using namespace dubins_traffic;

class Maestro {
public:
    Maestro( ros::NodeHandle &nh_, const RoadNetwork rnd_ );

    bool mode_request( dubins_traffic_msgs::MMode::Request &req,
                       dubins_traffic_msgs::MMode::Response &res );

    void perform_trial();
    void main();

private:
    ros::NodeHandle &nh;
    RoadNetwork rnd;
    Problem probinstance;
    ros::Publisher problemJSONpub;

    ros::Publisher set_model_state;
    ros::ServiceClient gazebo_toggle;
    bool gazebo_paused;

    ros::ServiceServer mode_srv;
    enum MMode { ready, waiting, running, resetting };
    MMode mmode;

    /* (copied from domains/integrator_chains/dynamaestro/src/main.cpp to avoid dependency.) */
    bool parse_range_str( const std::string param_name, Eigen::Vector2i &range );
};

bool Maestro::parse_range_str( const std::string param_name, Eigen::Vector2i &range )
{
    std::string range_str;
    if (!nh.getParam( param_name, range_str ))
        return false;

    char *endptr;
    errno = 0;
    range(0) = strtol( range_str.data(), &endptr, 10 );
    if (errno || endptr == range_str.data()) {
        std::cerr << "dubins_traffic_maestro: Malformed range string in \""
                  << param_name << "\"" << std::endl;
        return false;
    }
    char *prev_endptr = endptr;
    errno = 0;
    range(1) = strtol( prev_endptr, &endptr, 10 );
    if (errno || endptr == prev_endptr) {
        std::cerr << "dubins_traffic_maestro: Malformed range string in \""
                  << param_name << "\"" << std::endl;
        return false;
    }

    return true;
}

Maestro::Maestro( ros::NodeHandle &nh_, const RoadNetwork rnd_ )
    : nh(nh_), rnd(rnd_), probinstance( rnd_ ), gazebo_paused( true ), mmode(resetting)
{
    problemJSONpub = nh.advertise<integrator_chains_msgs::ProblemInstanceJSON>( "probleminstance_JSON", 1, true );
    mode_srv = nh.advertiseService( "mode", &Maestro::mode_request, this );
    set_model_state = nh.advertise<gazebo_msgs::ModelState>( "/gazebo/set_model_state", 1, false );
}

bool Maestro::mode_request( dubins_traffic_msgs::MMode::Request &req,
                            dubins_traffic_msgs::MMode::Response &res )
{
    switch (req.mode) {
    case dubins_traffic_msgs::MMode::Request::READY:
        if (!gazebo_paused) {
            gazebo_toggle = nh.serviceClient<std_srvs::Empty>( "/gazebo/pause_physics" );
            std_srvs::Empty empty;
            if (gazebo_toggle.call( empty ))
                gazebo_paused = true;
        }
        if (mmode == ready && gazebo_paused) {
            res.result = true;
        } else {
            res.result = false;
        }
        break;

    case dubins_traffic_msgs::MMode::Request::START:
        if (gazebo_paused) {
            gazebo_toggle = nh.serviceClient<std_srvs::Empty>( "/gazebo/unpause_physics" );
            std_srvs::Empty empty;
            if (gazebo_toggle.call( empty ))
                gazebo_paused = false;
        }
        if (mmode == ready && !gazebo_paused) {
            mmode = waiting;
            res.result = true;
        } else {
            res.result = false;
        }
        break;

    case dubins_traffic_msgs::MMode::Request::RESET:
        mmode = resetting;
        ROS_INFO( "dubins_traffic_maestro: Stopping current trial and generating a new instance..." );
        res.result = true;
        break;

    default:
        return false;
    }

    return true;
}

void Maestro::perform_trial()
{
    Eigen::Vector2i number_goals_bounds;
    if (!parse_range_str( "number_goals_bounds", number_goals_bounds )) {
        number_goals_bounds << 1, 4;
    }
    ROS_INFO( "dubins_traffic_maestro: Using [%d, %d] as sampling range "
              "for number of goal polytopes.",
              number_goals_bounds(0), number_goals_bounds(1) );

    Eigen::Vector2i duration_bounds;
    if (!parse_range_str( "duration_bounds", duration_bounds )) {
        duration_bounds << 30, 90;
    }
    ROS_INFO( "dubins_traffic_maestro: Using [%d, %d] as range of integers for sampling "
              "the trial duration.",
              duration_bounds(0), duration_bounds(1) );

    int nominal_duration = duration_bounds(0);
    if (duration_bounds(0) != duration_bounds(1))
        nominal_duration += std::rand() % (1+duration_bounds(1)-duration_bounds(0));

    probinstance = Problem::random( rnd, number_goals_bounds );

    ros::Duration trial_duration;

    mmode = ready;
    while (mmode == ready) {
        if (!ros::ok())
            return;
        ros::spinOnce();
    }
    assert( mmode == waiting );

    integrator_chains_msgs::ProblemInstanceJSON probinstance_msg;
    probinstance_msg.stamp = ros::Time::now();
    probinstance_msg.problemjson = probinstance.dumpJSON();
    problemJSONpub.publish( probinstance_msg );
    ros::Time startt( probinstance_msg.stamp.sec,
                      probinstance_msg.stamp.nsec );
    ros::spinOnce();

    ros::Rate polling_rate( 1000 );
    while (ros::ok() && mmode != resetting && (trial_duration = ros::Time::now() - startt).toSec() < nominal_duration) {
        if (mmode == waiting) {
            mmode = running;
        }
        ros::spinOnce();
        polling_rate.sleep();
    }
    mmode = resetting;

    // Handle special cases of trial termination:
    if (ros::ok() && trial_duration.toSec() >= nominal_duration) {
        // The trial end because the nominal (hidden) duration was reached
        ROS_INFO( "dubins_traffic_maestro: Trial ended after %f s (threshold is %d s).",
                  trial_duration.toSec(), nominal_duration );
    }
}

void Maestro::main()
{
    int number_trials = 0;
    bool counting_trials = nh.getParam( "/number_trials", number_trials );
    if (counting_trials)
        ROS_INFO( "dubins_traffic_maestro: Initiated with request for %d trials.",
                  number_trials );
    int trial_counter = 0;
    while ((!counting_trials || trial_counter < number_trials)
           && ros::ok()) {
        perform_trial();
        if (counting_trials)
            trial_counter++;
    }

    if (counting_trials && ros::ok()) {
        ROS_INFO( "dubins_traffic_maestro: Completed %d trials.", trial_counter );
    }
}

int main( int argc, char **argv )
{
    ros::init( argc, argv, "dubins_traffic_maestro" );
    ros::NodeHandle nh( "~" );

    std::string rndjson;
    while (!nh.getParam( "/dubins_traffic/rnd", rndjson )) {
        ROS_INFO( "dubins_traffic_maestro: RND JSON string not present; will try again soon..." );
        sleep( 1 );
        if (!ros::ok())
            return 0;
    }
    RoadNetwork rnd( rndjson );
    Maestro maestro( nh, rnd );

    maestro.main();
    nh.shutdown();

    return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cache_service.hh"
#include "api/api-doc/cache_service.json.hh"
#include "column_family.hh"

namespace api {
using namespace json;
namespace cs = httpd::cache_service_json;

void set_cache_service(http_context& ctx, routes& r) {
    cs::get_row_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // We never save the cache
        // Origin uses 0 for never
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_row_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto period = req->get_query_param("period");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_key_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // We never save the cache
        // Origin uses 0 for never
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_key_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto period = req->get_query_param("period");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_counter_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // We never save the cache
        // Origin uses 0 for never
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_counter_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto ccspis = req->get_query_param("ccspis");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_row_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_row_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto rckts = req->get_query_param("rckts");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_key_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_key_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto kckts = req->get_query_param("kckts");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_counter_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_counter_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto cckts = req->get_query_param("cckts");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::invalidate_key_cache.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::invalidate_counter_cache.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::set_row_cache_capacity_in_mb.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto capacity = req->get_query_param("capacity");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::set_key_cache_capacity_in_mb.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto period = req->get_query_param("period");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::set_counter_cache_capacity_in_mb.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto capacity = req->get_query_param("capacity");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::save_caches.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_key_capacity.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for capacity is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_hits.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for hits is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_requests.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for request is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_hit_rate.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for rate is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_hits_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_key_requests_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_key_size.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for size is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_entries.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for key entries is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_row_capacity.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, uint64_t(0), [](const column_family& cf) {
            return cf.get_row_cache().get_cache_tracker().region().occupancy().used_space();
        }, std::plus<uint64_t>());
    });

    cs::get_row_hits.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, uint64_t(0), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.count();
        }, std::plus<uint64_t>());
    });

    cs::get_row_requests.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, uint64_t(0), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.count() + cf.get_row_cache().stats().misses.count();
        }, std::plus<uint64_t>());
    });

    cs::get_row_hit_rate.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, ratio_holder(), [](const column_family& cf) {
            return ratio_holder(cf.get_row_cache().stats().hits.count() + cf.get_row_cache().stats().misses.count(),
                    cf.get_row_cache().stats().hits.count());
        }, std::plus<ratio_holder>());
    });

    cs::get_row_hits_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf_raw(ctx, utils::rate_moving_average(), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.rate();
        }, std::plus<utils::rate_moving_average>()).then([](const utils::rate_moving_average& m) {
            return make_ready_future<json::json_return_type>(meter_to_json(m));
        });
    });

    cs::get_row_requests_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf_raw(ctx, utils::rate_moving_average(), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.rate() + cf.get_row_cache().stats().misses.rate();
        }, std::plus<utils::rate_moving_average>()).then([](const utils::rate_moving_average& m) {
            return make_ready_future<json::json_return_type>(meter_to_json(m));
        });
    });

    cs::get_row_size.set(r, [&ctx] (std::unique_ptr<request> req) {
        // In origin row size is the weighted size.
        // We currently do not support weights, so we use num entries instead
        return map_reduce_cf(ctx, 0, [](const column_family& cf) {
            return cf.get_row_cache().partitions();
        }, std::plus<uint64_t>());
    });

    cs::get_row_entries.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, 0, [](const column_family& cf) {
            return cf.get_row_cache().partitions();
        }, std::plus<uint64_t>());
    });

    cs::get_counter_capacity.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for rate is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_hits.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for hits is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_requests.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for hits is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_hit_rate.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for rate is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_hits_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_counter_requests_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_counter_size.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for size is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_entries.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for entries is ok
        return make_ready_future<json::json_return_type>(0);
    });
}

}

<commit_msg>api/cache_service: Fix get_row_capacity calculation<commit_after>/*
 * Copyright (C) 2015 ScyllaDB
 */

/*
 * This file is part of Scylla.
 *
 * Scylla is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * Scylla is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with Scylla.  If not, see <http://www.gnu.org/licenses/>.
 */

#include "cache_service.hh"
#include "api/api-doc/cache_service.json.hh"
#include "column_family.hh"

namespace api {
using namespace json;
namespace cs = httpd::cache_service_json;

void set_cache_service(http_context& ctx, routes& r) {
    cs::get_row_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // We never save the cache
        // Origin uses 0 for never
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_row_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto period = req->get_query_param("period");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_key_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // We never save the cache
        // Origin uses 0 for never
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_key_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto period = req->get_query_param("period");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_counter_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // We never save the cache
        // Origin uses 0 for never
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_counter_cache_save_period_in_seconds.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto ccspis = req->get_query_param("ccspis");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_row_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_row_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto rckts = req->get_query_param("rckts");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_key_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_key_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto kckts = req->get_query_param("kckts");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_counter_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(0);
    });

    cs::set_counter_cache_keys_to_save.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto cckts = req->get_query_param("cckts");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::invalidate_key_cache.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::invalidate_counter_cache.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::set_row_cache_capacity_in_mb.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto capacity = req->get_query_param("capacity");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::set_key_cache_capacity_in_mb.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto period = req->get_query_param("period");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::set_counter_cache_capacity_in_mb.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        auto capacity = req->get_query_param("capacity");
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::save_caches.set(r, [](std::unique_ptr<request> req) {
        // TBD
        unimplemented();
        return make_ready_future<json::json_return_type>(json_void());
    });

    cs::get_key_capacity.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for capacity is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_hits.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for hits is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_requests.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for request is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_hit_rate.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for rate is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_hits_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_key_requests_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_key_size.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for size is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_key_entries.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support keys cache,
        // so currently returning a 0 for key entries is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_row_capacity.set(r, [&ctx] (std::unique_ptr<request> req) {
        return ctx.db.map_reduce0([](database& db) -> uint64_t {
            return db.row_cache_tracker().region().occupancy().used_space();
        }, uint64_t(0), std::plus<uint64_t>()).then([](const int64_t& res) {
            return make_ready_future<json::json_return_type>(res);
        });
    });

    cs::get_row_hits.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, uint64_t(0), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.count();
        }, std::plus<uint64_t>());
    });

    cs::get_row_requests.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, uint64_t(0), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.count() + cf.get_row_cache().stats().misses.count();
        }, std::plus<uint64_t>());
    });

    cs::get_row_hit_rate.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, ratio_holder(), [](const column_family& cf) {
            return ratio_holder(cf.get_row_cache().stats().hits.count() + cf.get_row_cache().stats().misses.count(),
                    cf.get_row_cache().stats().hits.count());
        }, std::plus<ratio_holder>());
    });

    cs::get_row_hits_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf_raw(ctx, utils::rate_moving_average(), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.rate();
        }, std::plus<utils::rate_moving_average>()).then([](const utils::rate_moving_average& m) {
            return make_ready_future<json::json_return_type>(meter_to_json(m));
        });
    });

    cs::get_row_requests_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf_raw(ctx, utils::rate_moving_average(), [](const column_family& cf) {
            return cf.get_row_cache().stats().hits.rate() + cf.get_row_cache().stats().misses.rate();
        }, std::plus<utils::rate_moving_average>()).then([](const utils::rate_moving_average& m) {
            return make_ready_future<json::json_return_type>(meter_to_json(m));
        });
    });

    cs::get_row_size.set(r, [&ctx] (std::unique_ptr<request> req) {
        // In origin row size is the weighted size.
        // We currently do not support weights, so we use num entries instead
        return map_reduce_cf(ctx, 0, [](const column_family& cf) {
            return cf.get_row_cache().partitions();
        }, std::plus<uint64_t>());
    });

    cs::get_row_entries.set(r, [&ctx] (std::unique_ptr<request> req) {
        return map_reduce_cf(ctx, 0, [](const column_family& cf) {
            return cf.get_row_cache().partitions();
        }, std::plus<uint64_t>());
    });

    cs::get_counter_capacity.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for rate is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_hits.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for hits is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_requests.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for hits is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_hit_rate.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for rate is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_hits_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_counter_requests_moving_avrage.set(r, [&ctx] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // See above
        return make_ready_future<json::json_return_type>(meter_to_json(utils::rate_moving_average()));
    });

    cs::get_counter_size.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for size is ok
        return make_ready_future<json::json_return_type>(0);
    });

    cs::get_counter_entries.set(r, [] (std::unique_ptr<request> req) {
        // TBD
        // FIXME
        // we don't support counter cache,
        // so currently returning a 0 for entries is ok
        return make_ready_future<json::json_return_type>(0);
    });
}

}

<|endoftext|>


<commit_before>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * 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 the copyright holders 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 THE COPYRIGHT
 * OWNER 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.
 *
 * Authors: Steve Reinhardt
 *          Nathan Binkert
 */

#ifndef __CPU_BASE_HH__
#define __CPU_BASE_HH__

#include <vector>

#include "arch/isa_traits.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "sim/eventq.hh"
#include "sim/insttracer.hh"
#include "mem/mem_object.hh"

#if FULL_SYSTEM
#include "arch/interrupts.hh"
#endif

class BaseCPUParams;
class BranchPred;
class CheckerCPU;
class ThreadContext;
class System;
class Port;

namespace TheISA
{
    class Predecoder;
}

class CPUProgressEvent : public Event
{
  protected:
    Tick interval;
    Counter lastNumInst;
    BaseCPU *cpu;

  public:
    CPUProgressEvent(BaseCPU *_cpu, Tick ival);

    void process();

    virtual const char *description() const;
};

class BaseCPU : public MemObject
{
  protected:
    // CPU's clock period in terms of the number of ticks of curTime.
    Tick clock;
    // @todo remove me after debugging with legion done
    Tick instCnt;

  public:
//    Tick currentTick;
    inline Tick frequency() const { return Clock::Frequency / clock; }
    inline Tick ticks(int numCycles) const { return clock * numCycles; }
    inline Tick curCycle() const { return curTick / clock; }
    inline Tick tickToCycles(Tick val) const { return val / clock; }
    // @todo remove me after debugging with legion done
    Tick instCount() { return instCnt; }

    /** The next cycle the CPU should be scheduled, given a cache
     * access or quiesce event returning on this cycle.  This function
     * may return curTick if the CPU should run on the current cycle.
     */
    Tick nextCycle();

    /** The next cycle the CPU should be scheduled, given a cache
     * access or quiesce event returning on the given Tick.  This
     * function may return curTick if the CPU should run on the
     * current cycle.
     * @param begin_tick The tick that the event is completing on.
     */
    Tick nextCycle(Tick begin_tick);

#if FULL_SYSTEM
  protected:
//    uint64_t interrupts[TheISA::NumInterruptLevels];
//    uint64_t intstatus;
    TheISA::Interrupts interrupts;

  public:
    virtual void post_interrupt(int int_num, int index);
    virtual void clear_interrupt(int int_num, int index);
    virtual void clear_interrupts();
    virtual uint64_t get_interrupts(int int_num);

    bool check_interrupts(ThreadContext * tc) const
    { return interrupts.check_interrupts(tc); }

    class ProfileEvent : public Event
    {
      private:
        BaseCPU *cpu;
        Tick interval;

      public:
        ProfileEvent(BaseCPU *cpu, Tick interval);
        void process();
    };
    ProfileEvent *profileEvent;
#endif

  protected:
    std::vector<ThreadContext *> threadContexts;
    std::vector<TheISA::Predecoder *> predecoders;

    Trace::InstTracer * tracer;

  public:

    /// Provide access to the tracer pointer
    Trace::InstTracer * getTracer() { return tracer; }

    /// Notify the CPU that the indicated context is now active.  The
    /// delay parameter indicates the number of ticks to wait before
    /// executing (typically 0 or 1).
    virtual void activateContext(int thread_num, int delay) {}

    /// Notify the CPU that the indicated context is now suspended.
    virtual void suspendContext(int thread_num) {}

    /// Notify the CPU that the indicated context is now deallocated.
    virtual void deallocateContext(int thread_num) {}

    /// Notify the CPU that the indicated context is now halted.
    virtual void haltContext(int thread_num) {}

   /// Given a Thread Context pointer return the thread num
   int findContext(ThreadContext *tc);

   /// Given a thread num get tho thread context for it
   ThreadContext *getContext(int tn) { return threadContexts[tn]; }

  public:
    typedef BaseCPUParams Params;
    const Params *params() const
    { return reinterpret_cast<const Params *>(_params); }
    BaseCPU(Params *params);
    virtual ~BaseCPU();

    virtual void init();
    virtual void startup();
    virtual void regStats();

    virtual void activateWhenReady(int tid) {};

    void registerThreadContexts();

    /// Prepare for another CPU to take over execution.  When it is
    /// is ready (drained pipe) it signals the sampler.
    virtual void switchOut();

    /// Take over execution from the given CPU.  Used for warm-up and
    /// sampling.
    virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);

    /**
     *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
     * This is a constant for the duration of the simulation.
     */
    int number_of_threads;

    TheISA::CoreSpecific coreParams; //ISA-Specific Params That Set Up State in Core

    /**
     * Vector of per-thread instruction-based event queues.  Used for
     * scheduling events based on number of instructions committed by
     * a particular thread.
     */
    EventQueue **comInstEventQueue;

    /**
     * Vector of per-thread load-based event queues.  Used for
     * scheduling events based on number of loads committed by
     *a particular thread.
     */
    EventQueue **comLoadEventQueue;

    System *system;

    Tick phase;

#if FULL_SYSTEM
    /**
     * Serialize this object to the given output stream.
     * @param os The stream to serialize to.
     */
    virtual void serialize(std::ostream &os);

    /**
     * Reconstruct the state of this object from a checkpoint.
     * @param cp The checkpoint use.
     * @param section The section name of this object
     */
    virtual void unserialize(Checkpoint *cp, const std::string &section);

#endif

    /**
     * Return pointer to CPU's branch predictor (NULL if none).
     * @return Branch predictor pointer.
     */
    virtual BranchPred *getBranchPred() { return NULL; };

    virtual Counter totalInstructions() const { return 0; }

    // Function tracing
  private:
    bool functionTracingEnabled;
    std::ostream *functionTraceStream;
    Addr currentFunctionStart;
    Addr currentFunctionEnd;
    Tick functionEntryTick;
    void enableFunctionTrace();
    void traceFunctionsInternal(Addr pc);

  protected:
    void traceFunctions(Addr pc)
    {
        if (functionTracingEnabled)
            traceFunctionsInternal(pc);
    }

  private:
    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list

  public:
    static int numSimulatedCPUs() { return cpuList.size(); }
    static Counter numSimulatedInstructions()
    {
        Counter total = 0;

        int size = cpuList.size();
        for (int i = 0; i < size; ++i)
            total += cpuList[i]->totalInstructions();

        return total;
    }

  public:
    // Number of CPU cycles simulated
    Stats::Scalar<> numCycles;
};

#endif // __CPU_BASE_HH__
<commit_msg>CPU: Add a getInterruptController function<commit_after>/*
 * Copyright (c) 2002-2005 The Regents of The University of Michigan
 * 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 the copyright holders 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 THE COPYRIGHT
 * OWNER 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.
 *
 * Authors: Steve Reinhardt
 *          Nathan Binkert
 */

#ifndef __CPU_BASE_HH__
#define __CPU_BASE_HH__

#include <vector>

#include "arch/isa_traits.hh"
#include "base/statistics.hh"
#include "config/full_system.hh"
#include "sim/eventq.hh"
#include "sim/insttracer.hh"
#include "mem/mem_object.hh"

#if FULL_SYSTEM
#include "arch/interrupts.hh"
#endif

class BaseCPUParams;
class BranchPred;
class CheckerCPU;
class ThreadContext;
class System;
class Port;

namespace TheISA
{
    class Predecoder;
}

class CPUProgressEvent : public Event
{
  protected:
    Tick interval;
    Counter lastNumInst;
    BaseCPU *cpu;

  public:
    CPUProgressEvent(BaseCPU *_cpu, Tick ival);

    void process();

    virtual const char *description() const;
};

class BaseCPU : public MemObject
{
  protected:
    // CPU's clock period in terms of the number of ticks of curTime.
    Tick clock;
    // @todo remove me after debugging with legion done
    Tick instCnt;

  public:
//    Tick currentTick;
    inline Tick frequency() const { return Clock::Frequency / clock; }
    inline Tick ticks(int numCycles) const { return clock * numCycles; }
    inline Tick curCycle() const { return curTick / clock; }
    inline Tick tickToCycles(Tick val) const { return val / clock; }
    // @todo remove me after debugging with legion done
    Tick instCount() { return instCnt; }

    /** The next cycle the CPU should be scheduled, given a cache
     * access or quiesce event returning on this cycle.  This function
     * may return curTick if the CPU should run on the current cycle.
     */
    Tick nextCycle();

    /** The next cycle the CPU should be scheduled, given a cache
     * access or quiesce event returning on the given Tick.  This
     * function may return curTick if the CPU should run on the
     * current cycle.
     * @param begin_tick The tick that the event is completing on.
     */
    Tick nextCycle(Tick begin_tick);

#if FULL_SYSTEM
  protected:
//    uint64_t interrupts[TheISA::NumInterruptLevels];
//    uint64_t intstatus;
    TheISA::Interrupts interrupts;

  public:
    TheISA::Interrupts *
    getInterruptController()
    {
        return &interrupts;
    }

    virtual void post_interrupt(int int_num, int index);
    virtual void clear_interrupt(int int_num, int index);
    virtual void clear_interrupts();
    virtual uint64_t get_interrupts(int int_num);

    bool check_interrupts(ThreadContext * tc) const
    { return interrupts.check_interrupts(tc); }

    class ProfileEvent : public Event
    {
      private:
        BaseCPU *cpu;
        Tick interval;

      public:
        ProfileEvent(BaseCPU *cpu, Tick interval);
        void process();
    };
    ProfileEvent *profileEvent;
#endif

  protected:
    std::vector<ThreadContext *> threadContexts;
    std::vector<TheISA::Predecoder *> predecoders;

    Trace::InstTracer * tracer;

  public:

    /// Provide access to the tracer pointer
    Trace::InstTracer * getTracer() { return tracer; }

    /// Notify the CPU that the indicated context is now active.  The
    /// delay parameter indicates the number of ticks to wait before
    /// executing (typically 0 or 1).
    virtual void activateContext(int thread_num, int delay) {}

    /// Notify the CPU that the indicated context is now suspended.
    virtual void suspendContext(int thread_num) {}

    /// Notify the CPU that the indicated context is now deallocated.
    virtual void deallocateContext(int thread_num) {}

    /// Notify the CPU that the indicated context is now halted.
    virtual void haltContext(int thread_num) {}

   /// Given a Thread Context pointer return the thread num
   int findContext(ThreadContext *tc);

   /// Given a thread num get tho thread context for it
   ThreadContext *getContext(int tn) { return threadContexts[tn]; }

  public:
    typedef BaseCPUParams Params;
    const Params *params() const
    { return reinterpret_cast<const Params *>(_params); }
    BaseCPU(Params *params);
    virtual ~BaseCPU();

    virtual void init();
    virtual void startup();
    virtual void regStats();

    virtual void activateWhenReady(int tid) {};

    void registerThreadContexts();

    /// Prepare for another CPU to take over execution.  When it is
    /// is ready (drained pipe) it signals the sampler.
    virtual void switchOut();

    /// Take over execution from the given CPU.  Used for warm-up and
    /// sampling.
    virtual void takeOverFrom(BaseCPU *, Port *ic, Port *dc);

    /**
     *  Number of threads we're actually simulating (<= SMT_MAX_THREADS).
     * This is a constant for the duration of the simulation.
     */
    int number_of_threads;

    TheISA::CoreSpecific coreParams; //ISA-Specific Params That Set Up State in Core

    /**
     * Vector of per-thread instruction-based event queues.  Used for
     * scheduling events based on number of instructions committed by
     * a particular thread.
     */
    EventQueue **comInstEventQueue;

    /**
     * Vector of per-thread load-based event queues.  Used for
     * scheduling events based on number of loads committed by
     *a particular thread.
     */
    EventQueue **comLoadEventQueue;

    System *system;

    Tick phase;

#if FULL_SYSTEM
    /**
     * Serialize this object to the given output stream.
     * @param os The stream to serialize to.
     */
    virtual void serialize(std::ostream &os);

    /**
     * Reconstruct the state of this object from a checkpoint.
     * @param cp The checkpoint use.
     * @param section The section name of this object
     */
    virtual void unserialize(Checkpoint *cp, const std::string &section);

#endif

    /**
     * Return pointer to CPU's branch predictor (NULL if none).
     * @return Branch predictor pointer.
     */
    virtual BranchPred *getBranchPred() { return NULL; };

    virtual Counter totalInstructions() const { return 0; }

    // Function tracing
  private:
    bool functionTracingEnabled;
    std::ostream *functionTraceStream;
    Addr currentFunctionStart;
    Addr currentFunctionEnd;
    Tick functionEntryTick;
    void enableFunctionTrace();
    void traceFunctionsInternal(Addr pc);

  protected:
    void traceFunctions(Addr pc)
    {
        if (functionTracingEnabled)
            traceFunctionsInternal(pc);
    }

  private:
    static std::vector<BaseCPU *> cpuList;   //!< Static global cpu list

  public:
    static int numSimulatedCPUs() { return cpuList.size(); }
    static Counter numSimulatedInstructions()
    {
        Counter total = 0;

        int size = cpuList.size();
        for (int i = 0; i < size; ++i)
            total += cpuList[i]->totalInstructions();

        return total;
    }

  public:
    // Number of CPU cycles simulated
    Stats::Scalar<> numCycles;
};

#endif // __CPU_BASE_HH__
<|endoftext|>


<commit_before><commit_msg>removing set_cql_version. Force cql3<commit_after><|endoftext|>