<commit_before>/**
 * Consolite Compiler
 * Copyright (c) 2015 Robert Fotino, All Rights Reserved
 */

#include <iostream>
#include "parser.h"
#include "util.h"

Parser::Parser(Tokenizer *t) : _tokenizer(t), _bytePos(0) {
  // Add builtin "void COLOR(uint16 color)" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("void"),
        "COLOR",
        {
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "color")
          )
        }
      )
    )
  );
  // Add builtin "void PIXEL(uint16 x, uint16 y)" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("void"),
        "PIXEL",
        {
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "x")
          ),
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "y")
          )
        }
      )
    )
  );
  // Add builtin "void TIMERST()" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("void"),
        "TIMERST",
        { }
      )
    )
  );
  // Add builtin "uint16 TIME()" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("uint16"),
        "TIME",
        { }
      )
    )
  );
  // Add builtin "uint16 INPUT(uint16 input_id)" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("uint16"),
        "INPUT",
        {
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "input_id")
          )
        }
      )
    )
  );
  // Add builtin "uint16 RND()" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("uint16"),
        "RND",
        { }
      )
    )
  );
}

bool Parser::parse() {
  while (true) {
    // Get the type
    if (_tokenizer->peekNext().empty()) {
      // We have reached the end of the token stream without errors
      break;
    }
    TypeToken type;
    if (!type.parse(_tokenizer, _functions, _globals)) {
      return false;
    }

    // Get the name
    AtomToken name = _tokenizer->getNext();
    if (name.empty()) {
      _error("Error: Unexpected EOF, expected global or function name.");
      return false;
    }

    // Differentiate between function and global variable
    if ("(" == _tokenizer->peekNext().str()) {
      std::shared_ptr<FunctionToken> func(new FunctionToken(type, name.str()));
      if (!func->parse(_tokenizer, _functions, _globals)) {
        return false;
      }
    } else {
      std::shared_ptr<GlobalVarToken> var(new GlobalVarToken(type, name.str()));
      if (!var->parse(_tokenizer, _functions, _globals)) {
        return false;
      }
      _globals.push_back(var);
    }
  }
  // Make sure there is a 'void main()' function, which is the entry point.
  auto entryPoint = getFunction("main", _functions);
  if (!entryPoint ||
      "void" != entryPoint->type().name() ||
      0 != entryPoint->numParams()) {
    _error("No 'void main()' entry point found.");
    return false;
  }
  return true;
}

bool Parser::output(char *filename) {
  // Start by opening the output file.
  _outfile.open(filename, std::ofstream::out | std::ofstream::trunc);
  if (!_outfile.good()) {
    _error("Unable to open output file.");
    return false;
  }
  // Next assign labels for all globals and functions.
  for (auto global : _globals) {
    this->addLabel(global->name());
  }
  for (auto function : _functions) {
    this->addLabel(function->name());
  }
  // Output the "bootloader". This sets the stack pointer, calls main,
  // then goes into an infinite loop to prevent attempting to execute
  // code that wasn't meant to be executed.
  std::string stackLabel = this->getUnusedLabel("stack");
  this->writeInst("MOVI SP " + stackLabel);
  this->writeInst("CALL main");
  std::string finishedLabel = this->getUnusedLabel("program_finished");
  this->writeln(finishedLabel + ":");
  this->writeInst("JMPI " + finishedLabel);
  // Output global variables.
  for (auto global : _globals) {
    global->output(this);
  }
  // Output functions.
  for (auto function: _functions) {
    function->output(this);
  }
  // Output the stack position.
  this->writeln(stackLabel + ":");
  return true;
}

bool Parser::hasLabel(const std::string& label) {
  return 0 < _assignedLabels.count(label);
}

bool Parser::addLabel(const std::string& label) {
  if (this->hasLabel(label)) {
    return false;
  }
  _assignedLabels.insert(label);
  return true;
}

std::string Parser::getUnusedLabel(const std::string& label) {
  if (!this->hasLabel(label)) {
    this->addLabel(label);
    return label;
  }
  int i = 1;
  while (this->hasLabel(label + std::to_string(i))) {
    i++;
  }
  this->addLabel(label + std::to_string(i));
  return label + std::to_string(i);
}

void Parser::writeInst(const std::string& inst) {
  this->writeln("        " + inst);
  _bytePos += INST_SIZE;
}

void Parser::writeData(const std::string& data, int dataLength) {
  this->writeln("        " + data);
  _bytePos += dataLength * DATA_SIZE;
  while (0 != _bytePos % INST_SIZE) {
    _bytePos++;
  }
}

void Parser::writeln(const std::string& line) {
  std::cout << line << std::endl;
  _outfile << line << std::endl;
}
<commit_msg>Remove duplicating of output to stdout.<commit_after>/**
 * Consolite Compiler
 * Copyright (c) 2015 Robert Fotino, All Rights Reserved
 */

#include <iostream>
#include "parser.h"
#include "util.h"

Parser::Parser(Tokenizer *t) : _tokenizer(t), _bytePos(0) {
  // Add builtin "void COLOR(uint16 color)" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("void"),
        "COLOR",
        {
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "color")
          )
        }
      )
    )
  );
  // Add builtin "void PIXEL(uint16 x, uint16 y)" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("void"),
        "PIXEL",
        {
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "x")
          ),
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "y")
          )
        }
      )
    )
  );
  // Add builtin "void TIMERST()" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("void"),
        "TIMERST",
        { }
      )
    )
  );
  // Add builtin "uint16 TIME()" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("uint16"),
        "TIME",
        { }
      )
    )
  );
  // Add builtin "uint16 INPUT(uint16 input_id)" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("uint16"),
        "INPUT",
        {
          std::make_shared<ParamToken>(
            ParamToken(TypeToken("uint16"), "input_id")
          )
        }
      )
    )
  );
  // Add builtin "uint16 RND()" function.
  _functions.push_back(
    std::make_shared<FunctionToken>(
      FunctionToken(
        TypeToken("uint16"),
        "RND",
        { }
      )
    )
  );
}

bool Parser::parse() {
  while (true) {
    // Get the type
    if (_tokenizer->peekNext().empty()) {
      // We have reached the end of the token stream without errors
      break;
    }
    TypeToken type;
    if (!type.parse(_tokenizer, _functions, _globals)) {
      return false;
    }

    // Get the name
    AtomToken name = _tokenizer->getNext();
    if (name.empty()) {
      _error("Error: Unexpected EOF, expected global or function name.");
      return false;
    }

    // Differentiate between function and global variable
    if ("(" == _tokenizer->peekNext().str()) {
      std::shared_ptr<FunctionToken> func(new FunctionToken(type, name.str()));
      if (!func->parse(_tokenizer, _functions, _globals)) {
        return false;
      }
    } else {
      std::shared_ptr<GlobalVarToken> var(new GlobalVarToken(type, name.str()));
      if (!var->parse(_tokenizer, _functions, _globals)) {
        return false;
      }
      _globals.push_back(var);
    }
  }
  // Make sure there is a 'void main()' function, which is the entry point.
  auto entryPoint = getFunction("main", _functions);
  if (!entryPoint ||
      "void" != entryPoint->type().name() ||
      0 != entryPoint->numParams()) {
    _error("No 'void main()' entry point found.");
    return false;
  }
  return true;
}

bool Parser::output(char *filename) {
  // Start by opening the output file.
  _outfile.open(filename, std::ofstream::out | std::ofstream::trunc);
  if (!_outfile.good()) {
    _error("Unable to open output file.");
    return false;
  }
  // Next assign labels for all globals and functions.
  for (auto global : _globals) {
    this->addLabel(global->name());
  }
  for (auto function : _functions) {
    this->addLabel(function->name());
  }
  // Output the "bootloader". This sets the stack pointer, calls main,
  // then goes into an infinite loop to prevent attempting to execute
  // code that wasn't meant to be executed.
  std::string stackLabel = this->getUnusedLabel("stack");
  this->writeInst("MOVI SP " + stackLabel);
  this->writeInst("CALL main");
  std::string finishedLabel = this->getUnusedLabel("program_finished");
  this->writeln(finishedLabel + ":");
  this->writeInst("JMPI " + finishedLabel);
  // Output global variables.
  for (auto global : _globals) {
    global->output(this);
  }
  // Output functions.
  for (auto function: _functions) {
    function->output(this);
  }
  // Output the stack position.
  this->writeln(stackLabel + ":");
  return true;
}

bool Parser::hasLabel(const std::string& label) {
  return 0 < _assignedLabels.count(label);
}

bool Parser::addLabel(const std::string& label) {
  if (this->hasLabel(label)) {
    return false;
  }
  _assignedLabels.insert(label);
  return true;
}

