<commit_before>/*****************************************************************************
*  Copyright 2011 Sergey Shekya,n Victor Agababov
*
*  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.
* *****************************************************************************/

/*****
 * Author: Sergey Shekyan shekyan@gmail.com
 *         Victor Agababov vagababov@gmail.com
 *
 * Slow HTTP attack vulnerability test tool
 *  http://code.google.com/p/slowhttptest/
 *****/
#include "config.h"
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <cctype>

#include "slowlog.h"
#include "slowhttptest.h"

#define DEFAULT_URL "http://localhost/"

static void usage() {
  printf(
      "\n%s %s, a tool to test for slow HTTP "
      "DoS vulnerabilities.\n"
      "Usage:\n"
      "slowtest [-a <range start>] [-b <range limit>]\n"
      "[-c <number of connections>] [-<H|B|R>]\n"
      "[-g <generate statistics>]\n"
      "[-i <interval in seconds>] [-l <test duration in seconds>]\n"
      "[-o <output file path and/or name>]\n"
      "[-p <timeout for probe connection>]\n"
      "[-r <connections per second>]\n"
      "[-s <value of Content-Length header>] [-t <verb>]\n"
      "[-u <URL>]\n"
      "[-v <verbosity level>] [-x <max length of follow up data>]\n"
      "Options:\n\t"
      "-a start,        left boundary of range in range header, default: 5\n\t"
      "-b bytes,        limit for range header right boundary values, default: 2000\n\t"
      "-c connections,  target number of connections, default: 50\n\t"
      "-h               display this help and exit\n\t"
      "-H, -B, or -R    specify test mode (slow headers,body or range),\n\t"
      "                 default: headers\n\t"
      "-g,              generate statistics with socket state changes,\n\t"
      "                 default: off\n\t"
      "-i seconds,      interval between followup data in seconds, default: 10\n\t"
      "-l seconds,      target test length in seconds, default: 240\n\t"
      "-o file,         save statistics output in file.html and file.csv,\n\t"
      "                 -g must be specified to use this option\n\t"
      "-p seconds,      timeout to wait for HTTP response on probe connection,\n\t"
      "                 after which server is considered inaccessible,\n\t"
      "                 default: 10\n\t"
      "-r num,          connection rate (connections per seconds), default: 50\n\t"
      "-s bytes,        value of Content-Length header if needed, default: 4096\n\t"
      "-t verb          verb to use in request,\n\t"
      "                 defalut to GET for slow headers and POST for slow body)\n\t"
      "-u URL,          absolute URL to target, default: http://localhost/\n\t"
      "-v level,        verbosity level 0-4: Fatal, Info, Error, Warning, Debug\n\t"
      "                 default: 1 - Info\n\t"
      "-x bytes,        max length of each randomized name/value pair of\n\t"
      "                 followup data per tick, e.g. -x 2 generates\n\t"
      "                 X-xx: xx for header or &xx=xx for body, where x\n\t"
      "                 is random character, default: 32\n"
      , PACKAGE
      , VERSION
      );
}

// global flag to indicite if we need to run
int g_running = true;

void int_handler(int param) {
  g_running = false;
}

using slowhttptest::slowlog_init;
using slowhttptest::slowlog;
using slowhttptest::SlowHTTPTest;
using slowhttptest::SlowTestType;

int main(int argc, char **argv) {

  if (argc < 1) {
    usage();
    return -1;
  }
  char url[1024] = { 0 };
  char path[1024] = { 0 };
  char verb[16] = { 0 };
  // default vaules
  int conn_cnt            = 50;
  int content_length      = 4096;
  int duration            = 240;
  int interval            = 10;
  int max_random_data_len = 32;
  int probe_interval      = 10;
  int range_start         = 5;
  int range_limit         = 2000;
  int rate                = 50;
  int debug_level         = LOG_INFO;
  bool  need_stats        = false;
  SlowTestType type = slowhttptest::eHeader;
  long tmp;
  char o;
  while((o = getopt(argc, argv, ":HBRga:b:c:i:l:o:p:r:s:t:u:v:x:")) != -1) {
    switch (o) {
      case 'a':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 65539) {
          range_start = tmp;
        } else {
          usage();
          return -1;
        }
        break;
      case 'b':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 524288) {
          range_limit = tmp;
        } else {
          usage();
          return -1;
        }
        break;
      case 'c':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 1024) {
          conn_cnt = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'h':
        usage();
        return 1;
        break;
      case 'H':
        type = slowhttptest::eHeader;
        break;
      case 'B':
        type = slowhttptest::ePost;
        break;
      case 'R':
        type = slowhttptest::eRange;
        break;
      case 'g':
        need_stats = true;
        break;
      case 'i':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          interval = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'l':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          duration = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'o':
        strncpy(path, optarg, 1023);
        break;
      case 'p':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          probe_interval = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'r':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          rate = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 's':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          content_length = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 't':
        strncpy(verb, optarg, 15);
        break;
      case 'u':
        strncpy(url, optarg, 1023);
        break;
      case 'v':
        tmp = strtol(optarg, 0, 10);
        if(0 <= tmp && tmp <= 4) {
          debug_level = static_cast<int>(tmp);
        } else {
          debug_level = LOG_FATAL;
        }
        break;
      case 'x':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          max_random_data_len = static_cast<int>(tmp);
          if(max_random_data_len < 2) max_random_data_len = 2;
        } else {
          usage();
          return -1;
        }
        break;
      case '?':
        printf("Illegal option -%c\n", optopt);
        usage();
        return -1;
        break;
      default:
        printf("Option -%c requires an argument.\n", optopt);
        usage();
        return -1;
    }
  }
  if(!strlen(url)) {
    strncpy(url, DEFAULT_URL, sizeof(DEFAULT_URL));
  }
  signal(SIGPIPE, SIG_IGN);
  signal(SIGINT, &int_handler);
  slowlog_init(debug_level, NULL);
  std::auto_ptr<SlowHTTPTest> slow_test(
      new SlowHTTPTest(rate, duration, interval, conn_cnt,
      max_random_data_len, content_length, type, need_stats,
     probe_interval, range_start, range_limit));
  if(!slow_test->init(url, verb, path)) {
    slowlog(LOG_FATAL, "%s: error setting up slow HTTP test\n", __FUNCTION__);
    return -1;
  } else if(!slow_test->run_test()) {
    slowlog(LOG_FATAL, "%s: error running slow HTTP test\n", __FUNCTION__);
    return -1;
  }
  slow_test->report_final();
  return 0;
}
<commit_msg>decreased probe timeout to 5 seconds<commit_after>/*****************************************************************************
*  Copyright 2011 Sergey Shekya,n Victor Agababov
*
*  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.
* *****************************************************************************/

/*****
 * Author: Sergey Shekyan shekyan@gmail.com
 *         Victor Agababov vagababov@gmail.com
 *
 * Slow HTTP attack vulnerability test tool
 *  http://code.google.com/p/slowhttptest/
 *****/
#include "config.h"
#include <limits.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <memory>
#include <cctype>

#include "slowlog.h"
#include "slowhttptest.h"

#define DEFAULT_URL "http://localhost/"

static void usage() {
  printf(
      "\n%s %s, a tool to test for slow HTTP "
      "DoS vulnerabilities.\n"
      "Usage:\n"
      "slowtest [-a <range start>] [-b <range limit>]\n"
      "[-c <number of connections>] [-<H|B|R>]\n"
      "[-g <generate statistics>]\n"
      "[-i <interval in seconds>] [-l <test duration in seconds>]\n"
      "[-o <output file path and/or name>]\n"
      "[-p <timeout for probe connection>]\n"
      "[-r <connections per second>]\n"
      "[-s <value of Content-Length header>] [-t <verb>]\n"
      "[-u <URL>]\n"
      "[-v <verbosity level>] [-x <max length of follow up data>]\n"
      "Options:\n\t"
      "-a start,        left boundary of range in range header, default: 5\n\t"
      "-b bytes,        limit for range header right boundary values, default: 2000\n\t"
      "-c connections,  target number of connections, default: 50\n\t"
      "-h               display this help and exit\n\t"
      "-H, -B, or -R    specify test mode (slow headers,body or range),\n\t"
      "                 default: headers\n\t"
      "-g,              generate statistics with socket state changes,\n\t"
      "                 default: off\n\t"
      "-i seconds,      interval between followup data in seconds, default: 10\n\t"
      "-l seconds,      target test length in seconds, default: 240\n\t"
      "-o file,         save statistics output in file.html and file.csv,\n\t"
      "                 -g must be specified to use this option\n\t"
      "-p seconds,      timeout to wait for HTTP response on probe connection,\n\t"
      "                 after which server is considered inaccessible,\n\t"
      "                 default: 5\n\t"
      "-r num,          connection rate (connections per seconds), default: 50\n\t"
      "-s bytes,        value of Content-Length header if needed, default: 4096\n\t"
      "-t verb          verb to use in request,\n\t"
      "                 defalut to GET for slow headers and POST for slow body)\n\t"
      "-u URL,          absolute URL to target, default: http://localhost/\n\t"
      "-v level,        verbosity level 0-4: Fatal, Info, Error, Warning, Debug\n\t"
      "                 default: 1 - Info\n\t"
      "-x bytes,        max length of each randomized name/value pair of\n\t"
      "                 followup data per tick, e.g. -x 2 generates\n\t"
      "                 X-xx: xx for header or &xx=xx for body, where x\n\t"
      "                 is random character, default: 32\n"
      , PACKAGE
      , VERSION
      );
}

// global flag to indicite if we need to run
int g_running = true;

void int_handler(int param) {
  g_running = false;
}

using slowhttptest::slowlog_init;
using slowhttptest::slowlog;
using slowhttptest::SlowHTTPTest;
using slowhttptest::SlowTestType;

int main(int argc, char **argv) {

  if (argc < 1) {
    usage();
    return -1;
  }
  char url[1024] = { 0 };
  char path[1024] = { 0 };
  char verb[16] = { 0 };
  // default vaules
  int conn_cnt            = 50;
  int content_length      = 4096;
  int duration            = 240;
  int interval            = 10;
  int max_random_data_len = 32;
  int probe_interval      = 5;
  int range_start         = 5;
  int range_limit         = 2000;
  int rate                = 50;
  int debug_level         = LOG_INFO;
  bool  need_stats        = false;
  SlowTestType type = slowhttptest::eHeader;
  long tmp;
  char o;
  while((o = getopt(argc, argv, ":HBRga:b:c:i:l:o:p:r:s:t:u:v:x:")) != -1) {
    switch (o) {
      case 'a':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 65539) {
          range_start = tmp;
        } else {
          usage();
          return -1;
        }
        break;
      case 'b':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 524288) {
          range_limit = tmp;
        } else {
          usage();
          return -1;
        }
        break;
      case 'c':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= 1024) {
          conn_cnt = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'h':
        usage();
        return 1;
        break;
      case 'H':
        type = slowhttptest::eHeader;
        break;
      case 'B':
        type = slowhttptest::ePost;
        break;
      case 'R':
        type = slowhttptest::eRange;
        break;
      case 'g':
        need_stats = true;
        break;
      case 'i':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          interval = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'l':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          duration = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'o':
        strncpy(path, optarg, 1023);
        break;
      case 'p':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          probe_interval = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 'r':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          rate = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 's':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          content_length = static_cast<int>(tmp);
        } else {
          usage();
          return -1;
        }
        break;
      case 't':
        strncpy(verb, optarg, 15);
        break;
      case 'u':
        strncpy(url, optarg, 1023);
        break;
      case 'v':
        tmp = strtol(optarg, 0, 10);
        if(0 <= tmp && tmp <= 4) {
          debug_level = static_cast<int>(tmp);
        } else {
          debug_level = LOG_FATAL;
        }
        break;
      case 'x':
        tmp = strtol(optarg, 0, 10);
        if(tmp && tmp <= INT_MAX) {
          max_random_data_len = static_cast<int>(tmp);
          if(max_random_data_len < 2) max_random_data_len = 2;
        } else {
          usage();
          return -1;
        }
        break;
      case '?':
        printf("Illegal option -%c\n", optopt);
        usage();
        return -1;
        break;
      default:
        printf("Option -%c requires an argument.\n", optopt);
        usage();
        return -1;
    }
  }
  if(!strlen(url)) {
    strncpy(url, DEFAULT_URL, sizeof(DEFAULT_URL));
  }
  signal(SIGPIPE, SIG_IGN);
  signal(SIGINT, &int_handler);
  slowlog_init(debug_level, NULL);
  std::auto_ptr<SlowHTTPTest> slow_test(
      new SlowHTTPTest(rate, duration, interval, conn_cnt,
      max_random_data_len, content_length, type, need_stats,
     probe_interval, range_start, range_limit));
  if(!slow_test->init(url, verb, path)) {
    slowlog(LOG_FATAL, "%s: error setting up slow HTTP test\n", __FUNCTION__);
    return -1;
  } else if(!slow_test->run_test()) {
    slowlog(LOG_FATAL, "%s: error running slow HTTP test\n", __FUNCTION__);
    return -1;
  }
  slow_test->report_final();
  return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2014 The Bitcoin Core developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2020 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "primitives/transaction.h"
#include "main.h"
#include "test_pivx.h"

#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup)

CAmount nMoneySupplyPoWEnd = 43199500 * COIN;

BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
    CAmount nSum = 0;
    for (int nHeight = 0; nHeight < 1; nHeight += 1) {
        /* premine in block 1 (60,001 PIV) */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 60001 * COIN);
        nSum += nSubsidy;
    }

    for (int nHeight = 1; nHeight < 86400; nHeight += 1) {
        /* PoW Phase One */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 250 * COIN);
        nSum += nSubsidy;
    }

    for (int nHeight = 86400; nHeight < 151200; nHeight += 1) {
        /* PoW Phase Two */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 225 * COIN);
        nSum += nSubsidy;
    }

    for (int nHeight = 151200; nHeight < 259200; nHeight += 1) {
        /* PoW Phase Two */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 45 * COIN);
        BOOST_CHECK(Params().GetConsensus().MoneyRange(nSubsidy));
        nSum += nSubsidy;
        BOOST_CHECK(nSum > 0 && nSum <= nMoneySupplyPoWEnd);
    }
    BOOST_CHECK(nSum == 4109975100000000ULL);
}

bool ReturnFalse() { return false; }
bool ReturnTrue() { return true; }

BOOST_AUTO_TEST_CASE(test_combiner_all)
{
    boost::signals2::signal<bool(), CombinerAll> Test;
    BOOST_CHECK(Test());
    Test.connect(&ReturnFalse);
    BOOST_CHECK(!Test());
    Test.connect(&ReturnTrue);
    BOOST_CHECK(!Test());
    Test.disconnect(&ReturnFalse);
    BOOST_CHECK(Test());
    Test.disconnect(&ReturnTrue);
    BOOST_CHECK(Test());
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>Implemented a block signature verification unit test.<commit_after>// Copyright (c) 2014 The Bitcoin Core developers
// Copyright (c) 2014-2015 The Dash developers
// Copyright (c) 2015-2020 The PIVX developers
// Distributed under the MIT/X11 software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "blocksignature.h"
#include "main.h"
#include "primitives/transaction.h"
#include "script/sign.h"
#include "test_pivx.h"
#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(main_tests, TestingSetup)

enum BlockSignatureType{
    P2PK,
    P2PKH,
    P2CS
};

CScript GetScriptForType(CPubKey pubKey, BlockSignatureType type)
{
    switch(type){
        case P2PK:
            return CScript() << pubKey << OP_CHECKSIG;
        default:
            return GetScriptForDestination(pubKey.GetID());
    }
}

std::vector<unsigned char> CreateDummyScriptSigWithKey(CPubKey pubKey)
{
    std::vector<unsigned char> vchSig;
    const CScript scriptCode;
    DummySignatureCreator(nullptr).CreateSig(vchSig, pubKey.GetID(), scriptCode);
    return vchSig;
}

CScript GetDummyScriptSigByType(CPubKey pubKey, bool isP2PK)
{
    CScript script = CScript() << CreateDummyScriptSigWithKey(pubKey);
    if (!isP2PK)
        script << ToByteVector(pubKey);
    return script;
}

CBlock CreateDummyBlockWithSignature(CKey stakingKey, BlockSignatureType type, bool useInputP2PK)
{
    CMutableTransaction txCoinStake;
    // Dummy input
    CTxIn input(uint256(), 0);
    // P2PKH input
    input.scriptSig = GetDummyScriptSigByType(stakingKey.GetPubKey(), useInputP2PK);
    // Add dummy input
    txCoinStake.vin.emplace_back(input);
    // Empty first output
    txCoinStake.vout.emplace_back(CTxOut(0, CScript()));
    // P2PK staking output
    CScript scriptPubKey = GetScriptForType(stakingKey.GetPubKey(), type);
    txCoinStake.vout.emplace_back(CTxOut(0, scriptPubKey));

    // Now the block.
    CBlock block;
    block.vtx.emplace_back(CTransaction()); // dummy first tx
    block.vtx.emplace_back(txCoinStake);
    SignBlockWithKey(block, stakingKey);

    return block;
}

bool TestBlockSignaturePreEnforcementV5(const CBlock& block)
{
    return CheckBlockSignature(block, false);
}

bool TestBlockSignaturePostEnforcementV5(const CBlock& block)
{
    return CheckBlockSignature(block, true);
}

BOOST_AUTO_TEST_CASE(block_signature_test)
{
    for (int i = 0; i < 20; ++i) {
        CKey stakingKey;
        stakingKey.MakeNewKey(true);
        bool useInputP2PK = i % 2 == 0;

        // Test P2PK block signature pre enforcement.
        CBlock block = CreateDummyBlockWithSignature(stakingKey, BlockSignatureType::P2PK, useInputP2PK);
        BOOST_CHECK(TestBlockSignaturePreEnforcementV5(block));

        // Test P2PK block signature post enforcement
        block = CreateDummyBlockWithSignature(stakingKey, BlockSignatureType::P2PK, useInputP2PK);
        BOOST_CHECK(TestBlockSignaturePostEnforcementV5(block));

        // Test P2PKH block signature pre enforcement ---> must fail.
        block = CreateDummyBlockWithSignature(stakingKey, BlockSignatureType::P2PKH, useInputP2PK);
        BOOST_CHECK(!TestBlockSignaturePreEnforcementV5(block));

        // Test P2PKH block signature post enforcement
        block = CreateDummyBlockWithSignature(stakingKey, BlockSignatureType::P2PKH, useInputP2PK);
        if (useInputP2PK) {
            // If it's using a P2PK scriptsig as input and a P2PKH output
            // The block doesn't contain the public key to verify the sig anywhere.
            // Must fail.
            BOOST_CHECK(!TestBlockSignaturePostEnforcementV5(block));
        } else {
            BOOST_CHECK(TestBlockSignaturePostEnforcementV5(block));
        }
    }
}

CAmount nMoneySupplyPoWEnd = 43199500 * COIN;

BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
    CAmount nSum = 0;
    for (int nHeight = 0; nHeight < 1; nHeight += 1) {
        /* premine in block 1 (60,001 PIV) */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 60001 * COIN);
        nSum += nSubsidy;
    }

    for (int nHeight = 1; nHeight < 86400; nHeight += 1) {
        /* PoW Phase One */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 250 * COIN);
        nSum += nSubsidy;
    }

    for (int nHeight = 86400; nHeight < 151200; nHeight += 1) {
        /* PoW Phase Two */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 225 * COIN);
        nSum += nSubsidy;
    }

    for (int nHeight = 151200; nHeight < 259200; nHeight += 1) {
        /* PoW Phase Two */
        CAmount nSubsidy = GetBlockValue(nHeight);
        BOOST_CHECK(nSubsidy <= 45 * COIN);
        BOOST_CHECK(Params().GetConsensus().MoneyRange(nSubsidy));
        nSum += nSubsidy;
        BOOST_CHECK(nSum > 0 && nSum <= nMoneySupplyPoWEnd);
    }
    BOOST_CHECK(nSum == 4109975100000000ULL);
}