std::string Parser::getUnusedLabel(const std::string& label) {
  if (!this->hasLabel(label)) {
    this->addLabel(label);
    return label;
  }
  int i = 1;
  while (this->hasLabel(label + std::to_string(i))) {
    i++;
  }
  this->addLabel(label + std::to_string(i));
  return label + std::to_string(i);
}

void Parser::writeInst(const std::string& inst) {
  this->writeln("        " + inst);
  _bytePos += INST_SIZE;
}

void Parser::writeData(const std::string& data, int dataLength) {
  this->writeln("        " + data);
  _bytePos += dataLength * DATA_SIZE;
  while (0 != _bytePos % INST_SIZE) {
    _bytePos++;
  }
}

void Parser::writeln(const std::string& line) {
  _outfile << line << std::endl;
}
<|endoftext|>


<commit_before>#pragma once

#include <iostream>
#include <cassert>
#include "lexer.hpp"

namespace popo {
    namespace parser {

        enum struct node_type{
            num,
            string,
            symbol,
            cons
        };

        class expr_node
        {
            public:
                expr_node(node_type t) :type(t){}
                virtual ~expr_node() {}

            public:
                node_type type;

        };

        class num_node
            : public expr_node
        {
            public:
                num_node(int value)
                    : expr_node(node_type::num), val(value) {}

            public:
                int val;
        };

        class string_node
            : public expr_node
        {
            public:
                string_node(std::string value)
                    :expr_node(node_type::string), val(value){}

            public:
                std::string val;
        };

        class symbol_node
            : public expr_node
        {
            public:
                symbol_node(std::string value)
                    : expr_node(node_type::symbol), val(value){}

            public:
                std::string val;
        };

        class cons_node
            : public expr_node
        {
            public:
                cons_node(): expr_node(node_type::cons) {
                    car = nullptr;
                    cdr = nullptr;
                }

                cons_node(expr_node* ca, expr_node* cd)
                    : expr_node(node_type::cons), car(ca), cdr(cd){}

            public:
                bool is_function;
                expr_node* car;
                expr_node* cdr;
        };

        template<typename Iteratable>
        class s_expression_parser
        {
            public:
                s_expression_parser(lexer::lexical_analyser<Iteratable>& lex)
                    : lex_(lex) {}

            public:
                auto sexp_parse() -> expr_node*
                {
                    return sexp_car_parse(false);
                }

            private:
                auto sexp_car_parse(bool already_read_token)
                    -> expr_node*
                {
                    auto cons = new cons_node();
                    if(!already_read_token){
                        auto token = lex_.get_next_token();
                        if(lexer::Token::eof == token){
                            return nullptr;
                        }
                        assert(lexer::Token::left == token);
                    }
                    cons->is_function = true;
                    switch(lex_.get_next_token()){
                        case lexer::Token::string:
                            cons->car = new string_node(lex_.get_lex().str);
                            break;

                        case lexer::Token::num:
                            cons->car = new num_node(lex_.get_lex().num);
                            break;

                        case lexer::Token::eof:
                            delete cons;
                            return nullptr;

                        default:
                            assert(false);
                    }

                    cons->cdr = sexp_cdr_parse();
//                     cons->cdr = sexp_cdr_parse(lexer::Token::eof);
                    return cons;
                }

                auto sexp_cdr_parse()
                    -> expr_node*
                {
                    auto cons = new cons_node();
                    switch(lex_.get_next_token()){
                        case lexer::Token::string:
                            cons->is_function = false;
                            cons->car = new string_node(lex_.get_lex().str);
                            break;

                        case lexer::Token::num:
                            cons->is_function = false;
                            cons->car = new num_node(lex_.get_lex().num);
                            break;

                        case lexer::Token::right:
                            delete cons;
                            return nil;

                        case lexer::Token::left:
                            cons->is_function = true;
                            cons->car = sexp_car_parse(true);
                            break;

                        default:
                            assert(false);
                    }
                    cons->cdr = sexp_cdr_parse();
                    return cons;
                }

            private:
                lexer::lexical_analyser<Iteratable> lex_;

            public:
                static cons_node* nil;

        };

//         cons_node* s_expression_parser<typename T>::nil = new cons_node();
        template <typename T> cons_node* s_expression_parser<T>::nil = new cons_node();

        template<typename T>
        auto print_cons(expr_node* node)
            -> void
        {
            if(node->type == node_type::num){
                auto n = static_cast<num_node*>(node);
                std::cout << n->val << std::endl;
            }
            else if(node->type == node_type::string){
                auto n = static_cast<string_node*>(node);
                std::cout << n->val << std::endl;
            }
            else if(node->type == node_type::cons){
                auto n = static_cast<cons_node*>(node);
                if(s_expression_parser<T>::nil == n){
                    return;
                }
                print_cons<T>(n->car);
                print_cons<T>(n->cdr);
            }

        }

    } // namespace parser
} // namespace popo
<commit_msg>have to fix cons_node<commit_after>#pragma once

#include <iostream>
#include <cassert>
#include "lexer.hpp"

namespace popo {
    namespace parser {

        enum struct node_type{
            num,
            string,
            symbol,
            cons
        };

        class expr_node
        {
            public:
                expr_node(node_type t) :type(t){}
                virtual ~expr_node() {}

            public:
                node_type type;
                expr_node* parent_node;

        };

        class num_node
            : public expr_node
        {
            public:
                num_node(int value)
                    : expr_node(node_type::num), val(value) {}

            public:
                int val;
        };

        class string_node
            : public expr_node
        {
            public:
                string_node(std::string value)
                    :expr_node(node_type::string), val(value){}

            public:
                std::string val;
        };

        class symbol_node
            : public expr_node
        {
            public:
                symbol_node(std::string value)
                    : expr_node(node_type::symbol), val(value){}

            public:
                std::string val;
        };

        class cons_node
            : public expr_node
        {
            public:
                cons_node(): expr_node(node_type::cons) {
                    car = nullptr;
                    cdr = nullptr;
                }

                cons_node(expr_node* ca, expr_node* cd)
                    : expr_node(node_type::cons), car(ca), cdr(cd){}

            public:
                bool is_function;
                expr_node* car;
                expr_node* cdr;
        };

        template<typename Iteratable>
        class s_expression_parser
        {
            public:
                s_expression_parser(lexer::lexical_analyser<Iteratable>& lex)
                    : lex_(lex) {}

            public:
                auto sexp_parse() -> expr_node*
                {
                    return sexp_car_parse(false);
                }

            private:
                auto sexp_car_parse(bool already_read_token)
                    -> expr_node*
                {
                    auto cons = new cons_node();
                    if(!already_read_token){
                        auto token = lex_.get_next_token();
                        if(lexer::Token::eof == token){
                            return nullptr;
                        }
                        assert(lexer::Token::left == token);
                    }
                    cons->is_function = true;
                    switch(lex_.get_next_token()){
                        case lexer::Token::string:
                            cons->car = new string_node(lex_.get_lex().str);
                            break;

                        case lexer::Token::num:
                            cons->car = new num_node(lex_.get_lex().num);
                            break;

                        case lexer::Token::eof:
                            delete cons;
                            return nullptr;

                        default:
                            assert(false);
                    }

                    cons->cdr = sexp_cdr_parse();
//                     cons->cdr = sexp_cdr_parse(lexer::Token::eof);
                    return cons;
                }

                auto sexp_cdr_parse()
                    -> expr_node*
                {
                    auto cons = new cons_node();
                    switch(lex_.get_next_token()){
                        case lexer::Token::string:
                            cons->is_function = false;
                            cons->car = new string_node(lex_.get_lex().str);
                            break;

                        case lexer::Token::num:
                            cons->is_function = false;
                            cons->car = new num_node(lex_.get_lex().num);
                            break;

                        case lexer::Token::right:
                            delete cons;
                            return nil;

                        case lexer::Token::left:
                            cons->is_function = true;
                            cons->car = sexp_car_parse(true);
                            break;

                        default:
                            assert(false);
                    }
                    cons->cdr = sexp_cdr_parse();
                    return cons;
                }

            private:
                lexer::lexical_analyser<Iteratable> lex_;

            public:
                static cons_node* nil;

        };

        template <typename T>
        cons_node* s_expression_parser<T>::nil = new cons_node();

        template<typename T>
        auto _print_cons(expr_node* node, int depth)
            -> void
        {
            if (node->type == node_type::num) {
                auto vn = static_cast<num_node*>(node);
                std::cout << std::string(" ", depth) << vn->val << std::endl;
            } else if (node->type == node_type::string) {
                auto vn = static_cast<string_node*>(node);
                std::cout << std::string(" ", depth) << vn->val << std::endl;
            } else if (node->type == node_type::cons) {
                auto n = static_cast<cons_node*>(node);
                if (s_expression_parser<T>::nil == n) {
                    return;
                }

                _print_cons<T>(n->car, depth);
                if (n->is_function){
                    depth++;
                }
                _print_cons<T>(n->cdr, depth);
            }
        }