bool ReturnFalse() { return false; }
bool ReturnTrue() { return true; }

BOOST_AUTO_TEST_CASE(test_combiner_all)
{
    boost::signals2::signal<bool(), CombinerAll> Test;
    BOOST_CHECK(Test());
    Test.connect(&ReturnFalse);
    BOOST_CHECK(!Test());
    Test.connect(&ReturnTrue);
    BOOST_CHECK(!Test());
    Test.disconnect(&ReturnFalse);
    BOOST_CHECK(Test());
    Test.disconnect(&ReturnTrue);
    BOOST_CHECK(Test());
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>#ifndef MJOLNIR_CORE_FORCE_FIELD_HPP
#define MJOLNIR_CORE_FORCE_FIELD_HPP
#include <mjolnir/core/LocalForceField.hpp>
#include <mjolnir/core/GlobalForceField.hpp>
#include <mjolnir/core/ExternalForceField.hpp>

namespace mjolnir
{

template<typename traitsT>
class ForceField
{
  public:
    using traits_type              = traitsT;
    using real_type                = typename traits_type::real_type;
    using coordinate_type          = typename traits_type::coordinate_type;
    using system_type              = System<traits_type>;
    using local_forcefield_type    = LocalForceField<traits_type>;
    using global_forcefield_type   = GlobalForceField<traits_type>;
    using external_forcefield_type = ExternalForceField<traits_type>;

  public:

    ForceField(local_forcefield_type&&    local,
               global_forcefield_type&&   global,
               external_forcefield_type&& external)
        : local_(std::move(local)), global_(std::move(global)),
          external_(std::move(external))
    {}

    ForceField()  = default;
    ~ForceField() = default;
    ForceField(const ForceField&) = delete;
    ForceField(ForceField&&)      = default;
    ForceField& operator=(const ForceField&) = delete;
    ForceField& operator=(ForceField&&)      = default;

    // this modify system::topology by using local interaction info.
    void initialize(system_type& sys)
    {
        // first, fetch current topology
        local_.write_topology(sys.topology());
        sys.topology().construct_molecules();

        // based on the topology, make exclusion list
        local_   .initialize(sys);
        global_  .initialize(sys);
        external_.initialize(sys);

        return;
    }

    // update parameters like temperature, ionic concentration, etc...
    void update(const system_type& sys)
    {
        local_   .update(sys);
        global_  .update(sys);
        external_.update(sys);
        return;
    }

    // update margin of neighbor list
    void update_margin(const real_type dmargin, const system_type& sys)
    {
        // TODO:
        // dmargin is a maximum (safe) length to reduce the margin. Since global
        // forcefields calculate forces between particles, the safe length is
        // mostly 2 * (largest displacement in the step). It is dmargin.
        // However, since external forcefields calculate forces between particle
        // and an external field, the safe length can be just the largest
        // displacement in the step. The current implementation overestimate the
        // safe length for the external forcefields (it's correct for global
        // forcefields). In most cases, the most time-consuming part is global
        // forcefields, so I implemented in this way for now. If some idea that
        // works more efficiently is came up, this part would be re-implemented.
        local_   .update_margin(dmargin, sys);
        global_  .update_margin(dmargin, sys);
        external_.update_margin(dmargin, sys);
        return;
    }

    void calc_force(system_type& sys) const noexcept
    {
        local_   .calc_force(sys);
        global_  .calc_force(sys);
        external_.calc_force(sys);
        return;
    }
    real_type calc_energy(const system_type& sys) const noexcept
    {
        return local_.calc_energy(sys) + global_.calc_energy(sys) +
            external_.calc_energy(sys);
    }

    std::vector<std::string> list_energy_name() const
    {
        auto retval = local_.list_energy();
        auto glo    = global_.list_energy();
        auto ext    = external_.list_energy();

        retval.reserve(retval.size() + glo.size() + ext.size());

        std::copy(std::make_move_iterator(glo.begin()),
                  std::make_move_iterator(glo.end()),
                  std::back_inserter(retval));

        std::copy(std::make_move_iterator(ext.begin()),
                  std::make_move_iterator(ext.end()),
                  std::back_inserter(retval));

        return retval;
    }
    std::vector<real_type> dump_energy(const system_type& sys) const
    {
        auto retval = local_.dump_energy(sys);
        auto glo    = global_.dump_energy(sys);
        auto ext    = external_.dump_energy(sys);

        retval.reserve(retval.size() + glo.size() + ext.size());

        std::copy(glo.begin(), glo.end(), std::back_inserter(retval));
        std::copy(ext.begin(), ext.end(), std::back_inserter(retval));
        return retval;
    }

    local_forcefield_type    const& local()    const noexcept {return local_;}
    local_forcefield_type    &      local()          noexcept {return local_;}
    global_forcefield_type   const& global()   const noexcept {return global_;}
    global_forcefield_type   &      global()         noexcept {return global_;}
    external_forcefield_type const& external() const noexcept {return external_;}
    external_forcefield_type &      external()       noexcept {return external_;}

  private:

    local_forcefield_type    local_;
    global_forcefield_type   global_;
    external_forcefield_type external_;
};

#ifdef MJOLNIR_SEPARATE_BUILD
extern template class ForceField<SimulatorTraits<double, UnlimitedBoundary>>;
extern template class ForceField<SimulatorTraits<float,  UnlimitedBoundary>>;
extern template class ForceField<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class ForceField<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
#endif

} // mjolnir
#endif /* MJOLNIR_FORCE_FIELD */
<commit_msg>feat: add logger to ForceField::inititalize<commit_after>#ifndef MJOLNIR_CORE_FORCE_FIELD_HPP
#define MJOLNIR_CORE_FORCE_FIELD_HPP
#include <mjolnir/core/LocalForceField.hpp>
#include <mjolnir/core/GlobalForceField.hpp>
#include <mjolnir/core/ExternalForceField.hpp>

namespace mjolnir
{

template<typename traitsT>
class ForceField
{
  public:
    using traits_type              = traitsT;
    using real_type                = typename traits_type::real_type;
    using coordinate_type          = typename traits_type::coordinate_type;
    using system_type              = System<traits_type>;
    using local_forcefield_type    = LocalForceField<traits_type>;
    using global_forcefield_type   = GlobalForceField<traits_type>;
    using external_forcefield_type = ExternalForceField<traits_type>;

  public:

    ForceField(local_forcefield_type&&    local,
               global_forcefield_type&&   global,
               external_forcefield_type&& external)
        : local_(std::move(local)), global_(std::move(global)),
          external_(std::move(external))
    {}

    ForceField()  = default;
    ~ForceField() = default;
    ForceField(const ForceField&) = delete;
    ForceField(ForceField&&)      = default;
    ForceField& operator=(const ForceField&) = delete;
    ForceField& operator=(ForceField&&)      = default;

    // this modify system::topology by using local interaction info.
    void initialize(system_type& sys)
    {
        MJOLNIR_GET_DEFAULT_LOGGER();
        MJOLNIR_LOG_FUNCTION();

        MJOLNIR_LOG_INFO("writing current topology");
        local_.write_topology(sys.topology());
        sys.topology().construct_molecules();

        MJOLNIR_LOG_INFO("initializing forcefields");
        local_   .initialize(sys);
        global_  .initialize(sys);
        external_.initialize(sys);

        return;
    }

    // update parameters like temperature, ionic concentration, etc...
    void update(const system_type& sys)
    {
        local_   .update(sys);
        global_  .update(sys);
        external_.update(sys);
        return;
    }

    // update margin of neighbor list
    void update_margin(const real_type dmargin, const system_type& sys)
    {
        // TODO:
        // dmargin is a maximum (safe) length to reduce the margin. Since global
        // forcefields calculate forces between particles, the safe length is
        // mostly 2 * (largest displacement in the step). It is dmargin.
        // However, since external forcefields calculate forces between particle
        // and an external field, the safe length can be just the largest
        // displacement in the step. The current implementation overestimate the
        // safe length for the external forcefields (it's correct for global
        // forcefields). In most cases, the most time-consuming part is global
        // forcefields, so I implemented in this way for now. If some idea that
        // works more efficiently is came up, this part would be re-implemented.
        local_   .update_margin(dmargin, sys);
        global_  .update_margin(dmargin, sys);
        external_.update_margin(dmargin, sys);
        return;
    }

    void calc_force(system_type& sys) const noexcept
    {
        local_   .calc_force(sys);
        global_  .calc_force(sys);
        external_.calc_force(sys);
        return;
    }
    real_type calc_energy(const system_type& sys) const noexcept
    {
        return local_.calc_energy(sys) + global_.calc_energy(sys) +
            external_.calc_energy(sys);
    }

    std::vector<std::string> list_energy_name() const
    {
        auto retval = local_.list_energy();
        auto glo    = global_.list_energy();
        auto ext    = external_.list_energy();

        retval.reserve(retval.size() + glo.size() + ext.size());

        std::copy(std::make_move_iterator(glo.begin()),
                  std::make_move_iterator(glo.end()),
                  std::back_inserter(retval));

        std::copy(std::make_move_iterator(ext.begin()),
                  std::make_move_iterator(ext.end()),
                  std::back_inserter(retval));

        return retval;
    }
    std::vector<real_type> dump_energy(const system_type& sys) const
    {
        auto retval = local_.dump_energy(sys);
        auto glo    = global_.dump_energy(sys);
        auto ext    = external_.dump_energy(sys);

        retval.reserve(retval.size() + glo.size() + ext.size());

        std::copy(glo.begin(), glo.end(), std::back_inserter(retval));
        std::copy(ext.begin(), ext.end(), std::back_inserter(retval));
        return retval;
    }

    local_forcefield_type    const& local()    const noexcept {return local_;}
    local_forcefield_type    &      local()          noexcept {return local_;}
    global_forcefield_type   const& global()   const noexcept {return global_;}
    global_forcefield_type   &      global()         noexcept {return global_;}
    external_forcefield_type const& external() const noexcept {return external_;}
    external_forcefield_type &      external()       noexcept {return external_;}

  private:

    local_forcefield_type    local_;
    global_forcefield_type   global_;
    external_forcefield_type external_;
};

#ifdef MJOLNIR_SEPARATE_BUILD
extern template class ForceField<SimulatorTraits<double, UnlimitedBoundary>>;
extern template class ForceField<SimulatorTraits<float,  UnlimitedBoundary>>;
extern template class ForceField<SimulatorTraits<double, CuboidalPeriodicBoundary>>;
extern template class ForceField<SimulatorTraits<float,  CuboidalPeriodicBoundary>>;
#endif

} // mjolnir
#endif /* MJOLNIR_FORCE_FIELD */
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2016, Google Inc.
 * All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <vector>

#include "src/compat/string_compat.h"
#include "src/compat/test_compat.h"
#include "src/path_matching.h"
#include "src/perf_data_handler.h"
#include "src/quipper/binary_data_utils.h"
#include "src/quipper/kernel/perf_event.h"
#include "src/quipper/perf_data_utils.h"

namespace perftools {

TEST(PathMatching, DeletedSharedObjectMatching) {
  const std::vector<string> paths = {
      "lib.so.v1(deleted)",
      "lib.so.v1(deleted)junk",
      "lib.so (deleted)",
      "lib.so_junk_(deleted)",
      "lib.so   .so junk_(deleted)",
  };
  for (const auto& path : paths) {
    ASSERT_TRUE(IsDeletedSharedObject(path));
  }
}

TEST(PathMatching, DeletedSharedObjectNotMatching) {
  const std::vector<string> paths = {
      "abc",
      "lib.so ",
      "lib.so(deleted)",
      ".so (deleted)",
      "lib.sojunk(deleted)",
      "",
  };

  for (const auto& path : paths) {
    ASSERT_FALSE(IsDeletedSharedObject(path));
  }
}

TEST(PathMatching, VersionedSharedObjectMatching) {
  const std::vector<string> paths = {
      "lib.so.", "lib.so.abc", "lib.so.1", "lib.so.v1",
  };
  for (const auto& path : paths) {
    ASSERT_TRUE(IsVersionedSharedObject(path));
  }
}

TEST(PathMatching, VersionedSharedObjectNotMatching) {
  const std::vector<string> paths = {
      "abc", "lib.so(deleted)", ".so.v1", ".so.", "",
  };
  for (const auto& path : paths) {
    ASSERT_FALSE(IsDeletedSharedObject(path));
  }
}

class PerfDataHandlerTest : public ::testing::Test {
 protected:
  PerfDataHandlerTest() {}
};

class MMapTestHandler : public perftools::PerfDataHandler {
 public:
  MMapTestHandler(
      std::unordered_map<string, string> expected_filename_to_build_id)
      : _expected_filename_to_build_id(
            std::move(expected_filename_to_build_id)) {}
  MMapTestHandler(const MMapTestHandler&) = delete;
  MMapTestHandler& operator=(const MMapTestHandler&) = delete;
  ~MMapTestHandler() override {}

  // Callbacks for PerfDataHandler
  void Sample(const PerfDataHandler::SampleContext& sample) override {}
  void Comm(const CommContext& comm) override {}
  void MMap(const MMapContext& mmap) override {
    const string* actual_build_id = mmap.mapping->build_id;
    const string* actual_filename = mmap.mapping->filename;
    const auto expected_build_id_it =
        _expected_filename_to_build_id.find(*actual_filename);
    if (expected_build_id_it != _expected_filename_to_build_id.end()) {
      EXPECT_TRUE(actual_build_id != nullptr)
          << "Expected build id " << expected_build_id_it->second
          << " for the filename " << *actual_filename;
      if (actual_build_id != nullptr) {
        EXPECT_EQ(expected_build_id_it->second, *actual_build_id);
        _seen_filenames.insert(*actual_filename);
      }
    } else {
      EXPECT_TRUE(actual_build_id == nullptr)
          << "Actual build id " << *actual_build_id << " for the filename "
          << *actual_filename;
    }
  }

  void CheckSeenFilenames() {
    EXPECT_EQ(_expected_filename_to_build_id.size(), _seen_filenames.size());
    for (auto const& filename : _seen_filenames) {
      EXPECT_TRUE(_expected_filename_to_build_id.find(filename) !=
                  _expected_filename_to_build_id.end());
    }
  }

 private:
  std::unordered_map<string, string> _expected_filename_to_build_id;
  std::unordered_set<string> _seen_filenames;
};

TEST(PerfDataHandlerTest, KernelBuildIdWithDifferentFilename) {
  const int kHexCharsPerByte = 2;
  quipper::PerfDataProto proto;
  // Add a guest kernel build id.
  auto* build_id = proto.add_build_ids();
  build_id->set_misc(quipper::PERF_RECORD_MISC_GUEST_KERNEL);
  build_id->set_pid(-1);
  build_id->set_filename("[guest.kernel.kallsyms]");
  build_id->set_filename_md5_prefix(
      quipper::Md5Prefix("[guest.kernel.kallsyms]"));

  string guest_kernel_build_id = "27357e645f";
  uint8_t guest_kernel_build_id_bytes[quipper::kBuildIDArraySize];
  ASSERT_TRUE(quipper::HexStringToRawData(guest_kernel_build_id,
                                          guest_kernel_build_id_bytes,
                                          sizeof(guest_kernel_build_id_bytes)));
  build_id->set_build_id_hash(guest_kernel_build_id_bytes,
                              guest_kernel_build_id.size() / kHexCharsPerByte);

  // Add kernel build id with a different filename.
  build_id = proto.add_build_ids();
  build_id->set_misc(quipper::PERF_RECORD_MISC_KERNEL);
  build_id->set_pid(-1);
  build_id->set_filename("kernel");
  build_id->set_filename_md5_prefix(quipper::Md5Prefix("kernel"));

  string kernel_build_id = "17937e648e";
  uint8_t kernel_build_id_bytes[quipper::kBuildIDArraySize];
  ASSERT_TRUE(quipper::HexStringToRawData(
      kernel_build_id, kernel_build_id_bytes, sizeof(kernel_build_id_bytes)));
  build_id->set_build_id_hash(kernel_build_id_bytes,
                              kernel_build_id.size() / kHexCharsPerByte);

  // Add a non-kernel build id.
  build_id = proto.add_build_ids();
  build_id->set_misc(quipper::PERF_RECORD_MISC_USER);
  build_id->set_pid(7568);
  build_id->set_filename("chrome");
  build_id->set_filename_md5_prefix(quipper::Md5Prefix("chrome"));

  string chrome_build_id = "cac4b36db4d0";
  uint8_t chrome_build_id_bytes[quipper::kBuildIDArraySize];
  ASSERT_TRUE(quipper::HexStringToRawData(
      chrome_build_id, chrome_build_id_bytes, sizeof(chrome_build_id_bytes)));
  build_id->set_build_id_hash(chrome_build_id_bytes,
                              chrome_build_id.size() / kHexCharsPerByte);

  // Add MMaps for kernel and non-kernel filenames.
  auto* mmap_event = proto.add_events()->mutable_mmap_event();
  mmap_event->set_filename("[kernel.kallsyms]");
  mmap_event->set_pid(100);
  mmap_event->set_tid(100);
  mmap_event->set_start(0);
  mmap_event->set_len(20000);
  mmap_event->set_pgoff(4000);

  mmap_event = proto.add_events()->mutable_mmap_event();
  mmap_event->set_filename("chrome");
  mmap_event->set_pid(100);
  mmap_event->set_tid(100);
  mmap_event->set_start(1000);
  mmap_event->set_len(1000);
  mmap_event->set_pgoff(0);

  mmap_event = proto.add_events()->mutable_mmap_event();
  mmap_event->set_filename("unknown");
  mmap_event->set_pid(3400);
  mmap_event->set_tid(3400);
  mmap_event->set_start(2000);
  mmap_event->set_len(1000);
  mmap_event->set_pgoff(0);

  // Map of expected filenames to buildids. Unknown is expected not to have a
  // build id. Since the guest kernel doesn't have a mapping, it is not expected
  // to appear in the MMap() call.
  std::unordered_map<string, string> expected_filename_to_build_id;
  expected_filename_to_build_id["[kernel.kallsyms]"] = "17937e648e";
  expected_filename_to_build_id["chrome"] = "cac4b36db4d0";

  MMapTestHandler handler(expected_filename_to_build_id);
  perftools::PerfDataHandler::Process(proto, &handler);
  handler.CheckSeenFilenames();
}

}  // namespace perftools

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<commit_msg>Add includes in perf_data_handler_test to fix the build issue in travis.<commit_after>/*
 * Copyright (c) 2016, Google Inc.
 * All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include <unordered_map>
#include <unordered_set>
#include <vector>

#include "src/compat/string_compat.h"
#include "src/compat/test_compat.h"
#include "src/path_matching.h"
#include "src/perf_data_handler.h"
#include "src/quipper/binary_data_utils.h"
#include "src/quipper/kernel/perf_event.h"
#include "src/quipper/perf_data_utils.h"

namespace perftools {

TEST(PathMatching, DeletedSharedObjectMatching) {
  const std::vector<string> paths = {
      "lib.so.v1(deleted)",
      "lib.so.v1(deleted)junk",
      "lib.so (deleted)",
      "lib.so_junk_(deleted)",
      "lib.so   .so junk_(deleted)",
  };
  for (const auto& path : paths) {
    ASSERT_TRUE(IsDeletedSharedObject(path));
  }
}

TEST(PathMatching, DeletedSharedObjectNotMatching) {
  const std::vector<string> paths = {
      "abc",
      "lib.so ",
      "lib.so(deleted)",
      ".so (deleted)",
      "lib.sojunk(deleted)",
      "",
  };

  for (const auto& path : paths) {
    ASSERT_FALSE(IsDeletedSharedObject(path));
  }
}

TEST(PathMatching, VersionedSharedObjectMatching) {
  const std::vector<string> paths = {
      "lib.so.", "lib.so.abc", "lib.so.1", "lib.so.v1",
  };
  for (const auto& path : paths) {
    ASSERT_TRUE(IsVersionedSharedObject(path));
  }
}

TEST(PathMatching, VersionedSharedObjectNotMatching) {
  const std::vector<string> paths = {
      "abc", "lib.so(deleted)", ".so.v1", ".so.", "",
  };
  for (const auto& path : paths) {
    ASSERT_FALSE(IsDeletedSharedObject(path));
  }
}

class PerfDataHandlerTest : public ::testing::Test {
 protected:
  PerfDataHandlerTest() {}
};

class MMapTestHandler : public perftools::PerfDataHandler {
 public:
  MMapTestHandler(
      std::unordered_map<string, string> expected_filename_to_build_id)
      : _expected_filename_to_build_id(
            std::move(expected_filename_to_build_id)) {}
  MMapTestHandler(const MMapTestHandler&) = delete;
  MMapTestHandler& operator=(const MMapTestHandler&) = delete;
  ~MMapTestHandler() override {}

  // Callbacks for PerfDataHandler
  void Sample(const PerfDataHandler::SampleContext& sample) override {}
  void Comm(const CommContext& comm) override {}
  void MMap(const MMapContext& mmap) override {
    const string* actual_build_id = mmap.mapping->build_id;
    const string* actual_filename = mmap.mapping->filename;
    const auto expected_build_id_it =
        _expected_filename_to_build_id.find(*actual_filename);
    if (expected_build_id_it != _expected_filename_to_build_id.end()) {
      EXPECT_TRUE(actual_build_id != nullptr)
          << "Expected build id " << expected_build_id_it->second
          << " for the filename " << *actual_filename;
      if (actual_build_id != nullptr) {
        EXPECT_EQ(expected_build_id_it->second, *actual_build_id);
        _seen_filenames.insert(*actual_filename);
      }
    } else {
      EXPECT_TRUE(actual_build_id == nullptr)
          << "Actual build id " << *actual_build_id << " for the filename "
          << *actual_filename;
    }
  }

  void CheckSeenFilenames() {
    EXPECT_EQ(_expected_filename_to_build_id.size(), _seen_filenames.size());
    for (auto const& filename : _seen_filenames) {
      EXPECT_TRUE(_expected_filename_to_build_id.find(filename) !=
                  _expected_filename_to_build_id.end());
    }
  }

 private:
  std::unordered_map<string, string> _expected_filename_to_build_id;
  std::unordered_set<string> _seen_filenames;
};

TEST(PerfDataHandlerTest, KernelBuildIdWithDifferentFilename) {
  const int kHexCharsPerByte = 2;
  quipper::PerfDataProto proto;
  // Add a guest kernel build id.
  auto* build_id = proto.add_build_ids();
  build_id->set_misc(quipper::PERF_RECORD_MISC_GUEST_KERNEL);
  build_id->set_pid(-1);
  build_id->set_filename("[guest.kernel.kallsyms]");
  build_id->set_filename_md5_prefix(
      quipper::Md5Prefix("[guest.kernel.kallsyms]"));

  string guest_kernel_build_id = "27357e645f";
  uint8_t guest_kernel_build_id_bytes[quipper::kBuildIDArraySize];
  ASSERT_TRUE(quipper::HexStringToRawData(guest_kernel_build_id,
                                          guest_kernel_build_id_bytes,
                                          sizeof(guest_kernel_build_id_bytes)));
  build_id->set_build_id_hash(guest_kernel_build_id_bytes,
                              guest_kernel_build_id.size() / kHexCharsPerByte);

  // Add kernel build id with a different filename.
  build_id = proto.add_build_ids();
  build_id->set_misc(quipper::PERF_RECORD_MISC_KERNEL);
  build_id->set_pid(-1);
  build_id->set_filename("kernel");
  build_id->set_filename_md5_prefix(quipper::Md5Prefix("kernel"));

  string kernel_build_id = "17937e648e";
  uint8_t kernel_build_id_bytes[quipper::kBuildIDArraySize];
  ASSERT_TRUE(quipper::HexStringToRawData(
      kernel_build_id, kernel_build_id_bytes, sizeof(kernel_build_id_bytes)));
  build_id->set_build_id_hash(kernel_build_id_bytes,
                              kernel_build_id.size() / kHexCharsPerByte);

  // Add a non-kernel build id.
  build_id = proto.add_build_ids();
  build_id->set_misc(quipper::PERF_RECORD_MISC_USER);
  build_id->set_pid(7568);
  build_id->set_filename("chrome");
  build_id->set_filename_md5_prefix(quipper::Md5Prefix("chrome"));

  string chrome_build_id = "cac4b36db4d0";
  uint8_t chrome_build_id_bytes[quipper::kBuildIDArraySize];
  ASSERT_TRUE(quipper::HexStringToRawData(
      chrome_build_id, chrome_build_id_bytes, sizeof(chrome_build_id_bytes)));
  build_id->set_build_id_hash(chrome_build_id_bytes,
                              chrome_build_id.size() / kHexCharsPerByte);

  // Add MMaps for kernel and non-kernel filenames.
  auto* mmap_event = proto.add_events()->mutable_mmap_event();
  mmap_event->set_filename("[kernel.kallsyms]");
  mmap_event->set_pid(100);
  mmap_event->set_tid(100);
  mmap_event->set_start(0);
  mmap_event->set_len(20000);
  mmap_event->set_pgoff(4000);

  mmap_event = proto.add_events()->mutable_mmap_event();
  mmap_event->set_filename("chrome");
  mmap_event->set_pid(100);
  mmap_event->set_tid(100);
  mmap_event->set_start(1000);
  mmap_event->set_len(1000);
  mmap_event->set_pgoff(0);

  mmap_event = proto.add_events()->mutable_mmap_event();
  mmap_event->set_filename("unknown");
  mmap_event->set_pid(3400);
  mmap_event->set_tid(3400);
  mmap_event->set_start(2000);
  mmap_event->set_len(1000);
  mmap_event->set_pgoff(0);

  // Map of expected filenames to buildids. Unknown is expected not to have a
  // build id. Since the guest kernel doesn't have a mapping, it is not expected
  // to appear in the MMap() call.
  std::unordered_map<string, string> expected_filename_to_build_id;
  expected_filename_to_build_id["[kernel.kallsyms]"] = "17937e648e";
  expected_filename_to_build_id["chrome"] = "cac4b36db4d0";

  MMapTestHandler handler(expected_filename_to_build_id);
  perftools::PerfDataHandler::Process(proto, &handler);
  handler.CheckSeenFilenames();
}

}  // namespace perftools

int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();
}
<|endoftext|>


<commit_before>// Copyright (c) 2012-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <sync.h>
#include <test/util/setup_common.h>

#include <boost/test/unit_test.hpp>

namespace {
template <typename MutexType>
void TestPotentialDeadLockDetected(MutexType& mutex1, MutexType& mutex2)
{
    {
        LOCK2(mutex1, mutex2);
    }
    bool error_thrown = false;
    try {
        LOCK2(mutex2, mutex1);
    } catch (const std::logic_error& e) {
        BOOST_CHECK_EQUAL(e.what(), "potential deadlock detected: mutex1 -> mutex2 -> mutex1");
        error_thrown = true;
    }
    #ifdef DEBUG_LOCKORDER
    BOOST_CHECK(error_thrown);
    #else
    BOOST_CHECK(!error_thrown);
    #endif
}
} // namespace

BOOST_FIXTURE_TEST_SUITE(sync_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(potential_deadlock_detected)
{
    #ifdef DEBUG_LOCKORDER
    bool prev = g_debug_lockorder_abort;
    g_debug_lockorder_abort = false;
    #endif

    RecursiveMutex rmutex1, rmutex2;
    TestPotentialDeadLockDetected(rmutex1, rmutex2);

    Mutex mutex1, mutex2;
    TestPotentialDeadLockDetected(mutex1, mutex2);

    #ifdef DEBUG_LOCKORDER
    g_debug_lockorder_abort = prev;
    #endif
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>test: Repeat deadlock tests<commit_after>// Copyright (c) 2012-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <sync.h>
#include <test/util/setup_common.h>

#include <boost/test/unit_test.hpp>

namespace {
template <typename MutexType>
void TestPotentialDeadLockDetected(MutexType& mutex1, MutexType& mutex2)
{
    {
        LOCK2(mutex1, mutex2);
    }
    bool error_thrown = false;
    try {
        LOCK2(mutex2, mutex1);
    } catch (const std::logic_error& e) {
        BOOST_CHECK_EQUAL(e.what(), "potential deadlock detected: mutex1 -> mutex2 -> mutex1");
        error_thrown = true;
    }
    #ifdef DEBUG_LOCKORDER
    BOOST_CHECK(error_thrown);
    #else
    BOOST_CHECK(!error_thrown);
    #endif
}
} // namespace

BOOST_FIXTURE_TEST_SUITE(sync_tests, BasicTestingSetup)

BOOST_AUTO_TEST_CASE(potential_deadlock_detected)
{
    #ifdef DEBUG_LOCKORDER
    bool prev = g_debug_lockorder_abort;
    g_debug_lockorder_abort = false;
    #endif

    RecursiveMutex rmutex1, rmutex2;
    TestPotentialDeadLockDetected(rmutex1, rmutex2);
    // The second test ensures that lock tracking data have not been broken by exception.
    TestPotentialDeadLockDetected(rmutex1, rmutex2);

    Mutex mutex1, mutex2;
    TestPotentialDeadLockDetected(mutex1, mutex2);
    // The second test ensures that lock tracking data have not been broken by exception.
    TestPotentialDeadLockDetected(mutex1, mutex2);

    #ifdef DEBUG_LOCKORDER
    g_debug_lockorder_abort = prev;
    #endif
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2019 projectchrono.org
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Benchmark test for contact simulation using NSC contact.
//
// =============================================================================

#include "chrono/ChConfig.h"
#include "chrono/utils/ChBenchmark.h"

#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChBodyEasy.h"
#include "chrono/physics/ChLinkMotorRotationSpeed.h"

#ifdef CHRONO_IRRLICHT
#include "chrono_irrlicht/ChIrrApp.h"
#endif

using namespace chrono;

// =============================================================================

template <int N>
class MixerTestNSC : public utils::ChBenchmarkTest {
  public:
    MixerTestNSC();
    ~MixerTestNSC() { delete m_system; }

    ChSystem* GetSystem() override { return m_system; }
    void ExecuteStep() override { m_system->DoStepDynamics(m_step); }

    void SimulateVis();

  private:
    ChSystemNSC* m_system;
    double m_step;
};

template <int N>
MixerTestNSC<N>::MixerTestNSC() : m_system(new ChSystemNSC()), m_step(0.02) {
    auto mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();

    for (int bi = 0; bi < N; bi++) {
        auto sphereBody = chrono_types::make_shared<ChBodyEasySphere>(1.1, 1000, true, true, mat);
        sphereBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
        m_system->Add(sphereBody);

        auto boxBody = chrono_types::make_shared<ChBodyEasyBox>(1.5, 1.5, 1.5, 100, true, true, mat);
        boxBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
        m_system->Add(boxBody);

        auto mcylBody = chrono_types::make_shared<ChBodyEasyCylinder>(0.75, 0.5, 100, true, true, mat);
        mcylBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
        m_system->Add(mcylBody);
    }

    auto floorBody = chrono_types::make_shared<ChBodyEasyBox>(20, 1, 20, 1000, true, true, mat);
    floorBody->SetPos(ChVector<>(0, -5, 0));
    floorBody->SetBodyFixed(true);
    m_system->Add(floorBody);

    auto wallBody1 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
    wallBody1->SetPos(ChVector<>(-10, 0, 0));
    wallBody1->SetBodyFixed(true);
    m_system->Add(wallBody1);

    auto wallBody2 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
    wallBody2->SetPos(ChVector<>(10, 0, 0));
    wallBody2->SetBodyFixed(true);
    m_system->Add(wallBody2);

    auto wallBody3 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
    wallBody3->SetPos(ChVector<>(0, 0, -10));
    wallBody3->SetBodyFixed(true);
    m_system->Add(wallBody3);

    auto wallBody4 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
    wallBody4->SetPos(ChVector<>(0, 0, 10));
    wallBody4->SetBodyFixed(true);
    m_system->Add(wallBody4);

    auto rotatingBody = chrono_types::make_shared<ChBodyEasyBox>(10, 5, 1, 4000, true, true, mat);
    rotatingBody->SetPos(ChVector<>(0, -1.6, 0));
    m_system->Add(rotatingBody);

    auto my_motor = chrono_types::make_shared<ChLinkMotorRotationSpeed>();
    my_motor->Initialize(rotatingBody, floorBody, ChFrame<>(ChVector<>(0, 0, 0), Q_from_AngAxis(CH_C_PI_2, VECT_X)));
    auto mfun = chrono_types::make_shared<ChFunction_Const>(CH_C_PI / 2.0);
    my_motor->SetSpeedFunction(mfun);
    m_system->AddLink(my_motor);
}

template <int N>
void MixerTestNSC<N>::SimulateVis() {
#ifdef CHRONO_IRRLICHT
    irrlicht::ChIrrApp application(m_system, L"Rigid contacts", irr::core::dimension2d<irr::u32>(800, 600), false, true);
    application.AddTypicalLogo();
    application.AddTypicalSky();
    application.AddTypicalLights();
    application.AddTypicalCamera(irr::core::vector3df(0, 14, -20));

    application.AssetBindAll();
    application.AssetUpdateAll();

    while (application.GetDevice()->run()) {
        application.BeginScene();
        application.DrawAll();
        ExecuteStep();
        application.EndScene();
    }
#endif
}

// =============================================================================

#define NUM_SKIP_STEPS 2000  // number of steps for hot start
#define NUM_SIM_STEPS 1000   // number of simulation steps for each benchmark

CH_BM_SIMULATION_LOOP(MixerNSC032, MixerTestNSC<32>,  NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);
CH_BM_SIMULATION_LOOP(MixerNSC064, MixerTestNSC<64>,  NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);

// =============================================================================

int main(int argc, char* argv[]) {
    ::benchmark::Initialize(&argc, argv);

#ifdef CHRONO_IRRLICHT
    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
        MixerTestNSC<64> test;
        test.SimulateVis();
        return 0;
    }
#endif

    ::benchmark::RunSpecifiedBenchmarks();
}
<commit_msg>Tweak benchmark test to ensure objects do not bounce out of the container<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2019 projectchrono.org
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban
// =============================================================================
//
// Benchmark test for contact simulation using NSC contact.
//
// =============================================================================

#include "chrono/ChConfig.h"
#include "chrono/utils/ChBenchmark.h"

#include "chrono/physics/ChSystemNSC.h"
#include "chrono/physics/ChBodyEasy.h"
#include "chrono/physics/ChLinkMotorRotationSpeed.h"

#include "chrono/assets/ChColorAsset.h"

#ifdef CHRONO_IRRLICHT
#include "chrono_irrlicht/ChIrrApp.h"
#endif

using namespace chrono;

// =============================================================================

template <int N>
class MixerTestNSC : public utils::ChBenchmarkTest {
  public:
    MixerTestNSC();
    ~MixerTestNSC() { delete m_system; }

    ChSystem* GetSystem() override { return m_system; }
    void ExecuteStep() override { m_system->DoStepDynamics(m_step); }

    void SimulateVis();

  private:
    ChSystemNSC* m_system;
    double m_step;
};

template <int N>
MixerTestNSC<N>::MixerTestNSC() : m_system(new ChSystemNSC()), m_step(0.02) {
    auto mat = chrono_types::make_shared<ChMaterialSurfaceNSC>();

    for (int bi = 0; bi < N; bi++) {
        auto sphereBody = chrono_types::make_shared<ChBodyEasySphere>(1.0, 1000, true, true, mat);
        sphereBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
        sphereBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.4f, 0.0f, 0.0f));
        m_system->Add(sphereBody);

        auto boxBody = chrono_types::make_shared<ChBodyEasyBox>(1.25, 1.25, 1.25, 1000, true, true, mat);
        boxBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
        boxBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.0f, 0.4f, 0.0f));
        m_system->Add(boxBody);

        auto cylBody = chrono_types::make_shared<ChBodyEasyCylinder>(0.8, 1.0, 1000, true, true, mat);
        cylBody->SetPos(ChVector<>(-5 + ChRandom() * 10, 4 + bi * 0.05, -5 + ChRandom() * 10));
        cylBody->AddAsset(chrono_types::make_shared<ChColorAsset>(0.0f, 0.0f, 0.4f));
        m_system->Add(cylBody);
    }

    auto floorBody = chrono_types::make_shared<ChBodyEasyBox>(20, 1, 20, 1000, true, true, mat);
    floorBody->SetPos(ChVector<>(0, -5, 0));
    floorBody->SetBodyFixed(true);
    m_system->Add(floorBody);

    auto wallBody1 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
    wallBody1->SetPos(ChVector<>(-10, 0, 0));
    wallBody1->SetBodyFixed(true);
    m_system->Add(wallBody1);

    auto wallBody2 = chrono_types::make_shared<ChBodyEasyBox>(1, 10, 20.99, 1000, true, true, mat);
    wallBody2->SetPos(ChVector<>(10, 0, 0));
    wallBody2->SetBodyFixed(true);
    m_system->Add(wallBody2);

    auto wallBody3 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
    wallBody3->SetPos(ChVector<>(0, 0, -10));
    wallBody3->SetBodyFixed(true);
    m_system->Add(wallBody3);

    auto wallBody4 = chrono_types::make_shared<ChBodyEasyBox>(20.99, 10, 1, 1000, true, true, mat);
    wallBody4->SetPos(ChVector<>(0, 0, 10));
    wallBody4->SetBodyFixed(true);
    m_system->Add(wallBody4);

    auto rotatingBody = chrono_types::make_shared<ChBodyEasyBox>(10, 5, 1, 4000, true, true, mat);
    rotatingBody->SetPos(ChVector<>(0, -1.6, 0));
    m_system->Add(rotatingBody);

    auto motor = chrono_types::make_shared<ChLinkMotorRotationSpeed>();
    motor->Initialize(rotatingBody, floorBody, ChFrame<>(ChVector<>(0, 0, 0), Q_from_AngAxis(CH_C_PI_2, VECT_X)));
    auto fun = chrono_types::make_shared<ChFunction_Const>(CH_C_PI / 3.0);
    motor->SetSpeedFunction(fun);
    m_system->AddLink(motor);
}

template <int N>
void MixerTestNSC<N>::SimulateVis() {
#ifdef CHRONO_IRRLICHT
    irrlicht::ChIrrApp application(m_system, L"Rigid contacts", irr::core::dimension2d<irr::u32>(800, 600), false, true);
    application.AddTypicalLogo();
    application.AddTypicalSky();
    application.AddTypicalLights();
    application.AddTypicalCamera(irr::core::vector3df(0, 14, -20));

    application.AssetBindAll();
    application.AssetUpdateAll();

    while (application.GetDevice()->run()) {
        application.BeginScene();
        application.DrawAll();
        ExecuteStep();
        application.EndScene();
    }
#endif
}

// =============================================================================

#define NUM_SKIP_STEPS 2000  // number of steps for hot start
#define NUM_SIM_STEPS 1000   // number of simulation steps for each benchmark

CH_BM_SIMULATION_LOOP(MixerNSC032, MixerTestNSC<32>,  NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);
CH_BM_SIMULATION_LOOP(MixerNSC064, MixerTestNSC<64>,  NUM_SKIP_STEPS, NUM_SIM_STEPS, 10);

// =============================================================================

int main(int argc, char* argv[]) {
    ::benchmark::Initialize(&argc, argv);

#ifdef CHRONO_IRRLICHT
    if (::benchmark::ReportUnrecognizedArguments(argc, argv)) {
        MixerTestNSC<64> test;
        test.SimulateVis();
        return 0;
    }
#endif

    ::benchmark::RunSpecifiedBenchmarks();
}
<|endoftext|>


<commit_before>#include "../../util/token.h"
#include "../../util/tokenreader.h"
#include <exception>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>

using namespace std;

class Failure: public exception{
public:
    Failure(int num):
    num(num){
    }

    int num;
};

static void test1_write(const string & name){
    ofstream out(name.c_str());
    out << "(foo)";
    out.close();
}

static string randomFile(){
    static char temp[64];
    sprintf(temp, "/tmp/tokenXXXXXX");
    return string(mktemp(temp));
}

static void test1(){
    try{
        string file = randomFile();
        test1_write(file);
        TokenReader reader(file);
        reader.readToken();
    } catch (...){
        throw Failure(1);
    }
}

static void test2_write(string name){
    ofstream out(name.c_str());
    out << "(foo";
    out.close();
}

static void test2(){
    try{
        string file = randomFile();
        test2_write(file);
        TokenReader reader(file);
        reader.readToken();
        throw Failure(2);
    } catch (const TokenException & e){
        /* good */
    }
}

int main(){
    try{
        test1();
        test2();
        cout << "All tests passed!" << endl;
    } catch (const Failure & f){
        cout << "Test case " << f.num << " failed" << endl;
    }
}
<commit_msg>add another token test<commit_after>#include "../../util/token.h"
#include "../../util/tokenreader.h"
#include <exception>
#include <iostream>
#include <fstream>
#include <stdlib.h>
#include <string>

using namespace std;

class Failure: public exception{
public:
    Failure(int num):
    num(num){
    }

    int num;
};

static void test1_write(const string & name){
    ofstream out(name.c_str());
    out << "(foo)";
    out.close();
}

static string randomFile(){
    static char temp[64];
    sprintf(temp, "/tmp/tokenXXXXXX");
    return string(mktemp(temp));
}

static void test1(){
    try{
        string file = randomFile();
        test1_write(file);
        TokenReader reader(file);
        reader.readToken();
    } catch (...){
        throw Failure(1);
    }
}

static void test2_write(string name){
    ofstream out(name.c_str());
    out << "(foo";
    out.close();
}

static void test2(){
    try{
        string file = randomFile();
        test2_write(file);
        TokenReader reader(file);
        reader.readToken();
        throw Failure(2);
    } catch (const TokenException & e){
        /* good */
    }
}