        template<typename T>
        auto print_cons(expr_node* node)
            -> void
        {
            _print_cons<T>(node, 0);
        }

    } // namespace parser
} // namespace popo
<|endoftext|>


<commit_before>// pythia8 basic example
//Author: Andreas Morsch
//
// to run, do
//  root > .x pythia8.C
//
// Note that before executing this script,
//   -the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
//   -the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
//
void pythia8(Int_t nev  = 100, Int_t ndeb = 1)
{
   char *p8dataenv = gSystem->Getenv("PYTHIA8DATA");
   if (!p8dataenv) {
      char *p8env = gSystem->Getenv("PYTHIA8");
      if (!p8env) {
         Error("pythia8.C",
               "Environment variable PYTHIA8 must contain path to pythi8 directory !");
         return;
      }
      TString p8d = gSystem->Getenv("PYTHIA8");
      p8d += "/xmldoc";
      gSystem->Setenv("PYTHIA8DATA", p8d);
   }

   char* path = gSystem->ExpandPathName("$PYTHIA8DATA");
   if (gSystem->AccessPathName(path)) {
         Error("pythia8.C",
               "Environment variable PYTHIA8DATA must contain path to pythi8/xmldoc directory !");
      return;
   }

// Load libraries
   gSystem->Load("$PYTHIA8/lib/libpythia8");
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("SoftQCD:minBias = on");
   pythia8->ReadString("SoftQCD:singleDiffractive = on");
   pythia8->ReadString("SoftQCD:doubleDiffractive = on");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<commit_msg>Spelling.<commit_after>// pythia8 basic example
//Author: Andreas Morsch
//
// to run, do
//  root > .x pythia8.C
//
// Note that before executing this script,
//   -the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
//   -the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
//
void pythia8(Int_t nev  = 100, Int_t ndeb = 1)
{
   char *p8dataenv = gSystem->Getenv("PYTHIA8DATA");
   if (!p8dataenv) {
      char *p8env = gSystem->Getenv("PYTHIA8");
      if (!p8env) {
         Error("pythia8.C",
               "Environment variable PYTHIA8 must contain path to pythia directory!");
         return;
      }
      TString p8d = p8env;
      p8d += "/xmldoc";
      gSystem->Setenv("PYTHIA8DATA", p8d);
   }

   char* path = gSystem->ExpandPathName("$PYTHIA8DATA");
   if (gSystem->AccessPathName(path)) {
         Error("pythia8.C",
               "Environment variable PYTHIA8DATA must contain path to $PYTHIA8/xmldoc directory !");
      return;
   }

// Load libraries
   gSystem->Load("$PYTHIA8/lib/libpythia8");
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("SoftQCD:minBias = on");
   pythia8->ReadString("SoftQCD:singleDiffractive = on");
   pythia8->ReadString("SoftQCD:doubleDiffractive = on");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_pythia
/// pythia8 basic example
///
/// to run, do:
///
/// ~~~{.cpp}
///  root > .x pythia8.C
/// ~~~
///
/// Note that before executing this script, for some Pythia8 builds:
///
///  - the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
///  - the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
///
/// \macro_code
///
/// \author Andreas Morsch

#include "TSystem.h"
#include "TH1F.h"
#include "TClonesArray.h"
#include "TPythia8.h"
#include "TParticle.h"
#include "TDatabasePDG.h"
#include "TCanvas.h"

void pythia8(Int_t nev  = 100, Int_t ndeb = 1)
{
// Load libraries
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("HardQCD:all = on");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<commit_msg>[tutorial,pythia8] Try to work around timeout on Fed28.<commit_after>/// \file
/// \ingroup tutorial_pythia
/// pythia8 basic example
///
/// to run, do:
///
/// ~~~{.cpp}
///  root > .x pythia8.C
/// ~~~
///
/// Note that before executing this script, for some Pythia8 builds:
///
///  - the env variable PYTHIA8 must point to the pythia8100 (or newer) directory
///  - the env variable PYTHIA8DATA must be defined and it must point to $PYTHIA8/xmldoc
///
/// \macro_code
///
/// \author Andreas Morsch

#include "TSystem.h"
#include "TH1F.h"
#include "TClonesArray.h"
#include "TPythia8.h"
#include "TParticle.h"
#include "TDatabasePDG.h"
#include "TCanvas.h"

void pythia8(Int_t nev  = 100, Int_t ndeb = 1)
{
// Load libraries
   gSystem->Load("libEG");
   gSystem->Load("libEGPythia8");
// Histograms
   TH1F* etaH = new TH1F("etaH", "Pseudorapidity", 120, -12., 12.);
   TH1F* ptH  = new TH1F("ptH",  "pt",              50,   0., 10.);

// Array of particles
   TClonesArray* particles = new TClonesArray("TParticle", 1000);
// Create pythia8 object
   TPythia8* pythia8 = new TPythia8();

// Configure
   pythia8->ReadString("HardQCD:all = on");
   pythia8->ReadString("Random:setSeed = on");
   // use a reproducible seed: always the same results for the tutorial.
   pythia8->ReadString("Random:seed = 42");

// Initialize

   pythia8->Initialize(2212 /* p */, 2212 /* p */, 14000. /* TeV */);

// Event loop
   for (Int_t iev = 0; iev < nev; iev++) {
      pythia8->GenerateEvent();
      if (iev < ndeb) pythia8->EventListing();
      pythia8->ImportParticles(particles,"All");
      Int_t np = particles->GetEntriesFast();
// Particle loop
      for (Int_t ip = 0; ip < np; ip++) {
         TParticle* part = (TParticle*) particles->At(ip);
         Int_t ist = part->GetStatusCode();
         // Positive codes are final particles.
         if (ist <= 0) continue;
         Int_t pdg = part->GetPdgCode();
         Float_t charge = TDatabasePDG::Instance()->GetParticle(pdg)->Charge();
         if (charge == 0.) continue;
         Float_t eta = part->Eta();
         Float_t pt  = part->Pt();

         etaH->Fill(eta);
         if (pt > 0.) ptH->Fill(pt, 1./(2. * pt));
      }
   }

   pythia8->PrintStatistics();

   TCanvas* c1 = new TCanvas("c1","Pythia8 test example",800,800);
   c1->Divide(1, 2);
   c1->cd(1);
   etaH->Scale(5./Float_t(nev));
   etaH->Draw();
   etaH->SetXTitle("#eta");
   etaH->SetYTitle("dN/d#eta");

   c1->cd(2);
   gPad->SetLogy();
   ptH->Scale(5./Float_t(nev));
   ptH->Draw();
   ptH->SetXTitle("p_{t} [GeV/c]");
   ptH->SetYTitle("dN/dp_{t}^{2} [GeV/c]^{-2}");
 }
<|endoftext|>


<commit_before>#include "customizer.h"

#include <QtWidgets/QApplication>

#include <qrkernel/settingsManager.h>

using namespace interpreterCore;

QString Customizer::windowTitle() const
{
	return QObject::tr("Trik Studio") + " " + productVersion();
}

QIcon Customizer::applicationIcon() const
{
	return QIcon(":/icons/icon.png");
}

QImage Customizer::applicationLogo() const
{
	return QImage(":/icons/splashscreen.png");
}

QString Customizer::productVersion() const
{
	/// @todo other storage for it?
	return "3.0.0 α9";
}

QString Customizer::aboutText() const
{
	return "" + windowTitle() + "

http://robots.qreal.ru/";
}

QString Customizer::examplesDirectory() const
{
	return QApplication::applicationDirPath() + "/examples";
}

bool Customizer::showInterpeterButton() const
{
	return false;
}

void Customizer::customizeDocks(qReal::gui::MainWindowDockInterface *dockInterface)
{
	mDockInterface = dockInterface;
	dockInterface->logicalModelDock()->hide();
	dockInterface->tabifyDockWidget(dockInterface->graphicalModelDock(), dockInterface->propertyEditorDock());
	dockInterface->graphicalModelDock()->setWindowTitle(QObject::tr("Blocks"));
}

void Customizer::placeDevicesConfig(QWidget *devicesWidget)
{
	QDockWidget *devicesDock = produceDockWidget(QObject::tr("Configure devices"), devicesWidget);
	mDockInterface->addDockWidget(Qt::LeftDockWidgetArea, devicesDock);
}

void Customizer::placeWatchPlugins(QDockWidget *watchWindow, QWidget *graphicsWatch)
{
	mDockInterface->addDockWidget(Qt::LeftDockWidgetArea, watchWindow);
	watchWindow->setFloating(false);
	QDockWidget *graphWatchDock = produceDockWidget(QObject::tr("Sensors state"), graphicsWatch);
	mDockInterface->addDockWidget(Qt::LeftDockWidgetArea, graphWatchDock);

	mDockInterface->tabifyDockWidget(watchWindow, graphWatchDock);
}

QDockWidget *Customizer::produceDockWidget(QString const &title, QWidget *content) const
{
	QDockWidget *dock = new QDockWidget(title);
	dock->setWidget(content);
	return dock;
}

QString Customizer::userPaletteTitle() const
{
	return QObject::tr("Subprograms");
}

QString Customizer::userPaletteDescription() const
{
	return QObject::tr("The list of all declared subprograms in the project");
}
<commit_msg>Temporary removed graphics watcher<commit_after>#include "customizer.h"

#include <QtWidgets/QApplication>

#include <qrkernel/settingsManager.h>

using namespace interpreterCore;

QString Customizer::windowTitle() const
{
	return QObject::tr("Trik Studio") + " " + productVersion();
}

QIcon Customizer::applicationIcon() const
{
	return QIcon(":/icons/icon.png");
}

QImage Customizer::applicationLogo() const
{
	return QImage(":/icons/splashscreen.png");
}

QString Customizer::productVersion() const
{
	/// @todo other storage for it?
	return "3.0.0 α9";
}

QString Customizer::aboutText() const
{
	return "" + windowTitle() + "

http://robots.qreal.ru/";
}

QString Customizer::examplesDirectory() const
{
	return QApplication::applicationDirPath() + "/examples";
}

bool Customizer::showInterpeterButton() const
{
	return false;
}

void Customizer::customizeDocks(qReal::gui::MainWindowDockInterface *dockInterface)
{
	mDockInterface = dockInterface;
	dockInterface->logicalModelDock()->hide();
	dockInterface->tabifyDockWidget(dockInterface->graphicalModelDock(), dockInterface->propertyEditorDock());
	dockInterface->graphicalModelDock()->setWindowTitle(QObject::tr("Blocks"));
}

void Customizer::placeDevicesConfig(QWidget *devicesWidget)
{
	QDockWidget *devicesDock = produceDockWidget(QObject::tr("Configure devices"), devicesWidget);
	mDockInterface->addDockWidget(Qt::LeftDockWidgetArea, devicesDock);
}

void Customizer::placeWatchPlugins(QDockWidget *watchWindow, QWidget *graphicsWatch)
{
	mDockInterface->addDockWidget(Qt::LeftDockWidgetArea, watchWindow);
	watchWindow->setFloating(false);
	/// @todo: Restore plotter when everything will be fine...
	Q_UNUSED(graphicsWatch)
	// QDockWidget *graphWatchDock = produceDockWidget(QObject::tr("Sensors state"), graphicsWatch);
	// mDockInterface->addDockWidget(Qt::LeftDockWidgetArea, graphWatchDock);

	// mDockInterface->tabifyDockWidget(watchWindow, graphWatchDock);
}

QDockWidget *Customizer::produceDockWidget(QString const &title, QWidget *content) const
{
	QDockWidget *dock = new QDockWidget(title);
	dock->setWidget(content);
	return dock;
}

QString Customizer::userPaletteTitle() const
{
	return QObject::tr("Subprograms");
}

QString Customizer::userPaletteDescription() const
{
	return QObject::tr("The list of all declared subprograms in the project");
}
<|endoftext|>


<commit_before>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __STOUT_ABORT_HPP__
#define __STOUT_ABORT_HPP__

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __WINDOWS__
#include <stout/windows.hpp>
#else
#include <unistd.h>
#endif // __WINDOWS__

#include <string>

#include <stout/attributes.hpp>

// Signal safe abort which prints a message.
#define __STRINGIZE(x) #x
#define _STRINGIZE(x) __STRINGIZE(x)
#define _ABORT_PREFIX "ABORT: (" __FILE__ ":" _STRINGIZE(__LINE__) "): "

#define ABORT(...) _Abort(_ABORT_PREFIX, __VA_ARGS__)

inline NORETURN void _Abort(const char* prefix, const char* message)
{
  // Write the failure message in an async-signal safe manner,
  // assuming strlen is async-signal safe or optimized out.
  // In fact, it is highly unlikely that strlen would be
  // implemented in an unsafe manner:
  // http://austingroupbugs.net/view.php?id=692
  while (write(STDERR_FILENO, prefix, strlen(prefix)) == -1 &&
         errno == EINTR);
  while (message != NULL &&
         write(STDERR_FILENO, message, strlen(message)) == -1 &&
         errno == EINTR);
  abort();
}

inline NORETURN void _Abort(const char* prefix, const std::string& message)
{
  _Abort(prefix, message.c_str());
}

#endif // __STOUT_ABORT_HPP__
<commit_msg>Added a trailing newline to the ABORT() output.<commit_after>/**
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
#ifndef __STOUT_ABORT_HPP__
#define __STOUT_ABORT_HPP__

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __WINDOWS__
#include <stout/windows.hpp>
#else
#include <unistd.h>
#endif // __WINDOWS__

#include <string>

#include <stout/attributes.hpp>

// Signal safe abort which prints a message.
#define __STRINGIZE(x) #x
#define _STRINGIZE(x) __STRINGIZE(x)
#define _ABORT_PREFIX "ABORT: (" __FILE__ ":" _STRINGIZE(__LINE__) "): "

#define ABORT(...) _Abort(_ABORT_PREFIX, __VA_ARGS__)

inline NORETURN void _Abort(const char* prefix, const char* message)
{
  // Write the failure message in an async-signal safe manner,
  // assuming strlen is async-signal safe or optimized out.
  // In fact, it is highly unlikely that strlen would be
  // implemented in an unsafe manner:
  // http://austingroupbugs.net/view.php?id=692
  while (write(STDERR_FILENO, prefix, strlen(prefix)) == -1 &&
         errno == EINTR);
  while (message != NULL &&
         write(STDERR_FILENO, message, strlen(message)) == -1 &&
         errno == EINTR);
  while (write(STDERR_FILENO, "\n", 1) == -1 && errno == EINTR);
  abort();
}

inline NORETURN void _Abort(const char* prefix, const std::string& message)
{
  _Abort(prefix, message.c_str());
}

#endif // __STOUT_ABORT_HPP__
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2627
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1538669 by johtaylo@johtaylo-jtincrementor2-increment on 2018/04/10 03:00:05<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2628
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2519
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1470466 by johtaylo@johtaylo-jtincrementor2-increment on 2017/10/16 03:00:05<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2520
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2890
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1778587 by chui@ocl-promo-incrementor on 2019/05/06 03:00:17<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2891
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2696
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1581943 by chui@ocl-promo-incrementor on 2018/07/18 02:56:41<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
#define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif  // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
#define AMD_PLATFORM_BUILD_NUMBER 2697
#endif  // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
#define AMD_PLATFORM_REVISION_NUMBER 0
#endif  // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
#define AMD_PLATFORM_RELEASE_INFO
#endif  // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING                                                                           \
  XSTR(AMD_PLATFORM_BUILD_NUMBER)                                                                  \
  "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
#define AMD_PLATFORM_INFO                                                                          \
  "AMD-APP" AMD_PLATFORM_RELEASE_INFO DEBUG_ONLY(                                                  \
      "." IF(IS_OPTIMIZED, "opt", "dbg")) " (" AMD_BUILD_STRING ")"
#endif  // ATI_PLATFORM_INFO

#endif  // VERSIONS_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/thread_restrictions.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/metrics/thread_watcher.h"
#include "chrome/common/notification_service.h"

// static
const int ThreadWatcher::kPingCount = 3;

//------------------------------------------------------------------------------
// ThreadWatcher methods and members.

ThreadWatcher::ThreadWatcher(const BrowserThread::ID thread_id,
                             const std::string& thread_name,
                             const base::TimeDelta& sleep_time,
                             const base::TimeDelta& unresponsive_time)
    : thread_id_(thread_id),
      thread_name_(thread_name),
      sleep_time_(sleep_time),
      unresponsive_time_(unresponsive_time),
      ping_time_(base::TimeTicks::Now()),
      ping_sequence_number_(0),
      active_(false),
      ping_count_(kPingCount),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
  Initialize();
}

ThreadWatcher::~ThreadWatcher() {}

// static
void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id,
                                  const std::string& thread_name,
                                  const base::TimeDelta& sleep_time,
                                  const base::TimeDelta& unresponsive_time) {
  DCHECK_GE(sleep_time.InMilliseconds(), 0);
  DCHECK_GE(unresponsive_time.InMilliseconds(), sleep_time.InMilliseconds());

  // If we are not on WATCHDOG thread, then post a task to call StartWatching on
  // WATCHDOG thread.
  if (!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)) {
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableFunction(
            &ThreadWatcher::StartWatching,
            thread_id, thread_name, sleep_time, unresponsive_time));
    return;
  }

  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));

  // Create a new thread watcher object for the given thread and activate it.
  ThreadWatcher* watcher =
      new ThreadWatcher(thread_id, thread_name, sleep_time, unresponsive_time);
  DCHECK(watcher);
  watcher->ActivateThreadWatching();
}

void ThreadWatcher::ActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  if (active_) return;
  active_ = true;
  ping_count_ = kPingCount;
  MessageLoop::current()->PostTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage));
}

void ThreadWatcher::DeActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  active_ = false;
  ping_count_ = 0;
  method_factory_.RevokeAll();
}

void ThreadWatcher::WakeUp() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // There is some user activity, PostPingMessage task of thread watcher if
  // needed.
  if (!active_) return;

  if (ping_count_ <= 0) {
    ping_count_ = kPingCount;
    PostPingMessage();
  } else {
    ping_count_ = kPingCount;
  }
}

void ThreadWatcher::PostPingMessage() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || ping_count_ <= 0)
    return;

  // Save the current time when we have sent ping message.
  ping_time_ = base::TimeTicks::Now();

  // Send a ping message to the watched thread.
  Task* callback_task = method_factory_.NewRunnableMethod(
      &ThreadWatcher::OnPongMessage, ping_sequence_number_);
  if (BrowserThread::PostTask(
          thread_id(),
          FROM_HERE,
          NewRunnableFunction(
              &ThreadWatcher::OnPingMessage, thread_id_, callback_task))) {
      // Post a task to check the responsiveness of watched thread.
      MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          method_factory_.NewRunnableMethod(
              &ThreadWatcher::OnCheckResponsiveness, ping_sequence_number_),
          unresponsive_time_.InMilliseconds());
  } else {
    // Watched thread might have gone away, stop watching it.
    delete callback_task;
    DeActivateThreadWatching();
  }
}

void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // Record watched thread's response time.
  base::TimeDelta response_time = base::TimeTicks::Now() - ping_time_;
  histogram_->AddTime(response_time);

  // Check if there are any extra pings in flight.
  DCHECK_EQ(ping_sequence_number_, ping_sequence_number);
  if (ping_sequence_number_ != ping_sequence_number)
    return;

  // Increment sequence number for the next ping message to indicate watched
  // thread is responsive.
  ++ping_sequence_number_;

  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || --ping_count_ <= 0)
    return;

  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage),
      sleep_time_.InMilliseconds());
}

bool ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching then consider thread as responding.
  if (!active_)
    return true;
  // If the latest ping_sequence_number_ is not same as the ping_sequence_number
  // that is passed in, then we can assume OnPongMessage was called.
  // OnPongMessage increments ping_sequence_number_.
  if (ping_sequence_number_ != ping_sequence_number)
    return true;
  return false;
}

void ThreadWatcher::Initialize() {
  ThreadWatcherList::Register(this);
  histogram_ = base::Histogram::FactoryTimeGet(
      "ThreadWatcher.ResponseTime." + thread_name_,
      base::TimeDelta::FromMilliseconds(1),
      base::TimeDelta::FromSeconds(100), 50,
      base::Histogram::kUmaTargetedHistogramFlag);
}

// static
void ThreadWatcher::OnPingMessage(const BrowserThread::ID thread_id,
                                  Task* callback_task) {
  // This method is called on watched thread.
  DCHECK(BrowserThread::CurrentlyOn(thread_id));
  BrowserThread::PostTask(BrowserThread::WATCHDOG, FROM_HERE, callback_task);
}

//------------------------------------------------------------------------------
// ThreadWatcherList methods and members.

// static
ThreadWatcherList* ThreadWatcherList::global_ = NULL;

ThreadWatcherList::ThreadWatcherList()
    : last_wakeup_time_(base::TimeTicks::Now()) {
  // Assert we are not running on WATCHDOG thread. Would be ideal to assert we
  // are on UI thread, but Unit tests are not running on UI thread.
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  DCHECK(!global_);
  global_ = this;
  // Register Notifications observer.
  MetricsService::SetupNotifications(&registrar_, this);
}

ThreadWatcherList::~ThreadWatcherList() {
  base::AutoLock auto_lock(lock_);
  while (!registered_.empty()) {
    RegistrationList::iterator it = registered_.begin();
    delete it->second;
    registered_.erase(it->first);
  }
  DCHECK(this == global_);
  global_ = NULL;
}

// static
void ThreadWatcherList::Register(ThreadWatcher* watcher) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  DCHECK(!global_->PreLockedFind(watcher->thread_id()));
  global_->registered_[watcher->thread_id()] = watcher;
}

// static
void ThreadWatcherList::StopWatchingAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(
            it->second, &ThreadWatcher::DeActivateThreadWatching));
}

// static
void ThreadWatcherList::RemoveNotifications() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
  global_->registrar_.RemoveAll();
}

void ThreadWatcherList::Observe(NotificationType type,
                                const NotificationSource& source,
                                const NotificationDetails& details) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // There is some user activity, see if thread watchers are to be awakened.
  bool need_to_awaken = false;
  base::TimeTicks now = base::TimeTicks::Now();
  {
    base::AutoLock lock(lock_);
    if (now - last_wakeup_time_ > base::TimeDelta::FromSeconds(2)) {
      need_to_awaken = true;
      last_wakeup_time_ = now;
    }
  }
  if (need_to_awaken)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll));
}

void ThreadWatcherList::WakeUpAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  base::AutoLock auto_lock(lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    it->second->WakeUp();
}

// static
ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID thread_id) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  return global_->PreLockedFind(thread_id);
}

ThreadWatcher* ThreadWatcherList::PreLockedFind(
    const BrowserThread::ID thread_id) {
  RegistrationList::iterator it = registered_.find(thread_id);
  if (registered_.end() == it)
    return NULL;
  return it->second;
}

//------------------------------------------------------------------------------
// WatchDogThread methods and members.

// The WatchDogThread object must outlive any tasks posted to the IO thread
// before the Quit task.
DISABLE_RUNNABLE_METHOD_REFCOUNT(WatchDogThread);

WatchDogThread::WatchDogThread()
    : BrowserProcessSubThread(BrowserThread::WATCHDOG) {
}

WatchDogThread::~WatchDogThread() {
  // Remove all notifications for all watched threads.
  ThreadWatcherList::RemoveNotifications();
  // We cannot rely on our base class to stop the thread since we want our
  // CleanUp function to run.
  Stop();
}

void WatchDogThread::Init() {
  // This thread shouldn't be allowed to perform any blocking disk I/O.
  base::ThreadRestrictions::SetIOAllowed(false);

  BrowserProcessSubThread::Init();

  const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5);
  const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10);
  ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime,
                               kUnresponsiveTime);
}
<commit_msg>Stop thread watching on Mac to fix memory usage on mac-release-10.5/intl2.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/thread_restrictions.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/metrics/thread_watcher.h"
#include "chrome/common/notification_service.h"

// static
const int ThreadWatcher::kPingCount = 3;

//------------------------------------------------------------------------------
// ThreadWatcher methods and members.

ThreadWatcher::ThreadWatcher(const BrowserThread::ID thread_id,
                             const std::string& thread_name,
                             const base::TimeDelta& sleep_time,
                             const base::TimeDelta& unresponsive_time)
    : thread_id_(thread_id),
      thread_name_(thread_name),
      sleep_time_(sleep_time),
      unresponsive_time_(unresponsive_time),
      ping_time_(base::TimeTicks::Now()),
      ping_sequence_number_(0),
      active_(false),
      ping_count_(kPingCount),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
  Initialize();
}

ThreadWatcher::~ThreadWatcher() {}

// static
void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id,
                                  const std::string& thread_name,
                                  const base::TimeDelta& sleep_time,
                                  const base::TimeDelta& unresponsive_time) {
  DCHECK_GE(sleep_time.InMilliseconds(), 0);
  DCHECK_GE(unresponsive_time.InMilliseconds(), sleep_time.InMilliseconds());

  // If we are not on WATCHDOG thread, then post a task to call StartWatching on
  // WATCHDOG thread.
  if (!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)) {
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableFunction(
            &ThreadWatcher::StartWatching,
            thread_id, thread_name, sleep_time, unresponsive_time));
    return;
  }

  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));

  // Create a new thread watcher object for the given thread and activate it.
  ThreadWatcher* watcher =
      new ThreadWatcher(thread_id, thread_name, sleep_time, unresponsive_time);
  DCHECK(watcher);
  watcher->ActivateThreadWatching();
}

void ThreadWatcher::ActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  if (active_) return;
  active_ = true;
  ping_count_ = kPingCount;
  MessageLoop::current()->PostTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage));
}

void ThreadWatcher::DeActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  active_ = false;
  ping_count_ = 0;
  method_factory_.RevokeAll();
}

void ThreadWatcher::WakeUp() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // There is some user activity, PostPingMessage task of thread watcher if
  // needed.
  if (!active_) return;

  if (ping_count_ <= 0) {
    ping_count_ = kPingCount;
    PostPingMessage();
  } else {
    ping_count_ = kPingCount;
  }
}

void ThreadWatcher::PostPingMessage() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || ping_count_ <= 0)
    return;

  // Save the current time when we have sent ping message.
  ping_time_ = base::TimeTicks::Now();

  // Send a ping message to the watched thread.
  Task* callback_task = method_factory_.NewRunnableMethod(
      &ThreadWatcher::OnPongMessage, ping_sequence_number_);
  if (BrowserThread::PostTask(
          thread_id(),
          FROM_HERE,
          NewRunnableFunction(
              &ThreadWatcher::OnPingMessage, thread_id_, callback_task))) {
      // Post a task to check the responsiveness of watched thread.
      MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          method_factory_.NewRunnableMethod(
              &ThreadWatcher::OnCheckResponsiveness, ping_sequence_number_),
          unresponsive_time_.InMilliseconds());
  } else {
    // Watched thread might have gone away, stop watching it.
    delete callback_task;
    DeActivateThreadWatching();
  }
}

void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // Record watched thread's response time.
  base::TimeDelta response_time = base::TimeTicks::Now() - ping_time_;
  histogram_->AddTime(response_time);

  // Check if there are any extra pings in flight.
  DCHECK_EQ(ping_sequence_number_, ping_sequence_number);
  if (ping_sequence_number_ != ping_sequence_number)
    return;

  // Increment sequence number for the next ping message to indicate watched
  // thread is responsive.
  ++ping_sequence_number_;

  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || --ping_count_ <= 0)
    return;

  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage),
      sleep_time_.InMilliseconds());
}

bool ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching then consider thread as responding.
  if (!active_)
    return true;
  // If the latest ping_sequence_number_ is not same as the ping_sequence_number
  // that is passed in, then we can assume OnPongMessage was called.
  // OnPongMessage increments ping_sequence_number_.
  if (ping_sequence_number_ != ping_sequence_number)
    return true;
  return false;
}

void ThreadWatcher::Initialize() {
  ThreadWatcherList::Register(this);
  histogram_ = base::Histogram::FactoryTimeGet(
      "ThreadWatcher.ResponseTime." + thread_name_,
      base::TimeDelta::FromMilliseconds(1),
      base::TimeDelta::FromSeconds(100), 50,
      base::Histogram::kUmaTargetedHistogramFlag);
}

// static
void ThreadWatcher::OnPingMessage(const BrowserThread::ID thread_id,
                                  Task* callback_task) {
  // This method is called on watched thread.
  DCHECK(BrowserThread::CurrentlyOn(thread_id));
  BrowserThread::PostTask(BrowserThread::WATCHDOG, FROM_HERE, callback_task);
}

//------------------------------------------------------------------------------
// ThreadWatcherList methods and members.

// static
ThreadWatcherList* ThreadWatcherList::global_ = NULL;

ThreadWatcherList::ThreadWatcherList()
    : last_wakeup_time_(base::TimeTicks::Now()) {
  // Assert we are not running on WATCHDOG thread. Would be ideal to assert we
  // are on UI thread, but Unit tests are not running on UI thread.
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  DCHECK(!global_);
  global_ = this;
  // Register Notifications observer.
#if !defined(OS_MACOSX)
  MetricsService::SetupNotifications(&registrar_, this);
#endif
}

ThreadWatcherList::~ThreadWatcherList() {
  base::AutoLock auto_lock(lock_);
  while (!registered_.empty()) {
    RegistrationList::iterator it = registered_.begin();
    delete it->second;
    registered_.erase(it->first);
  }
  DCHECK(this == global_);
  global_ = NULL;
}

// static
void ThreadWatcherList::Register(ThreadWatcher* watcher) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  DCHECK(!global_->PreLockedFind(watcher->thread_id()));
  global_->registered_[watcher->thread_id()] = watcher;
}

// static
void ThreadWatcherList::StopWatchingAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(
            it->second, &ThreadWatcher::DeActivateThreadWatching));
}

// static
void ThreadWatcherList::RemoveNotifications() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
#if !defined(OS_MACOSX)
  global_->registrar_.RemoveAll();
#endif
}

void ThreadWatcherList::Observe(NotificationType type,
                                const NotificationSource& source,
                                const NotificationDetails& details) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // There is some user activity, see if thread watchers are to be awakened.
  bool need_to_awaken = false;
  base::TimeTicks now = base::TimeTicks::Now();
  {
    base::AutoLock lock(lock_);
    if (now - last_wakeup_time_ > base::TimeDelta::FromSeconds(2)) {
      need_to_awaken = true;
      last_wakeup_time_ = now;
    }
  }
  if (need_to_awaken)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll));
}

void ThreadWatcherList::WakeUpAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  base::AutoLock auto_lock(lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    it->second->WakeUp();
}

// static
ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID thread_id) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  return global_->PreLockedFind(thread_id);
}

ThreadWatcher* ThreadWatcherList::PreLockedFind(
    const BrowserThread::ID thread_id) {
  RegistrationList::iterator it = registered_.find(thread_id);
  if (registered_.end() == it)
    return NULL;
  return it->second;
}

//------------------------------------------------------------------------------
// WatchDogThread methods and members.

// The WatchDogThread object must outlive any tasks posted to the IO thread
// before the Quit task.
DISABLE_RUNNABLE_METHOD_REFCOUNT(WatchDogThread);

WatchDogThread::WatchDogThread()
    : BrowserProcessSubThread(BrowserThread::WATCHDOG) {
}

WatchDogThread::~WatchDogThread() {
  // Remove all notifications for all watched threads.
  ThreadWatcherList::RemoveNotifications();
  // We cannot rely on our base class to stop the thread since we want our
  // CleanUp function to run.
  Stop();
}

void WatchDogThread::Init() {
  // This thread shouldn't be allowed to perform any blocking disk I/O.
  base::ThreadRestrictions::SetIOAllowed(false);

  BrowserProcessSubThread::Init();

#if !defined(OS_MACOSX)
  const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5);
  const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10);
  ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime,
                               kUnresponsiveTime);
#endif
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2216
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<commit_msg>P4 to Git Change 1310723 by johtaylo@johtaylo-JTBUILDER03-increment on 2016/09/04 03:00:08<commit_after>//
// Copyright (c) 2010 Advanced Micro Devices, Inc. All rights reserved.
//

#ifndef VERSIONS_HPP_
#define VERSIONS_HPP_

#include "utils/macros.hpp"

#ifndef AMD_PLATFORM_NAME
# define AMD_PLATFORM_NAME "AMD Accelerated Parallel Processing"
#endif // AMD_PLATFORM_NAME

#ifndef AMD_PLATFORM_BUILD_NUMBER
# define AMD_PLATFORM_BUILD_NUMBER 2217
#endif // AMD_PLATFORM_BUILD_NUMBER

#ifndef AMD_PLATFORM_REVISION_NUMBER
# define AMD_PLATFORM_REVISION_NUMBER 0
#endif // AMD_PLATFORM_REVISION_NUMBER

#ifndef AMD_PLATFORM_RELEASE_INFO
# define AMD_PLATFORM_RELEASE_INFO
#endif // AMD_PLATFORM_RELEASE_INFO

#define AMD_BUILD_STRING XSTR(AMD_PLATFORM_BUILD_NUMBER) \
    "." XSTR(AMD_PLATFORM_REVISION_NUMBER)

#ifndef AMD_PLATFORM_INFO
# define AMD_PLATFORM_INFO "AMD-APP" AMD_PLATFORM_RELEASE_INFO \
    DEBUG_ONLY("." IF(IS_OPTIMIZED,"opt","dbg")) " (" AMD_BUILD_STRING ")"
#endif // ATI_PLATFORM_INFO

#endif // VERSIONS_HPP_
<|endoftext|>


<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/thread_restrictions.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/metrics/thread_watcher.h"
#include "chrome/common/notification_service.h"

// static
const int ThreadWatcher::kPingCount = 3;

//------------------------------------------------------------------------------
// ThreadWatcher methods and members.

ThreadWatcher::ThreadWatcher(const BrowserThread::ID thread_id,
                             const std::string& thread_name,
                             const base::TimeDelta& sleep_time,
                             const base::TimeDelta& unresponsive_time)
    : thread_id_(thread_id),
      thread_name_(thread_name),
      sleep_time_(sleep_time),
      unresponsive_time_(unresponsive_time),
      ping_time_(base::TimeTicks::Now()),
      ping_sequence_number_(0),
      active_(false),
      ping_count_(kPingCount),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
  Initialize();
}

ThreadWatcher::~ThreadWatcher() {}

// static
void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id,
                                  const std::string& thread_name,
                                  const base::TimeDelta& sleep_time,
                                  const base::TimeDelta& unresponsive_time) {
  DCHECK_GE(sleep_time.InMilliseconds(), 0);
  DCHECK_GE(unresponsive_time.InMilliseconds(), sleep_time.InMilliseconds());

  // If we are not on WATCHDOG thread, then post a task to call StartWatching on
  // WATCHDOG thread.
  if (!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)) {
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableFunction(
            &ThreadWatcher::StartWatching,
            thread_id, thread_name, sleep_time, unresponsive_time));
    return;
  }

  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));

  // Create a new thread watcher object for the given thread and activate it.
  ThreadWatcher* watcher =
      new ThreadWatcher(thread_id, thread_name, sleep_time, unresponsive_time);
  DCHECK(watcher);
  watcher->ActivateThreadWatching();
}

void ThreadWatcher::ActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  if (active_) return;
  active_ = true;
  ping_count_ = kPingCount;
  MessageLoop::current()->PostTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage));
}

void ThreadWatcher::DeActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  active_ = false;
  ping_count_ = 0;
  method_factory_.RevokeAll();
}

void ThreadWatcher::WakeUp() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // There is some user activity, PostPingMessage task of thread watcher if
  // needed.
  if (!active_) return;

  if (ping_count_ <= 0) {
    ping_count_ = kPingCount;
    PostPingMessage();
  } else {
    ping_count_ = kPingCount;
  }
}

void ThreadWatcher::PostPingMessage() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || ping_count_ <= 0)
    return;

  // Save the current time when we have sent ping message.
  ping_time_ = base::TimeTicks::Now();

  // Send a ping message to the watched thread.
  Task* callback_task = method_factory_.NewRunnableMethod(
      &ThreadWatcher::OnPongMessage, ping_sequence_number_);
  BrowserThread::PostTask(
      thread_id(),
      FROM_HERE,
      NewRunnableFunction(
          &ThreadWatcher::OnPingMessage, thread_id_, callback_task));

  // Post a task to check the responsiveness of watched thread.
  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(
          &ThreadWatcher::OnCheckResponsiveness, ping_sequence_number_),
      unresponsive_time_.InMilliseconds());
}

void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // Record watched thread's response time.
  base::TimeDelta response_time = base::TimeTicks::Now() - ping_time_;
  histogram_->AddTime(response_time);

  // Check if there are any extra pings in flight.
  DCHECK_EQ(ping_sequence_number_, ping_sequence_number);
  if (ping_sequence_number_ != ping_sequence_number)
    return;

  // Increment sequence number for the next ping message to indicate watched
  // thread is responsive.
  ++ping_sequence_number_;

  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || --ping_count_ <= 0)
    return;

  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage),
      sleep_time_.InMilliseconds());
}

bool ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching then consider thread as responding.
  if (!active_)
    return true;
  // If the latest ping_sequence_number_ is not same as the ping_sequence_number
  // that is passed in, then we can assume OnPongMessage was called.
  // OnPongMessage increments ping_sequence_number_.
  if (ping_sequence_number_ != ping_sequence_number)
    return true;
  return false;
}

void ThreadWatcher::Initialize() {
  ThreadWatcherList::Register(this);
  histogram_ = base::Histogram::FactoryTimeGet(
      "ThreadWatcher.ResponseTime." + thread_name_,
      base::TimeDelta::FromMilliseconds(1),
      base::TimeDelta::FromSeconds(100), 50,
      base::Histogram::kUmaTargetedHistogramFlag);
}

// static
void ThreadWatcher::OnPingMessage(const BrowserThread::ID thread_id,
                                  Task* callback_task) {
  // This method is called on watched thread.
  DCHECK(BrowserThread::CurrentlyOn(thread_id));
  BrowserThread::PostTask(BrowserThread::WATCHDOG, FROM_HERE, callback_task);
}

//------------------------------------------------------------------------------
// ThreadWatcherList methods and members.

// static
ThreadWatcherList* ThreadWatcherList::global_ = NULL;

ThreadWatcherList::ThreadWatcherList()
    : last_wakeup_time_(base::TimeTicks::Now()) {
  // Assert we are not running on WATCHDOG thread. Would be ideal to assert we
  // are on UI thread, but Unit tests are not running on UI thread.
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  DCHECK(!global_);
  global_ = this;
  // Register Notifications observer.
  MetricsService::SetupNotifications(&registrar_, this);
}

ThreadWatcherList::~ThreadWatcherList() {
  base::AutoLock auto_lock(lock_);
  while (!registered_.empty()) {
    RegistrationList::iterator it = registered_.begin();
    delete it->second;
    registered_.erase(it->first);
  }
  DCHECK(this == global_);
  global_ = NULL;
}

// static
void ThreadWatcherList::Register(ThreadWatcher* watcher) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  DCHECK(!global_->PreLockedFind(watcher->thread_id()));
  global_->registered_[watcher->thread_id()] = watcher;
}

// static
void ThreadWatcherList::StopWatchingAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(
            it->second, &ThreadWatcher::DeActivateThreadWatching));
}

// static
void ThreadWatcherList::RemoveNotifications() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
  global_->registrar_.RemoveAll();
}

void ThreadWatcherList::Observe(NotificationType type,
                                const NotificationSource& source,
                                const NotificationDetails& details) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // There is some user activity, see if thread watchers are to be awakened.
  bool need_to_awaken = false;
  base::TimeTicks now = base::TimeTicks::Now();
  {
    base::AutoLock lock(lock_);
    if (now - last_wakeup_time_ > base::TimeDelta::FromSeconds(2)) {
      need_to_awaken = true;
      last_wakeup_time_ = now;
    }
  }
  if (need_to_awaken)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll));
}

void ThreadWatcherList::WakeUpAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  base::AutoLock auto_lock(lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    it->second->WakeUp();
}

// static
ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID thread_id) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  return global_->PreLockedFind(thread_id);
}

ThreadWatcher* ThreadWatcherList::PreLockedFind(
    const BrowserThread::ID thread_id) {
  RegistrationList::iterator it = registered_.find(thread_id);
  if (registered_.end() == it)
    return NULL;
  return it->second;
}

//------------------------------------------------------------------------------
// WatchDogThread methods and members.

// The WatchDogThread object must outlive any tasks posted to the IO thread
// before the Quit task.
DISABLE_RUNNABLE_METHOD_REFCOUNT(WatchDogThread);

WatchDogThread::WatchDogThread()
    : BrowserProcessSubThread(BrowserThread::WATCHDOG) {
}

WatchDogThread::~WatchDogThread() {
  // Remove all notifications for all watched threads.
  ThreadWatcherList::RemoveNotifications();
  // We cannot rely on our base class to stop the thread since we want our
  // CleanUp function to run.
  Stop();
}

void WatchDogThread::Init() {
  // This thread shouldn't be allowed to perform any blocking disk I/O.
  base::ThreadRestrictions::SetIOAllowed(false);

  BrowserProcessSubThread::Init();

  const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5);
  const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10);
  ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime,
                               kUnresponsiveTime);
}
<commit_msg>Fixed the memory leak of callback Task in PostPingMessage. If PostTask to watched thread fails, we will stop monitoring that thread.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/thread_restrictions.h"
#include "chrome/browser/metrics/metrics_service.h"
#include "chrome/browser/metrics/thread_watcher.h"
#include "chrome/common/notification_service.h"

// static
const int ThreadWatcher::kPingCount = 3;

//------------------------------------------------------------------------------
// ThreadWatcher methods and members.

ThreadWatcher::ThreadWatcher(const BrowserThread::ID thread_id,
                             const std::string& thread_name,
                             const base::TimeDelta& sleep_time,
                             const base::TimeDelta& unresponsive_time)
    : thread_id_(thread_id),
      thread_name_(thread_name),
      sleep_time_(sleep_time),
      unresponsive_time_(unresponsive_time),
      ping_time_(base::TimeTicks::Now()),
      ping_sequence_number_(0),
      active_(false),
      ping_count_(kPingCount),
      ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)) {
  Initialize();
}

ThreadWatcher::~ThreadWatcher() {}

// static
void ThreadWatcher::StartWatching(const BrowserThread::ID thread_id,
                                  const std::string& thread_name,
                                  const base::TimeDelta& sleep_time,
                                  const base::TimeDelta& unresponsive_time) {
  DCHECK_GE(sleep_time.InMilliseconds(), 0);
  DCHECK_GE(unresponsive_time.InMilliseconds(), sleep_time.InMilliseconds());

  // If we are not on WATCHDOG thread, then post a task to call StartWatching on
  // WATCHDOG thread.
  if (!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG)) {
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableFunction(
            &ThreadWatcher::StartWatching,
            thread_id, thread_name, sleep_time, unresponsive_time));
    return;
  }

  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));

  // Create a new thread watcher object for the given thread and activate it.
  ThreadWatcher* watcher =
      new ThreadWatcher(thread_id, thread_name, sleep_time, unresponsive_time);
  DCHECK(watcher);
  watcher->ActivateThreadWatching();
}

void ThreadWatcher::ActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  if (active_) return;
  active_ = true;
  ping_count_ = kPingCount;
  MessageLoop::current()->PostTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage));
}

void ThreadWatcher::DeActivateThreadWatching() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  active_ = false;
  ping_count_ = 0;
  method_factory_.RevokeAll();
}

void ThreadWatcher::WakeUp() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // There is some user activity, PostPingMessage task of thread watcher if
  // needed.
  if (!active_) return;

  if (ping_count_ <= 0) {
    ping_count_ = kPingCount;
    PostPingMessage();
  } else {
    ping_count_ = kPingCount;
  }
}

void ThreadWatcher::PostPingMessage() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || ping_count_ <= 0)
    return;

  // Save the current time when we have sent ping message.
  ping_time_ = base::TimeTicks::Now();

  // Send a ping message to the watched thread.
  Task* callback_task = method_factory_.NewRunnableMethod(
      &ThreadWatcher::OnPongMessage, ping_sequence_number_);
  if (BrowserThread::PostTask(
          thread_id(),
          FROM_HERE,
          NewRunnableFunction(
              &ThreadWatcher::OnPingMessage, thread_id_, callback_task))) {
      // Post a task to check the responsiveness of watched thread.
      MessageLoop::current()->PostDelayedTask(
          FROM_HERE,
          method_factory_.NewRunnableMethod(
              &ThreadWatcher::OnCheckResponsiveness, ping_sequence_number_),
          unresponsive_time_.InMilliseconds());
  } else {
    // Watched thread might have gone away, stop watching it.
    delete callback_task;
    DeActivateThreadWatching();
  }
}

void ThreadWatcher::OnPongMessage(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // Record watched thread's response time.
  base::TimeDelta response_time = base::TimeTicks::Now() - ping_time_;
  histogram_->AddTime(response_time);

  // Check if there are any extra pings in flight.
  DCHECK_EQ(ping_sequence_number_, ping_sequence_number);
  if (ping_sequence_number_ != ping_sequence_number)
    return;

  // Increment sequence number for the next ping message to indicate watched
  // thread is responsive.
  ++ping_sequence_number_;

  // If we have stopped watching or if the user is idle, then stop sending
  // ping messages.
  if (!active_ || --ping_count_ <= 0)
    return;

  MessageLoop::current()->PostDelayedTask(
      FROM_HERE,
      method_factory_.NewRunnableMethod(&ThreadWatcher::PostPingMessage),
      sleep_time_.InMilliseconds());
}

bool ThreadWatcher::OnCheckResponsiveness(uint64 ping_sequence_number) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  // If we have stopped watching then consider thread as responding.
  if (!active_)
    return true;
  // If the latest ping_sequence_number_ is not same as the ping_sequence_number
  // that is passed in, then we can assume OnPongMessage was called.
  // OnPongMessage increments ping_sequence_number_.
  if (ping_sequence_number_ != ping_sequence_number)
    return true;
  return false;
}

void ThreadWatcher::Initialize() {
  ThreadWatcherList::Register(this);
  histogram_ = base::Histogram::FactoryTimeGet(
      "ThreadWatcher.ResponseTime." + thread_name_,
      base::TimeDelta::FromMilliseconds(1),
      base::TimeDelta::FromSeconds(100), 50,
      base::Histogram::kUmaTargetedHistogramFlag);
}

// static
void ThreadWatcher::OnPingMessage(const BrowserThread::ID thread_id,
                                  Task* callback_task) {
  // This method is called on watched thread.
  DCHECK(BrowserThread::CurrentlyOn(thread_id));
  BrowserThread::PostTask(BrowserThread::WATCHDOG, FROM_HERE, callback_task);
}

//------------------------------------------------------------------------------
// ThreadWatcherList methods and members.

// static
ThreadWatcherList* ThreadWatcherList::global_ = NULL;

ThreadWatcherList::ThreadWatcherList()
    : last_wakeup_time_(base::TimeTicks::Now()) {
  // Assert we are not running on WATCHDOG thread. Would be ideal to assert we
  // are on UI thread, but Unit tests are not running on UI thread.
  DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  DCHECK(!global_);
  global_ = this;
  // Register Notifications observer.
  MetricsService::SetupNotifications(&registrar_, this);
}

ThreadWatcherList::~ThreadWatcherList() {
  base::AutoLock auto_lock(lock_);
  while (!registered_.empty()) {
    RegistrationList::iterator it = registered_.begin();
    delete it->second;
    registered_.erase(it->first);
  }
  DCHECK(this == global_);
  global_ = NULL;
}

// static
void ThreadWatcherList::Register(ThreadWatcher* watcher) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  DCHECK(!global_->PreLockedFind(watcher->thread_id()));
  global_->registered_[watcher->thread_id()] = watcher;
}

// static
void ThreadWatcherList::StopWatchingAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(
            it->second, &ThreadWatcher::DeActivateThreadWatching));
}

// static
void ThreadWatcherList::RemoveNotifications() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  if (!global_)
    return;
  base::AutoLock auto_lock(global_->lock_);
  global_->registrar_.RemoveAll();
}

void ThreadWatcherList::Observe(NotificationType type,
                                const NotificationSource& source,
                                const NotificationDetails& details) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  // There is some user activity, see if thread watchers are to be awakened.
  bool need_to_awaken = false;
  base::TimeTicks now = base::TimeTicks::Now();
  {
    base::AutoLock lock(lock_);
    if (now - last_wakeup_time_ > base::TimeDelta::FromSeconds(2)) {
      need_to_awaken = true;
      last_wakeup_time_ = now;
    }
  }
  if (need_to_awaken)
    BrowserThread::PostTask(
        BrowserThread::WATCHDOG,
        FROM_HERE,
        NewRunnableMethod(this, &ThreadWatcherList::WakeUpAll));
}

void ThreadWatcherList::WakeUpAll() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WATCHDOG));
  base::AutoLock auto_lock(lock_);
  for (RegistrationList::iterator it = global_->registered_.begin();
       global_->registered_.end() != it;
       ++it)
    it->second->WakeUp();
}

// static
ThreadWatcher* ThreadWatcherList::Find(const BrowserThread::ID thread_id) {
  DCHECK(global_);
  base::AutoLock auto_lock(global_->lock_);
  return global_->PreLockedFind(thread_id);
}

ThreadWatcher* ThreadWatcherList::PreLockedFind(
    const BrowserThread::ID thread_id) {
  RegistrationList::iterator it = registered_.find(thread_id);
  if (registered_.end() == it)
    return NULL;
  return it->second;
}

//------------------------------------------------------------------------------
// WatchDogThread methods and members.

// The WatchDogThread object must outlive any tasks posted to the IO thread
// before the Quit task.
DISABLE_RUNNABLE_METHOD_REFCOUNT(WatchDogThread);

WatchDogThread::WatchDogThread()
    : BrowserProcessSubThread(BrowserThread::WATCHDOG) {
}

WatchDogThread::~WatchDogThread() {
  // Remove all notifications for all watched threads.
  ThreadWatcherList::RemoveNotifications();
  // We cannot rely on our base class to stop the thread since we want our
  // CleanUp function to run.
  Stop();
}

void WatchDogThread::Init() {
  // This thread shouldn't be allowed to perform any blocking disk I/O.
  base::ThreadRestrictions::SetIOAllowed(false);

  BrowserProcessSubThread::Init();

  const base::TimeDelta kSleepTime = base::TimeDelta::FromSeconds(5);
  const base::TimeDelta kUnresponsiveTime = base::TimeDelta::FromSeconds(10);
  ThreadWatcher::StartWatching(BrowserThread::UI, "UI", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::IO, "IO", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::DB, "DB", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::FILE, "FILE", kSleepTime,
                               kUnresponsiveTime);
  ThreadWatcher::StartWatching(BrowserThread::CACHE, "CACHE", kSleepTime,
                               kUnresponsiveTime);
}
<|endoftext|>