static void test3_write(string file){
    ofstream out(file.c_str());
    out << "(foo1 (foo2 (foo3)) (foo2 (foo3)))";
    out.close();
}

static void test3(){
    string file = randomFile();
    test3_write(file);
    TokenReader reader(file);
    Token * head = reader.readToken();
    vector<Token*> tokens = head->findTokens("foo1/foo2/foo3");
    if (tokens.size() != 2){
        throw Failure(3);
    }
}

int main(){
    try{
        test1();
        test2();
        test3();
        cout << "All tests passed!" << endl;
    } catch (const Failure & f){
        cout << "Test case " << f.num << " failed" << endl;
    }
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 *          Andreas Hansson
 */

/**
 * @file
 * Port object definitions.
 */

#include "base/chunk_generator.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/fs_translating_port_proxy.hh"

using namespace TheISA;

FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc)
    : PortProxy(*(tc->getCpuPtr()->getPort("dcache_port"))), _tc(tc)
{
}

FSTranslatingPortProxy::FSTranslatingPortProxy(Port &port)
    : PortProxy(port), _tc(NULL)
{
}

FSTranslatingPortProxy::~FSTranslatingPortProxy()
{
}

void
FSTranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
{
    Addr paddr;
    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
         gen.next())
    {
        if (_tc)
            paddr = TheISA::vtophys(_tc,gen.addr());
        else
            paddr = TheISA::vtophys(gen.addr());

        PortProxy::readBlob(paddr, p, gen.size());
        p += gen.size();
    }
}

void
FSTranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
{
    Addr paddr;
    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
         gen.next())
    {
        if (_tc)
            paddr = TheISA::vtophys(_tc,gen.addr());
        else
            paddr = TheISA::vtophys(gen.addr());

        PortProxy::writeBlob(paddr, p, gen.size());
        p += gen.size();
    }
}

void
FSTranslatingPortProxy::memsetBlob(Addr address, uint8_t v, int size)
{
    Addr paddr;
    for (ChunkGenerator gen(address, size, TheISA::PageBytes); !gen.done();
         gen.next())
    {
        if (_tc)
            paddr = TheISA::vtophys(_tc,gen.addr());
        else
            paddr = TheISA::vtophys(gen.addr());

        PortProxy::memsetBlob(paddr, v, gen.size());
    }
}

void
CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
{
    uint8_t *dst = (uint8_t *)dest;
    FSTranslatingPortProxy* vp = tc->getVirtProxy();

    vp->readBlob(src, dst, cplen);
}

void
CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
{
    uint8_t *src = (uint8_t *)source;
    FSTranslatingPortProxy* vp = tc->getVirtProxy();

    vp->writeBlob(dest, src, cplen);
}

void
CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
{
    int len = 0;
    char *start = dst;
    FSTranslatingPortProxy* vp = tc->getVirtProxy();

    do {
        vp->readBlob(vaddr++, (uint8_t*)dst++, 1);
    } while (len < maxlen && start[len++] != 0 );

    dst[len] = 0;
}

void
CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
    FSTranslatingPortProxy* vp = tc->getVirtProxy();
    for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
            gen.next())
    {
        vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
        src += gen.size();
    }
}
<commit_msg>Fix memory corruption issue with CopyStringOut()<commit_after>/*
 * Copyright (c) 2011 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2006 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Ali Saidi
 *          Andreas Hansson
 */

/**
 * @file
 * Port object definitions.
 */

#include "base/chunk_generator.hh"
#include "cpu/base.hh"
#include "cpu/thread_context.hh"
#include "mem/fs_translating_port_proxy.hh"

using namespace TheISA;

FSTranslatingPortProxy::FSTranslatingPortProxy(ThreadContext *tc)
    : PortProxy(*(tc->getCpuPtr()->getPort("dcache_port"))), _tc(tc)
{
}

FSTranslatingPortProxy::FSTranslatingPortProxy(Port &port)
    : PortProxy(port), _tc(NULL)
{
}

FSTranslatingPortProxy::~FSTranslatingPortProxy()
{
}

void
FSTranslatingPortProxy::readBlob(Addr addr, uint8_t *p, int size)
{
    Addr paddr;
    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
         gen.next())
    {
        if (_tc)
            paddr = TheISA::vtophys(_tc,gen.addr());
        else
            paddr = TheISA::vtophys(gen.addr());

        PortProxy::readBlob(paddr, p, gen.size());
        p += gen.size();
    }
}

void
FSTranslatingPortProxy::writeBlob(Addr addr, uint8_t *p, int size)
{
    Addr paddr;
    for (ChunkGenerator gen(addr, size, TheISA::PageBytes); !gen.done();
         gen.next())
    {
        if (_tc)
            paddr = TheISA::vtophys(_tc,gen.addr());
        else
            paddr = TheISA::vtophys(gen.addr());

        PortProxy::writeBlob(paddr, p, gen.size());
        p += gen.size();
    }
}

void
FSTranslatingPortProxy::memsetBlob(Addr address, uint8_t v, int size)
{
    Addr paddr;
    for (ChunkGenerator gen(address, size, TheISA::PageBytes); !gen.done();
         gen.next())
    {
        if (_tc)
            paddr = TheISA::vtophys(_tc,gen.addr());
        else
            paddr = TheISA::vtophys(gen.addr());

        PortProxy::memsetBlob(paddr, v, gen.size());
    }
}

void
CopyOut(ThreadContext *tc, void *dest, Addr src, size_t cplen)
{
    uint8_t *dst = (uint8_t *)dest;
    FSTranslatingPortProxy* vp = tc->getVirtProxy();

    vp->readBlob(src, dst, cplen);
}

void
CopyIn(ThreadContext *tc, Addr dest, void *source, size_t cplen)
{
    uint8_t *src = (uint8_t *)source;
    FSTranslatingPortProxy* vp = tc->getVirtProxy();

    vp->writeBlob(dest, src, cplen);
}

void
CopyStringOut(ThreadContext *tc, char *dst, Addr vaddr, size_t maxlen)
{
    char *start = dst;
    FSTranslatingPortProxy* vp = tc->getVirtProxy();

    bool foundNull = false;
    while ((dst - start + 1) < maxlen && !foundNull) {
        vp->readBlob(vaddr++, (uint8_t*)dst, 1);
        if (dst == '\0')
            foundNull = true;
        dst++;
    }

    if (!foundNull)
        *dst = '\0';
}

void
CopyStringIn(ThreadContext *tc, char *src, Addr vaddr)
{
    FSTranslatingPortProxy* vp = tc->getVirtProxy();
    for (ChunkGenerator gen(vaddr, strlen(src), TheISA::PageBytes); !gen.done();
            gen.next())
    {
        vp->writeBlob(gen.addr(), (uint8_t*)src, gen.size());
        src += gen.size();
    }
}
<|endoftext|>


<commit_before>#include "StandardCells.h"

namespace ophidian {
namespace standard_cell {

StandardCells::StandardCells() :
    cellNames_(cells_), pinNames_(pins_), pinDirections_(pins_),
    cellPins_(cells_, pins_)
{

}

StandardCells::StandardCells(const StandardCells && stdCell) :
	cells_(std::move(stdCell.cells_)),
	pins_(std::move(stdCell.pins_)),
    cellNames_(std::move(stdCell.cellNames_)),
    pinNames_(std::move(stdCell.pinNames_)),
    pinDirections_(std::move(stdCell.pinDirections_)),
    cellPins_(std::move(stdCell.cellPins_))
{

}

StandardCells::~StandardCells() = default;

//--------------------------- Cells -------------------------------//

Cell StandardCells::add(Cell, const std::__cxx11::string &name)
{
    auto cell = cells_.add();
    cellNames_[cell] = name;
    return cell;
}

void StandardCells::erase(const Cell & cell)
{
	cells_.erase(cell);
}

void StandardCells::reserve(Cell, uint32_t size)
{
	cells_.reserve(size);
}

uint32_t StandardCells::size(Cell) const
{
	return cells_.size();
}

uint32_t StandardCells::capacity(Cell) const
{
	return cells_.capacity();
}

std::string StandardCells::name(const Cell & cell) const
{
    return cellNames_[cell];
}

entity_system::Association<Cell, Pin>::Parts StandardCells::pins(const Cell &cell) const
{
    return cellPins_.parts(cell);
}

ophidian::util::Range<StandardCells::CellsIterator> StandardCells::range(Cell) const
{
	return ophidian::util::Range<StandardCells::CellsIterator>(cells_.begin(), cells_.end());
}

//--------------------------- Pins -------------------------------//

Pin StandardCells::add(Pin, const std::__cxx11::string &name, PinDirection direction)
{
    auto pin = pins_.add();
    pinNames_[pin] = name;
    pinDirections_[pin] = direction;
    return pin;
}

void StandardCells::erase(const Pin & pin)
{
	pins_.erase(pin);
}

void StandardCells::reserve(Pin, uint32_t size)
{
	pins_.reserve(size);
}

uint32_t StandardCells::size(Pin) const
{
	return pins_.size();
}

uint32_t StandardCells::capacity(Pin) const
{
	return pins_.capacity();
}

std::string StandardCells::name(const Pin & pin) const
{
	return pinNames_[pin];
}

PinDirection StandardCells::direction(const Pin & pin)
{
    return pinDirections_[pin];
}

Cell StandardCells::owner(const Pin & pin)
{
    return cellPins_.whole(pin);
}

ophidian::util::Range<StandardCells::PinsIterator> StandardCells::range(Pin) const
{
	return ophidian::util::Range<StandardCells::PinsIterator>(pins_.begin(), pins_.end());
}

//--------------------------- Association -------------------------------//

//! Add Pin into Cell
/*!
   \brief Adds a Pin to a given Cell.
   \param cell A handler for the Cell we want to add a Pin.
   \param pin A handler for the Pin we want to add in \p cell.
 */
void StandardCells::add(const Cell& cell, const Pin& pin)
{
	cellPins_.addAssociation(cell, pin);
}

} //namespace ophidian

} //namespace standard_cell
<commit_msg>using std::string instead of std::__cxx11::string (Travis is not compiling with std::__cxx11::string).<commit_after>#include "StandardCells.h"

namespace ophidian {
namespace standard_cell {

StandardCells::StandardCells() :
    cellNames_(cells_), pinNames_(pins_), pinDirections_(pins_),
    cellPins_(cells_, pins_)
{

}

StandardCells::StandardCells(const StandardCells && stdCell) :
	cells_(std::move(stdCell.cells_)),
	pins_(std::move(stdCell.pins_)),
    cellNames_(std::move(stdCell.cellNames_)),
    pinNames_(std::move(stdCell.pinNames_)),
    pinDirections_(std::move(stdCell.pinDirections_)),
    cellPins_(std::move(stdCell.cellPins_))
{

}

StandardCells::~StandardCells() = default;

//--------------------------- Cells -------------------------------//

Cell StandardCells::add(Cell, const std::string &name)
{
    auto cell = cells_.add();
    cellNames_[cell] = name;
    return cell;
}

void StandardCells::erase(const Cell & cell)
{
	cells_.erase(cell);
}

void StandardCells::reserve(Cell, uint32_t size)
{
	cells_.reserve(size);
}

uint32_t StandardCells::size(Cell) const
{
	return cells_.size();
}

uint32_t StandardCells::capacity(Cell) const
{
	return cells_.capacity();
}

std::string StandardCells::name(const Cell & cell) const
{
    return cellNames_[cell];
}

entity_system::Association<Cell, Pin>::Parts StandardCells::pins(const Cell &cell) const
{
    return cellPins_.parts(cell);
}

ophidian::util::Range<StandardCells::CellsIterator> StandardCells::range(Cell) const
{
	return ophidian::util::Range<StandardCells::CellsIterator>(cells_.begin(), cells_.end());
}

//--------------------------- Pins -------------------------------//

Pin StandardCells::add(Pin, const std::string &name, PinDirection direction)
{
    auto pin = pins_.add();
    pinNames_[pin] = name;
    pinDirections_[pin] = direction;
    return pin;
}

void StandardCells::erase(const Pin & pin)
{
	pins_.erase(pin);
}

void StandardCells::reserve(Pin, uint32_t size)
{
	pins_.reserve(size);
}

uint32_t StandardCells::size(Pin) const
{
	return pins_.size();
}

uint32_t StandardCells::capacity(Pin) const
{
	return pins_.capacity();
}

std::string StandardCells::name(const Pin & pin) const
{
	return pinNames_[pin];
}

PinDirection StandardCells::direction(const Pin & pin)
{
    return pinDirections_[pin];
}

Cell StandardCells::owner(const Pin & pin)
{
    return cellPins_.whole(pin);
}

ophidian::util::Range<StandardCells::PinsIterator> StandardCells::range(Pin) const
{
	return ophidian::util::Range<StandardCells::PinsIterator>(pins_.begin(), pins_.end());
}

//--------------------------- Association -------------------------------//

//! Add Pin into Cell
/*!
   \brief Adds a Pin to a given Cell.
   \param cell A handler for the Cell we want to add a Pin.
   \param pin A handler for the Pin we want to add in \p cell.
 */
void StandardCells::add(const Cell& cell, const Pin& pin)
{
	cellPins_.addAssociation(cell, pin);
}

} //namespace ophidian

} //namespace standard_cell
<|endoftext|>