<commit_before>#include <wx/url.h>
#include <wx/log.h>
#include <wx/intl.h>
#include <wx/tokenzr.h>
#include <wx/listimpl.cpp>
#include <wx/utils.h>

#include "main.h"
#include "listserverhandler.h"

WX_DEFINE_LIST(ServerList);

void ListServerHandler::GetServerList() {
	wxBusyCursor wait;
	BZLauncherApp& app = wxGetApp();

	app.SetStatusText(_("Fetching data from list-server..."));

	this->ClearList();

	if( this->GetListServerResponse() ) {
		app.SetStatusText(_("Parsing data from list-server..."));
		wxStringTokenizer tok(this->rawResponse, _T("\r\n"));

		while(tok.HasMoreTokens()) {
			wxString token = tok.GetNextToken();

			this->ParseLine(token);
		}
	}
	else {
		wxLogError(_("Can't connect to listserver!"));
	}
	app.SetStatusText(wxString::Format(_("Found %d server(s)"), this->serverList.GetCount()));
}

bool ListServerHandler::ParseLine(const wxString& line) {
	Server* s = new Server;

	wxStringTokenizer tok(line, _T(" "));

	int i = 0;
	while(tok.HasMoreTokens()) {
		wxString token = tok.GetNextToken();
		switch(i) {
		case 0:
			s->serverHostPort = token;
			break;
		case 1:
			s->protocolVersion = token;
			// We only parse BZFS0026 for now
			if( token.Cmp(_T("BZFS0026")) != 0 )
				return false;
			break;
		case 2:
			s->ParseServerInfo(token);
			break;
		case 3:
			s->ip.Hostname(token);

			// Get remaining stuff
			s->name += tok.GetString();
			break;
		}
		i++;
	}

	this->serverList.Append(s);

	return true;
}

bool ListServerHandler::GetListServerResponse() {
	wxURL listserv(wxT("http://my.bzflag.org/db?action=LIST"));

	if(listserv.IsOk()) {
		wxInputStream *in_stream;
		in_stream = listserv.GetInputStream();
		char		buffer[1024];

		this->rawResponse.Clear();

		while(!in_stream->Read(buffer,1024).Eof())
			this->rawResponse << wxString::From8BitData(buffer,in_stream->LastRead());

		return true;
	}

	return false;
}

void ListServerHandler::ClearList() {
	ServerList::iterator i;
	for(i = this->serverList.begin(); i != this->serverList.end(); ++i) {
		Server*	current = *i;

		delete current;
	}

	this->serverList.Clear();
}
<commit_msg>Clear selected server, everytime the server-list is refreshed (to avoid dangling pointers)<commit_after>#include <wx/url.h>
#include <wx/log.h>
#include <wx/intl.h>
#include <wx/tokenzr.h>
#include <wx/listimpl.cpp>
#include <wx/utils.h>

#include "main.h"
#include "listserverhandler.h"

WX_DEFINE_LIST(ServerList);

void ListServerHandler::GetServerList() {
	wxBusyCursor wait;
	BZLauncherApp& app = wxGetApp();

	app.SetStatusText(_("Fetching data from list-server..."));

	this->ClearList();

	if( this->GetListServerResponse() ) {
		app.SetStatusText(_("Parsing data from list-server..."));
		wxStringTokenizer tok(this->rawResponse, _T("\r\n"));

		while(tok.HasMoreTokens()) {
			wxString token = tok.GetNextToken();

			this->ParseLine(token);
		}
	}
	else {
		wxLogError(_("Can't connect to listserver!"));
	}
	app.SetStatusText(wxString::Format(_("Found %d server(s)"), this->serverList.GetCount()));
}

bool ListServerHandler::ParseLine(const wxString& line) {
	Server* s = new Server;

	wxStringTokenizer tok(line, _T(" "));

	int i = 0;
	while(tok.HasMoreTokens()) {
		wxString token = tok.GetNextToken();
		switch(i) {
		case 0:
			s->serverHostPort = token;
			break;
		case 1:
			s->protocolVersion = token;
			// We only parse BZFS0026 for now
			if( token.Cmp(_T("BZFS0026")) != 0 )
				return false;
			break;
		case 2:
			s->ParseServerInfo(token);
			break;
		case 3:
			s->ip.Hostname(token);

			// Get remaining stuff
			s->name += tok.GetString();
			break;
		}
		i++;
	}

	this->serverList.Append(s);

	return true;
}

bool ListServerHandler::GetListServerResponse() {
	wxURL listserv(wxT("http://my.bzflag.org/db?action=LIST"));

	if(listserv.IsOk()) {
		wxInputStream *in_stream;
		in_stream = listserv.GetInputStream();
		char		buffer[1024];

		this->rawResponse.Clear();

		while(!in_stream->Read(buffer,1024).Eof())
			this->rawResponse << wxString::From8BitData(buffer,in_stream->LastRead());

		return true;
	}

	return false;
}

void ListServerHandler::ClearList() {
	BZLauncherApp& app = wxGetApp();
	app.SetSelectedServer(NULL);

	ServerList::iterator i;
	for(i = this->serverList.begin(); i != this->serverList.end(); ++i) {
		Server*	current = *i;
		delete current;
	}

	this->serverList.Clear();
}
<|endoftext|>


<commit_before>/*
 * Simple cache model for predicting miss rates.
 *
 * By Eric Anger <eanger@lanl.gov>
 */

#include <algorithm>
#include <iterator>

#include "byfl.h"

namespace bytesflops {}
using namespace bytesflops;
using namespace std;

class Cache {
  public:
    void access(uint64_t baseaddr, uint64_t numaddrs);
    Cache(uint64_t line_size) : line_size_{line_size}, accesses_{0} {}
    uint64_t getAccesses() const { return accesses_; }
    vector<uint64_t> getHits() const { return hits_; }

  private:
    vector<uint64_t> lines_; // back is mru, front is lru
    uint64_t line_size_;
    uint64_t accesses_;
    vector<uint64_t> hits_;  // back is lru, front is mru
};

void Cache::access(uint64_t baseaddr, uint64_t numaddrs){
  uint64_t num_accesses = 0; // running total of number of lines accessed
  for(uint64_t addr = baseaddr / line_size_ * line_size_;
      addr <= (baseaddr + numaddrs ) / line_size_ * line_size_;
      addr += line_size_){
    ++num_accesses;
    auto line = lines_.rbegin();
    auto hit = begin(hits_);
    bool found = false;
    for(; line != lines_.rend(); ++line, ++hit){
      if(addr == *line){
        found = true;
        transform(hit, end(hits_), hit,
                  [=](const uint64_t cur_hits){return cur_hits + 1;});
        // erase the line pointed to by this reverse iterator. see
        // stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-iterator
        lines_.erase((line + 1).base());
        break;
      }
    }

    if(!found){
      // make a new entry containing all previous hits plus any that occur
      // this time
      hits_.push_back(accesses_ + num_accesses);
    }

    // move up this address to mru position
    lines_.push_back(addr);
  }

  // we've made all our accesses
  ++accesses_;
}

static Cache* cache = NULL;

namespace bytesflops{

void initialize_cache(void){
  cache = new Cache(bf_line_size);
}

// Access the cache model with this address.
void bf_touch_cache(uint64_t baseaddr, uint64_t numaddrs){
  cache->access(baseaddr, numaddrs);
}

// Get cache accesses
uint64_t bf_get_cache_accesses(void){
  return cache->getAccesses();
}

// Get cache hits
vector<uint64_t> bf_get_cache_hits(void){
  return cache->getHits();
}

} // namespace bytesflops
<commit_msg>Increment total accesses with the number of distinct cache lines requested.<commit_after>/*
 * Simple cache model for predicting miss rates.
 *
 * By Eric Anger <eanger@lanl.gov>
 */

#include <algorithm>
#include <iterator>

#include "byfl.h"

namespace bytesflops {}
using namespace bytesflops;
using namespace std;

class Cache {
  public:
    void access(uint64_t baseaddr, uint64_t numaddrs);
    Cache(uint64_t line_size) : line_size_{line_size}, accesses_{0} {}
    uint64_t getAccesses() const { return accesses_; }
    vector<uint64_t> getHits() const { return hits_; }

  private:
    vector<uint64_t> lines_; // back is mru, front is lru
    uint64_t line_size_;
    uint64_t accesses_;
    vector<uint64_t> hits_;  // back is lru, front is mru
};

void Cache::access(uint64_t baseaddr, uint64_t numaddrs){
  uint64_t num_accesses = 0; // running total of number of lines accessed
  for(uint64_t addr = baseaddr / line_size_ * line_size_;
      addr <= (baseaddr + numaddrs ) / line_size_ * line_size_;
      addr += line_size_){
    ++num_accesses;
    auto line = lines_.rbegin();
    auto hit = begin(hits_);
    bool found = false;
    for(; line != lines_.rend(); ++line, ++hit){
      if(addr == *line){
        found = true;
        transform(hit, end(hits_), hit,
                  [=](const uint64_t cur_hits){return cur_hits + 1;});
        // erase the line pointed to by this reverse iterator. see
        // stackoverflow.com/questions/1830158/how-to-call-erase-with-a-reverse-iterator
        lines_.erase((line + 1).base());
        break;
      }
    }

    if(!found){
      // make a new entry containing all previous hits plus any that occur
      // this time
      hits_.push_back(accesses_ + num_accesses);
    }

    // move up this address to mru position
    lines_.push_back(addr);
  }

  // we've made all our accesses
  accesses_ += num_accesses;
}

static Cache* cache = NULL;

namespace bytesflops{

void initialize_cache(void){
  cache = new Cache(bf_line_size);
}

// Access the cache model with this address.
void bf_touch_cache(uint64_t baseaddr, uint64_t numaddrs){
  cache->access(baseaddr, numaddrs);
}

// Get cache accesses
uint64_t bf_get_cache_accesses(void){
  return cache->getAccesses();
}

// Get cache hits
vector<uint64_t> bf_get_cache_hits(void){
  return cache->getHits();
}

} // namespace bytesflops
<|endoftext|>


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

#include "clientversion.h"

#include "tinyformat.h"

#include <string>

/**
 * Name of client reported in the 'version' message. Report the same name
 * for both syscoind and syscoin-qt, to make it harder for attackers to
 * target servers or GUI users specifically.
 */
const std::string CLIENT_NAME("Syscoin Core");

/**
 * Client version number
 */
#define CLIENT_VERSION_SUFFIX ""

/**
 * The following part of the code determines the CLIENT_BUILD variable.
 * Several mechanisms are used for this:
 * * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
 *   generated by the build environment, possibly containing the output
 *   of git-describe in a macro called BUILD_DESC
 * * secondly, if this is an exported version of the code, GIT_ARCHIVE will
 *   be defined (automatically using the export-subst git attribute), and
 *   GIT_COMMIT will contain the commit id.
 * * then, three options exist for determining CLIENT_BUILD:
 *   * if BUILD_DESC is defined, use that literally (output of git-describe)
 *   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
 *   * otherwise, use v[maj].[min].[rev].[build]-unk
 * finally CLIENT_VERSION_SUFFIX is added
 */

//! First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#include "build.h"
#endif

//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$
#ifdef GIT_ARCHIVE
#define GIT_COMMIT_ID "$Format:%h$"
#define GIT_COMMIT_DATE "$Format:%cD$"
#endif

#define BUILD_DESC_WITH_SUFFIX(maj, min, rev, build, suffix) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-" DO_STRINGIZE(suffix)

#define BUILD_DESC_FROM_COMMIT(maj, min, rev, build, commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj, min, rev, build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#ifdef BUILD_SUFFIX
#define BUILD_DESC BUILD_DESC_WITH_SUFFIX(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, BUILD_SUFFIX)
#elif defined(GIT_COMMIT_ID)
#define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#else
#define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);

std::string FormatVersion(int nVersion)
{
    if (nVersion % 100 == 0)
        return strprintf("%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100);
    else
        return strprintf("%d.%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, nVersion % 100);
}

std::string FormatFullVersion()
{
    return CLIENT_BUILD;
}

std::string FormatDashVersion()
{
	return DASH_VERSION;
}

/**
 * Format the subversion field according to BIP 14 spec (https://github.com/syscoin/bips/blob/master/bip-0014.mediawiki)
 */
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
{
    std::ostringstream ss;
    ss << "/";
    ss << name << ":" << FormatVersion(nClientVersion);
    if (!comments.empty())
    {
        std::vector<std::string>::const_iterator it(comments.begin());
        ss << "(" << *it;
        for(++it; it != comments.end(); ++it)
            ss << "; " << *it;
        ss << ")";
    }
    ss << "/";
    return ss.str();
}
<commit_msg>fix build.h include<commit_after>// Copyright (c) 2012-2014 The Syscoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "clientversion.h"

#include "tinyformat.h"

#include <string>

/**
 * Name of client reported in the 'version' message. Report the same name
 * for both syscoind and syscoin-qt, to make it harder for attackers to
 * target servers or GUI users specifically.
 */
const std::string CLIENT_NAME("Syscoin Core");

/**
 * Client version number
 */
#define CLIENT_VERSION_SUFFIX ""

/**
 * The following part of the code determines the CLIENT_BUILD variable.
 * Several mechanisms are used for this:
 * * first, if HAVE_BUILD_INFO is defined, include build.h, a file that is
 *   generated by the build environment, possibly containing the output
 *   of git-describe in a macro called BUILD_DESC
 * * secondly, if this is an exported version of the code, GIT_ARCHIVE will
 *   be defined (automatically using the export-subst git attribute), and
 *   GIT_COMMIT will contain the commit id.
 * * then, three options exist for determining CLIENT_BUILD:
 *   * if BUILD_DESC is defined, use that literally (output of git-describe)
 *   * if not, but GIT_COMMIT is defined, use v[maj].[min].[rev].[build]-g[commit]
 *   * otherwise, use v[maj].[min].[rev].[build]-unk
 * finally CLIENT_VERSION_SUFFIX is added
 */

//! First, include build.h if requested
#ifdef HAVE_BUILD_INFO
#include <obj/build.h>
#endif

//! git will put "#define GIT_ARCHIVE 1" on the next line inside archives. $Format:%n#define GIT_ARCHIVE 1$
#ifdef GIT_ARCHIVE
#define GIT_COMMIT_ID "$Format:%h$"
#define GIT_COMMIT_DATE "$Format:%cD$"
#endif

#define BUILD_DESC_WITH_SUFFIX(maj, min, rev, build, suffix) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-" DO_STRINGIZE(suffix)

#define BUILD_DESC_FROM_COMMIT(maj, min, rev, build, commit) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-g" commit

#define BUILD_DESC_FROM_UNKNOWN(maj, min, rev, build) \
    "v" DO_STRINGIZE(maj) "." DO_STRINGIZE(min) "." DO_STRINGIZE(rev) "." DO_STRINGIZE(build) "-unk"

#ifndef BUILD_DESC
#ifdef BUILD_SUFFIX
#define BUILD_DESC BUILD_DESC_WITH_SUFFIX(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, BUILD_SUFFIX)
#elif defined(GIT_COMMIT_ID)
#define BUILD_DESC BUILD_DESC_FROM_COMMIT(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD, GIT_COMMIT_ID)
#else
#define BUILD_DESC BUILD_DESC_FROM_UNKNOWN(CLIENT_VERSION_MAJOR, CLIENT_VERSION_MINOR, CLIENT_VERSION_REVISION, CLIENT_VERSION_BUILD)
#endif
#endif

const std::string CLIENT_BUILD(BUILD_DESC CLIENT_VERSION_SUFFIX);

std::string FormatVersion(int nVersion)
{
    if (nVersion % 100 == 0)
        return strprintf("%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100);
    else
        return strprintf("%d.%d.%d.%d", nVersion / 1000000, (nVersion / 10000) % 100, (nVersion / 100) % 100, nVersion % 100);
}

std::string FormatFullVersion()
{
    return CLIENT_BUILD;
}

std::string FormatDashVersion()
{
	return DASH_VERSION;
}

/**
 * Format the subversion field according to BIP 14 spec (https://github.com/syscoin/bips/blob/master/bip-0014.mediawiki)
 */
std::string FormatSubVersion(const std::string& name, int nClientVersion, const std::vector<std::string>& comments)
{
    std::ostringstream ss;
    ss << "/";
    ss << name << ":" << FormatVersion(nClientVersion);
    if (!comments.empty())
    {
        std::vector<std::string>::const_iterator it(comments.begin());
        ss << "(" << *it;
        for(++it; it != comments.end(); ++it)
            ss << "; " << *it;
        ss << ")";
    }
    ss << "/";
    return ss.str();
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include "common.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "reports/ReportBuilder.h"
#include "reports/JoinedQueryTableReport.h"
#include "reports/CTRByPositionReport.h"
#include "reports/CTRCounterMerge.h"
#include "reports/CTRCounterSSTableSink.h"
#include "reports/CTRCounterSSTableSource.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "conf",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      "./conf",
      "conf directory",
      "<path>");

  flags.defineFlag(
      "index",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "index directory",
      "<path>");

  flags.defineFlag(
      "artifacts",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  fnord::fts::Analyzer analyzer(flags.getString("conf"));

  cm::ReportBuilder report_builder;

  Set<uint64_t> generations { };

  /* find all generations */
  auto dir = flags.getString("artifacts");
  FileUtil::ls(dir, [&generations] (const String& file) -> bool {
    String prefix = "dawanda_joined_queries.";
    if (StringUtil::beginsWith(file, prefix)) {
      generations.emplace(std::stoul(file.substr(prefix.length())));
    }
    return true;
  });

  uint64_t min_gen = std::numeric_limits<uint64_t>::max();
  uint64_t max_gen = std::numeric_limits<uint64_t>::min();
  for (const auto g : generations) {
    if (g < min_gen) {
      min_gen = g;
    }

    if (g > max_gen) {
      max_gen = g;
    }
  }

  /* dawanda -- MAP: input joined queries */
  for (const auto& g : generations) {
    auto jq_report = new JoinedQueryTableReport(Set<String> {
        StringUtil::format("$0/dawanda_joined_queries.$1.sstable", dir, g) });
    report_builder.addReport(jq_report);

    auto ctr_by_posi_report = new CTRByPositionReport(ItemEligibility::ALL);
    ctr_by_posi_report->addReport(new CTRCounterSSTableSink(
        StringUtil::format("$0/dawanda_ctr_by_position.$1.sstable", dir, g)));
    jq_report->addReport(ctr_by_posi_report);
  }

  /* dawanda -- REDUCE: rollup ctr_by_position */
  if (generations.size() > 0) {
    Set<String> ctr_posi_sources;
    for (const auto& g : generations) {
      ctr_posi_sources.emplace(
          StringUtil::format("$0/dawanda_ctr_by_position.$1.sstable", dir, g));
    }

    auto ctr_posi_rollup_in = new CTRCounterSSTableSource(ctr_posi_sources);
    report_builder.addReport(ctr_posi_rollup_in);

    auto ctr_posi_rollup = new CTRCounterMerge();
    ctr_posi_rollup->addReport(new CTRCounterSSTableSink(
        StringUtil::format(
            "$0/dawanda_ctr_by_position_merged.$1-$1.sstable",
            dir,
            min_gen,
            max_gen)));
    ctr_posi_rollup_in->addReport(ctr_posi_rollup);
  }

  report_builder.buildAll();
  return 0;
}

<commit_msg>enqueue all generations<commit_after>/**
 * Copyright (c) 2015 - The CM Authors <legal@clickmatcher.com>
 *   All Rights Reserved.
 *
 * This file is CONFIDENTIAL -- Distribution or duplication of this material or
 * the information contained herein is strictly forbidden unless prior written
 * permission is obtained.
 */
#include <algorithm>
#include <stdlib.h>
#include <unistd.h>
#include <signal.h>
#include "fnord-base/io/fileutil.h"
#include "fnord-base/application.h"
#include "fnord-base/logging.h"
#include "fnord-base/Language.h"
#include "fnord-base/cli/flagparser.h"
#include "fnord-base/util/SimpleRateLimit.h"
#include "fnord-base/InternMap.h"
#include "fnord-json/json.h"
#include "fnord-mdb/MDB.h"
#include "fnord-mdb/MDBUtil.h"
#include "fnord-sstable/sstablereader.h"
#include "fnord-sstable/sstablewriter.h"
#include "fnord-sstable/SSTableColumnSchema.h"
#include "fnord-sstable/SSTableColumnReader.h"
#include "fnord-sstable/SSTableColumnWriter.h"
#include "common.h"
#include "CustomerNamespace.h"
#include "FeatureSchema.h"
#include "JoinedQuery.h"
#include "CTRCounter.h"
#include <fnord-fts/fts.h>
#include <fnord-fts/fts_common.h>
#include "reports/ReportBuilder.h"
#include "reports/JoinedQueryTableReport.h"
#include "reports/CTRByPositionReport.h"
#include "reports/CTRCounterMerge.h"
#include "reports/CTRCounterSSTableSink.h"
#include "reports/CTRCounterSSTableSource.h"

using namespace fnord;
using namespace cm;

int main(int argc, const char** argv) {
  fnord::Application::init();
  fnord::Application::logToStderr();

  fnord::cli::FlagParser flags;

  flags.defineFlag(
      "conf",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      "./conf",
      "conf directory",
      "<path>");

  flags.defineFlag(
      "index",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "index directory",
      "<path>");

  flags.defineFlag(
      "artifacts",
      cli::FlagParser::T_STRING,
      false,
      NULL,
      NULL,
      "artifact directory",
      "<path>");

  flags.defineFlag(
      "loglevel",
      fnord::cli::FlagParser::T_STRING,
      false,
      NULL,
      "INFO",
      "loglevel",
      "<level>");

  flags.parseArgv(argc, argv);

  Logger::get()->setMinimumLogLevel(
      strToLogLevel(flags.getString("loglevel")));

  fnord::fts::Analyzer analyzer(flags.getString("conf"));
  cm::ReportBuilder report_builder;

  auto dir = flags.getString("artifacts");

  Set<uint64_t> generations;
  auto now = WallClock::unixMicros();
  auto gen_window = kMicrosPerSecond * 3600 * 4;
  for (uint64_t i = 0; i < kMicrosPerDay * 32; i += gen_window) {
    generations.emplace((now - i) / gen_window);
  }

  uint64_t min_gen = std::numeric_limits<uint64_t>::max();
  uint64_t max_gen = std::numeric_limits<uint64_t>::min();
  for (const auto g : generations) {
    if (g < min_gen) {
      min_gen = g;
    }

    if (g > max_gen) {
      max_gen = g;
    }
  }

  /* dawanda -- MAP: input joined queries */
  for (const auto& g : generations) {
    auto jq_report = new JoinedQueryTableReport(Set<String> {
        StringUtil::format("$0/dawanda_joined_queries.$1.sstable", dir, g) });
    report_builder.addReport(jq_report);

    auto ctr_by_posi_report = new CTRByPositionReport(ItemEligibility::ALL);
    ctr_by_posi_report->addReport(new CTRCounterSSTableSink(
        StringUtil::format("$0/dawanda_ctr_by_position.$1.sstable", dir, g)));
    jq_report->addReport(ctr_by_posi_report);
  }

  /* dawanda -- REDUCE: rollup ctr_by_position */
  if (generations.size() > 0) {
    Set<String> ctr_posi_sources;
    for (const auto& g : generations) {
      ctr_posi_sources.emplace(
          StringUtil::format("$0/dawanda_ctr_by_position.$1.sstable", dir, g));
    }

    auto ctr_posi_rollup_in = new CTRCounterSSTableSource(ctr_posi_sources);
    report_builder.addReport(ctr_posi_rollup_in);

    auto ctr_posi_rollup = new CTRCounterMerge();
    ctr_posi_rollup->addReport(new CTRCounterSSTableSink(
        StringUtil::format(
            "$0/dawanda_ctr_by_position_merged.$1-$1.sstable",
            dir,
            min_gen,
            max_gen)));
    ctr_posi_rollup_in->addReport(ctr_posi_rollup);
  }

  report_builder.buildAll();
  return 0;
}

<|endoftext|>


<commit_before>// Copyright (c) 2015, Baidu.com, 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 "master_util.h"

#include <sstream>
#include <sys/utsname.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
#include <gflags/gflags.h>
#include <logging.h>

#include "proto/galaxy.pb.h"
#include "proto/master.pb.h"

DECLARE_string(master_port);

namespace baidu {
namespace galaxy {

std::string MasterUtil::UUID() {
    boost::uuids::uuid uuid = boost::uuids::random_generator()();
    return boost::lexical_cast<std::string>(uuid);
}

void MasterUtil::AddResource(const Resource& from, Resource* to) {
    to->set_millicores(to->millicores() + from.millicores());
    to->set_memory(to->memory() + from.memory());
}

void MasterUtil::SubstractResource(const Resource& from, Resource* to) {
    assert(FitResource(from, *to));
    to->set_millicores(to->millicores() - from.millicores());
    to->set_memory(to->memory() - from.memory());
}

bool MasterUtil::FitResource(const Resource& from, const Resource& to) {
    if (to.millicores() < from.millicores()) {
        return false;
    }
    if (to.memory() < from.memory()) {
        return false;
    }
    // TODO: check port & disk & ssd
    return true;
}

std::string MasterUtil::SelfEndpoint() {
    std::string hostname = "";
    struct utsname buf;
    if (0 != uname(&buf)) {
        *buf.nodename = '\0';
    }
    hostname = buf.nodename;
    return hostname + ":" + FLAGS_master_port;
}

void MasterUtil::TraceJobDesc(const JobDescriptor& job_desc) {
    LOG(INFO, "job descriptor: \"%s\", "
              "replica:%d, "
              "deploy_step:%d",
              job_desc.name().c_str(),
              job_desc.replica(),
              job_desc.deploy_step()
    );
    LOG(INFO, "pod descriptor mem:%ld, cpu:%d, port_size:%d",
       job_desc.pod().requirement().memory(),
       job_desc.pod().requirement().millicores(),
       job_desc.pod().requirement().ports_size());
    for (int i = 0; i < job_desc.pod().tasks_size(); i++) {
        const TaskDescriptor& task_desc = job_desc.pod().tasks(i);
        LOG(INFO, "job[%s]:task[%d] descriptor: "
            "start_cmd: \"%s\", stop_cmd: \"%s\", binary_size:%d, mem:%ld, cpu:%d ",
            job_desc.name().c_str(),
            i,
            task_desc.start_command().c_str(),
            task_desc.stop_command().c_str(),
            task_desc.binary().size(),
            task_desc.requirement().memory(),
            task_desc.requirement().millicores()
        );
    }
}

void MasterUtil::SetDiff(const std::set<std::string>& left_set,
                         const std::set<std::string>& right_set,
                         std::set<std::string>* left_diff,
                         std::set<std::string>* right_diff) {
    if (left_diff == NULL || right_diff == NULL) {
        LOG(WARNING, "set diff error for input NULL");
        return;
    }

    if (left_set.size() == 0) {
        *right_diff = right_set;
        return;
    }

    if (right_set.size() == 0) {
        *left_diff = left_set;
        return;
    }
    std::set<std::string>::iterator it_left = left_set.begin();
    std::set<std::string>::iterator it_right = right_set.begin();
    while (it_left != left_set.end()
            && it_right != right_set.end()) {
        if (*it_left == *it_right) {
            ++it_left;
            ++it_right;
        } else if (*it_left > *it_right) {
            right_diff->insert(*it_right);
            ++it_right;
        } else {
            left_diff->insert(*it_left);
            ++it_left;
        }
    }

    for (; it_left != left_set.end(); ++it_left) {
        left_diff->insert(*it_left);
    }
    for (; it_right != right_set.end(); ++it_right) {
        right_diff->insert(*it_right);
    }
    return;
}

void MasterUtil::ResetLabels(AgentInfo* agent,
                             const std::set<std::string>& labels) {
    if (agent == NULL) {
        return;
    }

    agent->clear_tags();
    std::set<std::string>::iterator it = labels.begin();
    for (; it != labels.end(); ++it) {
        agent->add_tags(*it);
    }
    return;
}

}
}
<commit_msg>update uuid generator<commit_after>// Copyright (c) 2015, Baidu.com, 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 "master_util.h"

#include <sstream>
#include <sys/utsname.h>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/uuid_generators.hpp>
#include <boost/uuid/uuid_io.hpp>
#include <boost/lexical_cast.hpp>
#include <gflags/gflags.h>
#include <logging.h>

#include "proto/galaxy.pb.h"
#include "proto/master.pb.h"

DECLARE_string(master_port);

namespace baidu {
namespace galaxy {
static boost::uuids::random_generator gen;
std::string MasterUtil::UUID() {
    boost::uuids::uuid uuid = gen();
    return boost::lexical_cast<std::string>(uuid);
}

void MasterUtil::AddResource(const Resource& from, Resource* to) {
    to->set_millicores(to->millicores() + from.millicores());
    to->set_memory(to->memory() + from.memory());
}

void MasterUtil::SubstractResource(const Resource& from, Resource* to) {
    assert(FitResource(from, *to));
    to->set_millicores(to->millicores() - from.millicores());
    to->set_memory(to->memory() - from.memory());
}

bool MasterUtil::FitResource(const Resource& from, const Resource& to) {
    if (to.millicores() < from.millicores()) {
        return false;
    }
    if (to.memory() < from.memory()) {
        return false;
    }
    // TODO: check port & disk & ssd
    return true;
}

std::string MasterUtil::SelfEndpoint() {
    std::string hostname = "";
    struct utsname buf;
    if (0 != uname(&buf)) {
        *buf.nodename = '\0';
    }
    hostname = buf.nodename;
    return hostname + ":" + FLAGS_master_port;
}

void MasterUtil::TraceJobDesc(const JobDescriptor& job_desc) {
    LOG(INFO, "job descriptor: \"%s\", "
              "replica:%d, "
              "deploy_step:%d",
              job_desc.name().c_str(),
              job_desc.replica(),
              job_desc.deploy_step()
    );
    LOG(INFO, "pod descriptor mem:%ld, cpu:%d, port_size:%d",
       job_desc.pod().requirement().memory(),
       job_desc.pod().requirement().millicores(),
       job_desc.pod().requirement().ports_size());
    for (int i = 0; i < job_desc.pod().tasks_size(); i++) {
        const TaskDescriptor& task_desc = job_desc.pod().tasks(i);
        LOG(INFO, "job[%s]:task[%d] descriptor: "
            "start_cmd: \"%s\", stop_cmd: \"%s\", binary_size:%d, mem:%ld, cpu:%d ",
            job_desc.name().c_str(),
            i,
            task_desc.start_command().c_str(),
            task_desc.stop_command().c_str(),
            task_desc.binary().size(),
            task_desc.requirement().memory(),
            task_desc.requirement().millicores()
        );
    }
}

void MasterUtil::SetDiff(const std::set<std::string>& left_set,
                         const std::set<std::string>& right_set,
                         std::set<std::string>* left_diff,
                         std::set<std::string>* right_diff) {
    if (left_diff == NULL || right_diff == NULL) {
        LOG(WARNING, "set diff error for input NULL");
        return;
    }

    if (left_set.size() == 0) {
        *right_diff = right_set;
        return;
    }

    if (right_set.size() == 0) {
        *left_diff = left_set;
        return;
    }
    std::set<std::string>::iterator it_left = left_set.begin();
    std::set<std::string>::iterator it_right = right_set.begin();
    while (it_left != left_set.end()
            && it_right != right_set.end()) {
        if (*it_left == *it_right) {
            ++it_left;
            ++it_right;
        } else if (*it_left > *it_right) {
            right_diff->insert(*it_right);
            ++it_right;
        } else {
            left_diff->insert(*it_left);
            ++it_left;
        }
    }

    for (; it_left != left_set.end(); ++it_left) {
        left_diff->insert(*it_left);
    }
    for (; it_right != right_set.end(); ++it_right) {
        right_diff->insert(*it_right);
    }
    return;
}

void MasterUtil::ResetLabels(AgentInfo* agent,
                             const std::set<std::string>& labels) {
    if (agent == NULL) {
        return;
    }

    agent->clear_tags();
    std::set<std::string>::iterator it = labels.begin();
    for (; it != labels.end(); ++it) {
        agent->add_tags(*it);
    }
    return;
}

}
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "global.h"

GlobalDBItem				globalDBItems[] = {
	{ "_gravity",			"-9.8",				false, StateDatabase::Locked},
	{ "_worldSize",			"800.0",			false, StateDatabase::Locked},
	{ "_tankLength",		"6.0",				false, StateDatabase::Locked},
	{ "_tankWidth",			"2.8",				false, StateDatabase::Locked},
	{ "_tankHeight",		"2.05",				false, StateDatabase::Locked},
	{ "_tankRadius",		"0.72 * _tankLength",		false, StateDatabase::Locked},
	{ "_muzzleHeight",		"1.57",				false, StateDatabase::Locked},
	{ "_muzzleFront",		"_tankRadius + 0.1",		false, StateDatabase::Locked},
	{ "_tankSpeed",			"25.0",				false, StateDatabase::Locked},
	{ "_tankAngVel",		"0.785398", 			false, StateDatabase::Locked},
	{ "_shotSpeed",			"100.0",			false, StateDatabase::Locked},
	{ "_shotRange",			"350.0",			false, StateDatabase::Locked},
	{ "_reloadTime",		"_shotRange / _shotSpeed",	false, StateDatabase::Locked},
	{ "_explodeTime",		"5.0",				false, StateDatabase::Locked},
	{ "_teleportTime",		"1.0",				false, StateDatabase::Locked},
	{ "_flagAltitude",		"11.0",				false, StateDatabase::Locked},
	{ "_flagRadius",		"2.5",				false, StateDatabase::Locked},
	{ "_velocityAd",		"1.5",				false, StateDatabase::Locked},
	{ "_angularAd",			"1.5",				false, StateDatabase::Locked},
	{ "_rFireAdVel",		"1.5",				false, StateDatabase::Locked},
	{ "_rFireAdRate",		"2.0",				false, StateDatabase::Locked},
	{ "_rFireAdLife",		"1.0 / _rFireAdRate",		false, StateDatabase::Locked},
	{ "_mGunAdVel",			"1.5",				false, StateDatabase::Locked},
	{ "_mGunAdRate",		"10.0",				false, StateDatabase::Locked},
	{ "_mGunAdLife",		"1.0 / _mGunAdRate",		false, StateDatabase::Locked},
	{ "_laserAdVel",		"1000.0",			false, StateDatabase::Locked},
	{ "_laserAdRate",		"0.5",				false, StateDatabase::Locked},
	{ "_laserAdLife",		"0.1",				false, StateDatabase::Locked},
	{ "_gMissileAng",		"0.628319", 			false, StateDatabase::Locked},
	{ "_tinyFactor",		"0.4",				false, StateDatabase::Locked},
	{ "_shieldFlight",		"2.7",				false, StateDatabase::Locked},
	{ "_srRadiusMult",		"2.0",				false, StateDatabase::Locked},
	{ "_shockAdLife",		"0.2",				false, StateDatabase::Locked},
	{ "_shockInRadius",		"_tankLength",			false, StateDatabase::Locked},
	{ "_shockOutRadius",		"60.0",				false, StateDatabase::Locked},
	{ "_jumpVelocity",		"19.0",				false, StateDatabase::Locked},
	{ "_identifyRange",		"50.0",				false, StateDatabase::Locked},
	{ "_obeseFactor",		"2.5",				false, StateDatabase::Locked},
	{ "_wideAngleAng",		"1.745329", 			false, StateDatabase::Locked},
	{ "_thiefVelAd",		"1.67",				false, StateDatabase::Locked},
	{ "_thiefTinyFactor",		"0.5",				false, StateDatabase::Locked},
	{ "_thiefAdShotVel",		"10.0",				false, StateDatabase::Locked},
	{ "_thiefAdLife",               "0.05",				false, StateDatabase::Locked},
	{ "_thiefAdRate",		"10.0",				false, StateDatabase::Locked},
	{ "_momentumLinAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_momentumAngAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_burrowDepth",		"-1.32",			false, StateDatabase::Locked},
	{ "_burrowSpeedAd",		"0.75",				false, StateDatabase::Locked},
	{ "_burrowAngularAd",		"0.33",				false, StateDatabase::Locked},
	{ "_lRAdRate",			"0.5",				false, StateDatabase::Locked},
	{ "_lockOnAngle",		"0.15",				false, StateDatabase::Locked},
	{ "_targetingAngle",		"0.3",				false, StateDatabase::Locked},
	{ "_flagHeight",                "10.0",                         false, StateDatabase::Locked},
	{ "_wallHeight",		"3.0*_tankHeight",              false, StateDatabase::Locked},
	{ "_boxHeight",			"6.0*_muzzleHeight",		false, StateDatabase::Locked},
	{ "_pyrBase",			"4.0*_tankHeight",		false, StateDatabase::Locked},
	{ "_pyrHeight",                 "5.0*_tankHeight",		false, StateDatabase::Locked},
};
<commit_msg>thief should shoot a lil shorter, with faster reload<commit_after>/* bzflag
 * Copyright (c) 1993 - 2003 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named LICENSE that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

#include "global.h"

GlobalDBItem				globalDBItems[] = {
	{ "_gravity",			"-9.8",				false, StateDatabase::Locked},
	{ "_worldSize",			"800.0",			false, StateDatabase::Locked},
	{ "_tankLength",		"6.0",				false, StateDatabase::Locked},
	{ "_tankWidth",			"2.8",				false, StateDatabase::Locked},
	{ "_tankHeight",		"2.05",				false, StateDatabase::Locked},
	{ "_tankRadius",		"0.72 * _tankLength",		false, StateDatabase::Locked},
	{ "_muzzleHeight",		"1.57",				false, StateDatabase::Locked},
	{ "_muzzleFront",		"_tankRadius + 0.1",		false, StateDatabase::Locked},
	{ "_tankSpeed",			"25.0",				false, StateDatabase::Locked},
	{ "_tankAngVel",		"0.785398", 			false, StateDatabase::Locked},
	{ "_shotSpeed",			"100.0",			false, StateDatabase::Locked},
	{ "_shotRange",			"350.0",			false, StateDatabase::Locked},
	{ "_reloadTime",		"_shotRange / _shotSpeed",	false, StateDatabase::Locked},
	{ "_explodeTime",		"5.0",				false, StateDatabase::Locked},
	{ "_teleportTime",		"1.0",				false, StateDatabase::Locked},
	{ "_flagAltitude",		"11.0",				false, StateDatabase::Locked},
	{ "_flagRadius",		"2.5",				false, StateDatabase::Locked},
	{ "_velocityAd",		"1.5",				false, StateDatabase::Locked},
	{ "_angularAd",			"1.5",				false, StateDatabase::Locked},
	{ "_rFireAdVel",		"1.5",				false, StateDatabase::Locked},
	{ "_rFireAdRate",		"2.0",				false, StateDatabase::Locked},
	{ "_rFireAdLife",		"1.0 / _rFireAdRate",		false, StateDatabase::Locked},
	{ "_mGunAdVel",			"1.5",				false, StateDatabase::Locked},
	{ "_mGunAdRate",		"10.0",				false, StateDatabase::Locked},
	{ "_mGunAdLife",		"1.0 / _mGunAdRate",		false, StateDatabase::Locked},
	{ "_laserAdVel",		"1000.0",			false, StateDatabase::Locked},
	{ "_laserAdRate",		"0.5",				false, StateDatabase::Locked},
	{ "_laserAdLife",		"0.1",				false, StateDatabase::Locked},
	{ "_gMissileAng",		"0.628319", 			false, StateDatabase::Locked},
	{ "_tinyFactor",		"0.4",				false, StateDatabase::Locked},
	{ "_shieldFlight",		"2.7",				false, StateDatabase::Locked},
	{ "_srRadiusMult",		"2.0",				false, StateDatabase::Locked},
	{ "_shockAdLife",		"0.2",				false, StateDatabase::Locked},
	{ "_shockInRadius",		"_tankLength",			false, StateDatabase::Locked},
	{ "_shockOutRadius",		"60.0",				false, StateDatabase::Locked},
	{ "_jumpVelocity",		"19.0",				false, StateDatabase::Locked},
	{ "_identifyRange",		"50.0",				false, StateDatabase::Locked},
	{ "_obeseFactor",		"2.5",				false, StateDatabase::Locked},
	{ "_wideAngleAng",		"1.745329", 			false, StateDatabase::Locked},
	{ "_thiefVelAd",		"1.67",				false, StateDatabase::Locked},
	{ "_thiefTinyFactor",		"0.5",				false, StateDatabase::Locked},
	{ "_thiefAdShotVel",		"8.0",				false, StateDatabase::Locked},
	{ "_thiefAdLife",               "0.05",				false, StateDatabase::Locked},
	{ "_thiefAdRate",		"12.0",				false, StateDatabase::Locked},
	{ "_momentumLinAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_momentumAngAcc",		"1.0",				false, StateDatabase::Locked},
	{ "_burrowDepth",		"-1.32",			false, StateDatabase::Locked},
	{ "_burrowSpeedAd",		"0.75",				false, StateDatabase::Locked},
	{ "_burrowAngularAd",		"0.33",				false, StateDatabase::Locked},
	{ "_lRAdRate",			"0.5",				false, StateDatabase::Locked},
	{ "_lockOnAngle",		"0.15",				false, StateDatabase::Locked},
	{ "_targetingAngle",		"0.3",				false, StateDatabase::Locked},
	{ "_flagHeight",                "10.0",                         false, StateDatabase::Locked},
	{ "_wallHeight",		"3.0*_tankHeight",              false, StateDatabase::Locked},
	{ "_boxHeight",			"6.0*_muzzleHeight",		false, StateDatabase::Locked},
	{ "_pyrBase",			"4.0*_tankHeight",		false, StateDatabase::Locked},
	{ "_pyrHeight",                 "5.0*_tankHeight",		false, StateDatabase::Locked},
};
<|endoftext|>


<commit_before>// Copyright (c) 2019 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#ifndef OVK_CORE_ARRAY_OPS_HPP_INCLUDED
#define OVK_CORE_ARRAY_OPS_HPP_INCLUDED

#include <ovk/core/ArrayTraits.hpp>
#include <ovk/core/ArrayView.hpp>
#include <ovk/core/Global.hpp>
#include <ovk/core/IteratorTraits.hpp>
#include <ovk/core/Requires.hpp>

#include <type_traits>
#include <utility>

namespace ovk {

template <typename T, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(!std::is_const<T>::value
  )> void ArrayFill(const array_view<T, Rank, Layout> &View, const T &Value) {

  View.Fill(Value);

}

template <typename ArrayType, OVK_FUNCTION_REQUIRES(core::IsArray<ArrayType>())> void ArrayFill(
  ArrayType &Array, const core::array_value_type<ArrayType> &Value) {

  long long NumValues = core::ArrayCount(Array);

  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = Value;
  }

}

template <typename T, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(!std::is_const<T>::value
  )> void ArrayFill(const array_view<T, Rank, Layout> &View, std::initializer_list<T> ValuesList) {

  View.Fill(ValuesList);

}

template <typename ArrayType, OVK_FUNCTION_REQUIRES(core::IsArray<ArrayType>())> void ArrayFill(
  ArrayType &Array, std::initializer_list<core::array_value_type<ArrayType>> ValuesList) {

  long long NumValues = core::ArrayCount(Array);

  auto Iter = ValuesList.begin();
  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = *Iter++;
  }

}

template <typename T, int Rank, array_layout Layout, typename IterType, OVK_FUNCTION_REQUIRES(
  !std::is_const<T>::value && core::IsInputIterator<IterType>() && std::is_convertible<
  core::iterator_reference_type<IterType>, T>::value)> void ArrayFill(const array_view<T, Rank,
  Layout> &View, IterType First) {

  View.Fill(First);

}

template <typename ArrayType, typename IterType, OVK_FUNCTION_REQUIRES(core::IsArray<ArrayType>() &&
  core::IsInputIterator<IterType>() && std::is_convertible<core::iterator_reference_type<IterType>,
  core::array_value_type<ArrayType>>::value)> void ArrayFill(ArrayType &Array, IterType First) {

  long long NumValues = core::ArrayCount(Array);

  IterType Iter = First;
  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = *Iter++;
  }

}

template <typename T, typename U, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(
  !std::is_const<T>::value && std::is_convertible<typename std::remove_const<U>::type, T>::value)>
  void ArrayFill(const array_view<T, Rank, Layout> &View, const array_view<U, Rank, Layout>
  &SourceView) {

  View.Fill(SourceView);

}

template <typename ArrayType, typename T, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(
  core::IsArray<ArrayType>() && core::ArrayHasFootprint<ArrayType, Rank, Layout>() &&
  std::is_convertible<typename std::remove_const<T>::type, core::array_value_type<ArrayType>>::
  value)> void ArrayFill(ArrayType &Array, const array_view<T, Rank, Layout> &SourceView) {

  long long NumValues = core::ArrayCount(Array);

  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = SourceView[i];
  }

}

template <typename T, int Rank, array_layout Layout, typename SourceArrayRefType,
  OVK_FUNCTION_REQUIRES(!std::is_const<T>::value && core::IsArray<core::remove_cvref<
  SourceArrayRefType>>() && !core::IsIterator<typename std::decay<SourceArrayRefType>::type>()
  && core::ArrayHasFootprint<core::remove_cvref<SourceArrayRefType>, Rank, Layout>() &&
  std::is_convertible<core::array_access_type<SourceArrayRefType &&>, T>::value)> void ArrayFill(
  const array_view<T, Rank, Layout> &View, SourceArrayRefType &&SourceArray) {

  View.Fill(std::forward<SourceArrayRefType>(SourceArray));

}

template <typename ArrayType, typename SourceArrayRefType, OVK_FUNCTION_REQUIRES(core::IsArray<
  ArrayType>() && core::IsArray<core::remove_cvref<SourceArrayRefType>>() && !core::IsIterator<
  typename std::decay<SourceArrayRefType>::type>() && core::ArraysAreSimilar<ArrayType,
  core::remove_cvref<SourceArrayRefType>>() && std::is_convertible<core::array_access_type<
  SourceArrayRefType &&>, core::array_value_type<ArrayType>>::value)> void ArrayFill(ArrayType
  &Array, SourceArrayRefType &&SourceArray) {

  long long NumValues = core::ArrayCount(Array);

  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = static_cast<core::array_access_type<SourceArrayRefType &&>>(SourceArray[i]);
  }

}

}

#endif
<commit_msg>cosmetic change<commit_after>// Copyright (c) 2019 Matthew J. Smith and Overkit contributors
// License: MIT (http://opensource.org/licenses/MIT)

#ifndef OVK_CORE_ARRAY_OPS_HPP_INCLUDED
#define OVK_CORE_ARRAY_OPS_HPP_INCLUDED

#include <ovk/core/ArrayTraits.hpp>
#include <ovk/core/ArrayView.hpp>
#include <ovk/core/Global.hpp>
#include <ovk/core/IteratorTraits.hpp>
#include <ovk/core/Requires.hpp>

#include <type_traits>
#include <utility>

namespace ovk {

template <typename ArrayType, OVK_FUNCTION_REQUIRES(core::IsArray<ArrayType>())> void ArrayFill(
  ArrayType &Array, const core::array_value_type<ArrayType> &Value) {

  long long NumValues = core::ArrayCount(Array);

  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = Value;
  }

}

template <typename T, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(!std::is_const<T>::value
  )> void ArrayFill(const array_view<T, Rank, Layout> &View, const T &Value) {

  View.Fill(Value);

}

template <typename ArrayType, OVK_FUNCTION_REQUIRES(core::IsArray<ArrayType>())> void ArrayFill(
  ArrayType &Array, std::initializer_list<core::array_value_type<ArrayType>> ValuesList) {

  long long NumValues = core::ArrayCount(Array);

  auto Iter = ValuesList.begin();
  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = *Iter++;
  }

}

template <typename T, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(!std::is_const<T>::value
  )> void ArrayFill(const array_view<T, Rank, Layout> &View, std::initializer_list<T> ValuesList) {

  View.Fill(ValuesList);

}

template <typename ArrayType, typename IterType, OVK_FUNCTION_REQUIRES(core::IsArray<ArrayType>() &&
  core::IsInputIterator<IterType>() && std::is_convertible<core::iterator_reference_type<IterType>,
  core::array_value_type<ArrayType>>::value)> void ArrayFill(ArrayType &Array, IterType First) {

  long long NumValues = core::ArrayCount(Array);

  IterType Iter = First;
  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = *Iter++;
  }

}

template <typename T, int Rank, array_layout Layout, typename IterType, OVK_FUNCTION_REQUIRES(
  !std::is_const<T>::value && core::IsInputIterator<IterType>() && std::is_convertible<
  core::iterator_reference_type<IterType>, T>::value)> void ArrayFill(const array_view<T, Rank,
  Layout> &View, IterType First) {

  View.Fill(First);

}

template <typename ArrayType, typename T, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(
  core::IsArray<ArrayType>() && core::ArrayHasFootprint<ArrayType, Rank, Layout>() &&
  std::is_convertible<typename std::remove_const<T>::type, core::array_value_type<ArrayType>>::
  value)> void ArrayFill(ArrayType &Array, const array_view<T, Rank, Layout> &SourceView) {

  long long NumValues = core::ArrayCount(Array);

  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = SourceView[i];
  }

}

template <typename T, typename U, int Rank, array_layout Layout, OVK_FUNCTION_REQUIRES(
  !std::is_const<T>::value && std::is_convertible<typename std::remove_const<U>::type, T>::value)>
  void ArrayFill(const array_view<T, Rank, Layout> &View, const array_view<U, Rank, Layout>
  &SourceView) {

  View.Fill(SourceView);

}

template <typename ArrayType, typename SourceArrayRefType, OVK_FUNCTION_REQUIRES(core::IsArray<
  ArrayType>() && core::IsArray<core::remove_cvref<SourceArrayRefType>>() && !core::IsIterator<
  typename std::decay<SourceArrayRefType>::type>() && core::ArraysAreSimilar<ArrayType,
  core::remove_cvref<SourceArrayRefType>>() && std::is_convertible<core::array_access_type<
  SourceArrayRefType &&>, core::array_value_type<ArrayType>>::value)> void ArrayFill(ArrayType
  &Array, SourceArrayRefType &&SourceArray) {

  long long NumValues = core::ArrayCount(Array);

  for (long long i = 0; i < NumValues; ++i) {
    Array[i] = static_cast<core::array_access_type<SourceArrayRefType &&>>(SourceArray[i]);
  }

}

template <typename T, int Rank, array_layout Layout, typename SourceArrayRefType,
  OVK_FUNCTION_REQUIRES(!std::is_const<T>::value && core::IsArray<core::remove_cvref<
  SourceArrayRefType>>() && !core::IsIterator<typename std::decay<SourceArrayRefType>::type>()
  && core::ArrayHasFootprint<core::remove_cvref<SourceArrayRefType>, Rank, Layout>() &&
  std::is_convertible<core::array_access_type<SourceArrayRefType &&>, T>::value)> void ArrayFill(
  const array_view<T, Rank, Layout> &View, SourceArrayRefType &&SourceArray) {

  View.Fill(std::forward<SourceArrayRefType>(SourceArray));

}

}

#endif
<|endoftext|>


<commit_before>#ifndef Q_MOC_RUN
#ifndef MUMBLE_MUMBLE_MUMBLE_PCH_H_
#define MUMBLE_MUMBLE_MUMBLE_PCH_H_

#define QT_NO_CAST_TO_ASCII
#define QT_NO_CAST_FROM_ASCII
#define QT_USE_FAST_CONCATENATION
#define QT_USE_FAST_OPERATOR_PLUS

#define NOMINMAX
#define _WINSOCKAPI_

#define BOOST_TYPEOF_SUPPRESS_UNNAMED_NAMESPACE

#ifdef __APPLE__
#include <Carbon/Carbon.h>
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
#undef nil
#undef check
#undef TYPE_BOOL
#endif

#include <QtCore/QtCore>
#include <QtGui/QtGui>
#if QT_VERSION >= 0x050000
# include "Qt4Compat.h"
# include <QtWidgets/QtWidgets>
#endif

#include <QtSvg/QtSvg>
#ifdef USE_DBUS
#include <QtDBus/QtDBus>
#endif
#include <QtNetwork/QtNetwork>
#include <QtSql/QtSql>
#include <QtXml/QtXml>

#ifdef Q_OS_WIN
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
#endif
#include <sndfile.h>
#include <celt.h>
#ifdef USE_SBCELT
#include <sbcelt.h>
#endif
#include <speex/speex.h>
#include <speex/speex_jitter.h>
#include <speex/speex_preprocess.h>
#include <speex/speex_echo.h>
#include <speex/speex_resampler.h>

#include <boost/array.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/accumulators/statistics/extended_p_square.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/weak_ptr.hpp>

#include <algorithm>

#ifdef Q_OS_WIN
// Qt 5's qnetworksession.h undefs 'interface' (as defined in ObjBase.h on Windows).
// This causes Windows headers that use COM interfaces to break. Internally, it's
// just defined as 'struct', so we'll do that here as well to make things work again
// without too much hassle.
#ifndef interface
#define interface struct
#endif

#include <windows.h>
#include <shellapi.h>
#include <winsock2.h>
#include <qos2.h>
#include <wintrust.h>
#include <Softpub.h>
#include <Dbt.h>
#include <delayimp.h>
#include <shlobj.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <math.h>

#define STACKVAR(type, varname, count) type *varname=reinterpret_cast<type *>(_alloca(sizeof(type) * (count)))

#else // ifndef Q_OS_WIN
#include <math.h>
#define STACKVAR(type, varname, count) type varname[count]
#define CopyMemory(dst,ptr,len) memcpy(dst,ptr,len)
#define ZeroMemory(ptr,len) memset(ptr, 0, len)
#define __cdecl
typedef WId HWND;
#include <arpa/inet.h>
#endif

#if defined(__MMX__) || defined(Q_OS_WIN)
#include <mmintrin.h>
#endif

#define iroundf(x) ( static_cast<int>(x) )

#ifdef USE_BONJOUR
#include <dns_sd.h>
#endif

#ifdef __OBJC__
 #define nil 0
#endif

#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include <openssl/pkcs12.h>
#include <openssl/ssl.h>
/* OpenSSL defines set_key. This breaks our protobuf-generated setters. */
#undef set_key

#endif
#endif
<commit_msg>mumble_pch.hpp: add missing networking headers to fix FreeBSD build.<commit_after>#ifndef Q_MOC_RUN
#ifndef MUMBLE_MUMBLE_MUMBLE_PCH_H_
#define MUMBLE_MUMBLE_MUMBLE_PCH_H_

#define QT_NO_CAST_TO_ASCII
#define QT_NO_CAST_FROM_ASCII
#define QT_USE_FAST_CONCATENATION
#define QT_USE_FAST_OPERATOR_PLUS

#define NOMINMAX
#define _WINSOCKAPI_

#define BOOST_TYPEOF_SUPPRESS_UNNAMED_NAMESPACE

#ifdef __APPLE__
#include <Carbon/Carbon.h>
#include <CoreFoundation/CoreFoundation.h>
#include <ApplicationServices/ApplicationServices.h>
#undef nil
#undef check
#undef TYPE_BOOL
#endif

#include <QtCore/QtCore>
#include <QtGui/QtGui>
#if QT_VERSION >= 0x050000
# include "Qt4Compat.h"
# include <QtWidgets/QtWidgets>
#endif

#include <QtSvg/QtSvg>
#ifdef USE_DBUS
#include <QtDBus/QtDBus>
#endif
#include <QtNetwork/QtNetwork>
#include <QtSql/QtSql>
#include <QtXml/QtXml>

#ifdef Q_OS_WIN
#define ENABLE_SNDFILE_WINDOWS_PROTOTYPES 1
#endif
#include <sndfile.h>
#include <celt.h>
#ifdef USE_SBCELT
#include <sbcelt.h>
#endif
#include <speex/speex.h>
#include <speex/speex_jitter.h>
#include <speex/speex_preprocess.h>
#include <speex/speex_echo.h>
#include <speex/speex_resampler.h>

#include <boost/array.hpp>
#include <boost/accumulators/accumulators.hpp>
#include <boost/accumulators/statistics/stats.hpp>
#include <boost/accumulators/statistics/mean.hpp>
#include <boost/accumulators/statistics/variance.hpp>
#include <boost/accumulators/statistics/extended_p_square.hpp>
#include <boost/bind.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/make_shared.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/shared_array.hpp>
#include <boost/scoped_ptr.hpp>
#include <boost/scoped_array.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/weak_ptr.hpp>

#include <algorithm>

#ifdef Q_OS_WIN
// Qt 5's qnetworksession.h undefs 'interface' (as defined in ObjBase.h on Windows).
// This causes Windows headers that use COM interfaces to break. Internally, it's
// just defined as 'struct', so we'll do that here as well to make things work again
// without too much hassle.
#ifndef interface
#define interface struct
#endif

#include <windows.h>
#include <shellapi.h>
#include <winsock2.h>
#include <qos2.h>
#include <wintrust.h>
#include <Softpub.h>
#include <Dbt.h>
#include <delayimp.h>
#include <shlobj.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <math.h>

#define STACKVAR(type, varname, count) type *varname=reinterpret_cast<type *>(_alloca(sizeof(type) * (count)))

#else // ifndef Q_OS_WIN
#include <math.h>
#define STACKVAR(type, varname, count) type varname[count]
#define CopyMemory(dst,ptr,len) memcpy(dst,ptr,len)
#define ZeroMemory(ptr,len) memset(ptr, 0, len)
#define __cdecl
typedef WId HWND;
#include <sys/socket.h>
#include <sys/types.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#endif

#if defined(__MMX__) || defined(Q_OS_WIN)
#include <mmintrin.h>
#endif

#define iroundf(x) ( static_cast<int>(x) )

#ifdef USE_BONJOUR
#include <dns_sd.h>
#endif

#ifdef __OBJC__
 #define nil 0
#endif

#include <openssl/aes.h>
#include <openssl/rand.h>
#include <openssl/pem.h>
#include <openssl/conf.h>
#include <openssl/x509v3.h>
#include <openssl/pkcs12.h>
#include <openssl/ssl.h>
/* OpenSSL defines set_key. This breaks our protobuf-generated setters. */
#undef set_key

#endif
#endif
<|endoftext|>


<commit_before>#include <algorithm>
#include <stdexcept>
#include <chrono>
#include <vector>
#include <memory>
#include <cmath>
#include <thread>
#include <signal.h>
#include <sched.h>
#include <sys/mman.h>

#include <eeros/core/Executor.hpp>
#include <eeros/task/Async.hpp>
#include <eeros/task/Lambda.hpp>
#include <eeros/task/HarmonicTaskList.hpp>
#include <eeros/control/TimeDomain.hpp>
#include <eeros/safety/SafetySystem.hpp>
#include <ros/callback_queue_interface.h>
#include <ros/callback_queue.h>

volatile bool running = true;

using namespace eeros;

namespace {

	using Logger = logger::Logger;

	struct TaskThread {
		TaskThread(double period, task::Periodic &task, task::HarmonicTaskList tasks) :
			taskList(tasks), async(taskList, task.getRealtime(), task.getNice())
		{
			async.counter.setPeriod(period);
			async.counter.monitors = task.monitors;
		}
		task::HarmonicTaskList taskList;
		task::Async async;
	};

	template < typename F >
	void traverse(std::vector<task::Periodic> &tasks, F func) {
		for (auto &t: tasks) {
			func(&t);
			traverse(t.before, func);
			traverse(t.after, func);
		}
	}

 	void createThread(Logger &log, task::Periodic &task, task::Periodic &baseTask, std::vector<std::shared_ptr<TaskThread>> &threads, std::vector<task::Harmonic> &output);

	void createThreads(Logger &log, std::vector<task::Periodic> &tasks, task::Periodic &baseTask, std::vector<std::shared_ptr<TaskThread>> &threads, task::HarmonicTaskList &output) {
		for (task::Periodic &t: tasks) {
			createThread(log, t, baseTask, threads, output.tasks);
		}
	}

	void createThread(Logger &log, task::Periodic &task, task::Periodic &baseTask, std::vector<std::shared_ptr<TaskThread>> &threads, std::vector<task::Harmonic> &output) {
		int k = static_cast<int>(task.getPeriod() / baseTask.getPeriod());
		double actualPeriod = k * baseTask.getPeriod();
		double deviation = std::abs(task.getPeriod() - actualPeriod) / task.getPeriod();
		task::HarmonicTaskList taskList;

		if (task.before.size() > 0) {
			createThreads(log, task.before, task, threads, taskList);
		}
		taskList.add(task.getTask());
		if (task.after.size() > 0) {
			createThreads(log, task.after, task, threads, taskList);
		}

		if (task.getRealtime())
			log.trace() << "creating harmonic realtime task '" << task.getName()
						<< "' with period " << actualPeriod << " sec (k = "
						<< k << ") and priority " << (Executor::basePriority - task.getNice())
						<< " based on '" << baseTask.getName() << "'";
		else
			log.trace() << "creating harmonic task '" << task.getName() << "' with period "
						<< actualPeriod << " sec (k = " << k << ")"
						<< " based on '" << baseTask.getName() << "'";

		if (deviation > 0.01) throw std::runtime_error("period deviation too high");

		if (task.getRealtime() && task.getNice() <= 0)
			throw std::runtime_error("priority not set");

		if (taskList.tasks.size() == 0)
			throw std::runtime_error("no task to execute");

		threads.push_back(std::make_shared<TaskThread>(actualPeriod, task, taskList));
		output.emplace_back(threads.back()->async, k);
	}
}

Executor::Executor() :
	log('E'), period(0), mainTask(nullptr), useRosTime(false), syncWithGazeboIsSet(false) { }

Executor::~Executor() {

}

Executor& Executor::instance() {
	static Executor executor;
	return executor;
}

#ifdef ECMASTERLIB_FOUND
void Executor::syncWithEtherCATSTack(ethercat::EtherCATMain* etherCATStack) {
	this->etherCATStack = etherCATStack;
	cv = etherCATStack->getConditionalVariable();
	m = etherCATStack->getMutex();
}
#endif

void Executor::setMainTask(task::Periodic &mainTask) {
	if (this->mainTask != nullptr)
		throw std::runtime_error("you can only define one main task per executor");
	period = mainTask.getPeriod();
	counter.setPeriod(period);
	this->mainTask = &mainTask;
}

void Executor::setMainTask(safety::SafetySystem &ss) {
	task::Periodic *task = new task::Periodic("safety system", ss.getPeriod(), ss, true);
	setMainTask(*task);
}

void Executor::add(task::Periodic &task) {
	tasks.push_back(task);
}

void Executor::add(control::TimeDomain &timedomain) {
	task::Periodic task(timedomain.getName().c_str(), timedomain.getPeriod(), timedomain, timedomain.getRealtime());
	tasks.push_back(task);
}

void Executor::prefault_stack() {
	unsigned char dummy[8*1024] = {};
}

bool Executor::lock_memory() {
	return (mlockall(MCL_CURRENT | MCL_FUTURE) != -1);
}

bool Executor::set_priority(int nice) {
	struct sched_param schedulingParam;
	schedulingParam.sched_priority = (Executor::basePriority - nice);
	return (sched_setscheduler(0, SCHED_FIFO, &schedulingParam) != -1);
}

void Executor::stop() {
	running = false;
	auto &instance = Executor::instance();
#ifdef ECMASTERLIB_FOUND
	if(instance.etherCATStack) instance.cv->notify_one();
#endif
}

void Executor::useRosTimeForExecutor() {
	useRosTime = true;
}

void Executor::syncWithGazebo(ros::CallbackQueue* syncRosCallbackQueue)
{
	std::cout << "sync executor with gazebo" << std::endl;
	syncWithGazeboIsSet = true;
	this->syncRosCallbackQueue = syncRosCallbackQueue;
}

void Executor::assignPriorities() {
	std::vector<task::Periodic*> priorityAssignments;

	// add task to list of priority assignments
	traverse(tasks, [&priorityAssignments] (task::Periodic *task) {
		priorityAssignments.push_back(task);
	});

	// sort list of priority assignments
	std::sort(priorityAssignments.begin(), priorityAssignments.end(), [] (task::Periodic *a, task::Periodic *b) -> bool {
		if (a->getRealtime() == b->getRealtime())
			return (a->getPeriod() < b->getPeriod());
		else
			return a->getRealtime();
	});

	// assign priorities
	int nice = 1;
	for (auto t: priorityAssignments) {
		if (t->getRealtime()) {
			t->setNice(nice++);
		}
	}
}

void Executor::run() {
	log.trace() << "starting executor with base period " << period << " sec and priority " << basePriority;

	if (period == 0.0)
		throw std::runtime_error("period of executor not set");

	log.trace() << "assigning priorities";
	assignPriorities();

	Runnable *mainTask = nullptr;

	if (this->mainTask != nullptr) {
		mainTask = &this->mainTask->getTask();
		log.trace() << "setting '" << this->mainTask->getName() << "' as main task";
	}

	std::vector<std::shared_ptr<TaskThread>> threads; // smart pointer used because async objects must not be copied
	task::HarmonicTaskList taskList;
	task::Periodic executorTask("executor", period, this, true);

	counter.monitors = this->mainTask->monitors;

	createThreads(log, tasks, executorTask, threads, taskList);

	using seconds = std::chrono::duration<double, std::chrono::seconds::period>;

	// TODO: implement this with ready-flag (wait for all threads to be ready instead of blind sleep)
	std::this_thread::sleep_for(seconds(1)); // wait 1 sec to allow threads to be created

	if (!set_priority(0))
		log.error() << "could not set realtime priority";

	prefault_stack();

	if (!lock_memory())
		log.error() << "could not lock memory in RAM";

	bool useDefaultExecutor = true;
#ifdef ECMASTERLIB_FOUND
	if (etherCATStack) {
		if (useRosTime || syncWithGazeboIsSet) log.error() << "Can't use both etherCAT and RosTime to sync executor";
		log.trace() << "starting execution synced to etcherCAT stack";
		useDefaultExecutor = false;
		while (running) {
			std::unique_lock<std::mutex> lk(*m);
			cv->wait(lk);
			lk.unlock();

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
		}
	}
#endif
#ifdef ROS_FOUND
	if (useRosTime) {
		log.trace() << "starting execution synced to rosTime";
		useDefaultExecutor = false;
		long periodNsec = static_cast<long>(period * 1.0e9);
		long next_cycle = ros::Time::now().toNSec()+periodNsec;

// 		auto next_cycle = std::chrono::steady_clock::now() + seconds(period);
		while (running) {
			while (ros::Time::now().toNSec() < next_cycle && running) usleep(10);

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
			next_cycle += periodNsec;
		}

	}
	else if (syncWithGazeboIsSet) {
		log.trace() << "starting execution synced to gazebo";
		useDefaultExecutor = false;

		while (running) {
			while (syncRosCallbackQueue->isEmpty() && running) usleep(1);
			syncRosCallbackQueue->callAvailable();
			ros::getGlobalCallbackQueue()->callAvailable();

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
		}

	}
#endif
	if (useDefaultExecutor) {
		log.trace() << "starting periodic execution";
		auto next_cycle = std::chrono::steady_clock::now() + seconds(period);
		while (running) {
			std::this_thread::sleep_until(next_cycle);

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
			next_cycle += seconds(period);
		}
	}

	log.trace() << "stopping all threads";

	for (auto &t: threads)
		t->async.stop();

	log.trace() << "joining all threads";

	for (auto &t: threads)
		t->async.join();

	log.trace() << "exiting executor";
}
<commit_msg>sync with gazebo now waits for timestamp to change<commit_after>#include <algorithm>
#include <stdexcept>
#include <chrono>
#include <vector>
#include <memory>
#include <cmath>
#include <thread>
#include <signal.h>
#include <sched.h>
#include <sys/mman.h>

#include <eeros/core/Executor.hpp>
#include <eeros/task/Async.hpp>
#include <eeros/task/Lambda.hpp>
#include <eeros/task/HarmonicTaskList.hpp>
#include <eeros/control/TimeDomain.hpp>
#include <eeros/safety/SafetySystem.hpp>
#include <ros/callback_queue_interface.h>
#include <ros/callback_queue.h>

volatile bool running = true;

using namespace eeros;

namespace {

	using Logger = logger::Logger;

	struct TaskThread {
		TaskThread(double period, task::Periodic &task, task::HarmonicTaskList tasks) :
			taskList(tasks), async(taskList, task.getRealtime(), task.getNice())
		{
			async.counter.setPeriod(period);
			async.counter.monitors = task.monitors;
		}
		task::HarmonicTaskList taskList;
		task::Async async;
	};

	template < typename F >
	void traverse(std::vector<task::Periodic> &tasks, F func) {
		for (auto &t: tasks) {
			func(&t);
			traverse(t.before, func);
			traverse(t.after, func);
		}
	}

 	void createThread(Logger &log, task::Periodic &task, task::Periodic &baseTask, std::vector<std::shared_ptr<TaskThread>> &threads, std::vector<task::Harmonic> &output);

	void createThreads(Logger &log, std::vector<task::Periodic> &tasks, task::Periodic &baseTask, std::vector<std::shared_ptr<TaskThread>> &threads, task::HarmonicTaskList &output) {
		for (task::Periodic &t: tasks) {
			createThread(log, t, baseTask, threads, output.tasks);
		}
	}

	void createThread(Logger &log, task::Periodic &task, task::Periodic &baseTask, std::vector<std::shared_ptr<TaskThread>> &threads, std::vector<task::Harmonic> &output) {
		int k = static_cast<int>(task.getPeriod() / baseTask.getPeriod());
		double actualPeriod = k * baseTask.getPeriod();
		double deviation = std::abs(task.getPeriod() - actualPeriod) / task.getPeriod();
		task::HarmonicTaskList taskList;

		if (task.before.size() > 0) {
			createThreads(log, task.before, task, threads, taskList);
		}
		taskList.add(task.getTask());
		if (task.after.size() > 0) {
			createThreads(log, task.after, task, threads, taskList);
		}

		if (task.getRealtime())
			log.trace() << "creating harmonic realtime task '" << task.getName()
						<< "' with period " << actualPeriod << " sec (k = "
						<< k << ") and priority " << (Executor::basePriority - task.getNice())
						<< " based on '" << baseTask.getName() << "'";
		else
			log.trace() << "creating harmonic task '" << task.getName() << "' with period "
						<< actualPeriod << " sec (k = " << k << ")"
						<< " based on '" << baseTask.getName() << "'";

		if (deviation > 0.01) throw std::runtime_error("period deviation too high");

		if (task.getRealtime() && task.getNice() <= 0)
			throw std::runtime_error("priority not set");

		if (taskList.tasks.size() == 0)
			throw std::runtime_error("no task to execute");

		threads.push_back(std::make_shared<TaskThread>(actualPeriod, task, taskList));
		output.emplace_back(threads.back()->async, k);
	}
}

Executor::Executor() :
	log('E'), period(0), mainTask(nullptr), useRosTime(false), syncWithGazeboIsSet(false) { }

Executor::~Executor() {

}

Executor& Executor::instance() {
	static Executor executor;
	return executor;
}

#ifdef ECMASTERLIB_FOUND
void Executor::syncWithEtherCATSTack(ethercat::EtherCATMain* etherCATStack) {
	this->etherCATStack = etherCATStack;
	cv = etherCATStack->getConditionalVariable();
	m = etherCATStack->getMutex();
}
#endif

void Executor::setMainTask(task::Periodic &mainTask) {
	if (this->mainTask != nullptr)
		throw std::runtime_error("you can only define one main task per executor");
	period = mainTask.getPeriod();
	counter.setPeriod(period);
	this->mainTask = &mainTask;
}

void Executor::setMainTask(safety::SafetySystem &ss) {
	task::Periodic *task = new task::Periodic("safety system", ss.getPeriod(), ss, true);
	setMainTask(*task);
}

void Executor::add(task::Periodic &task) {
	tasks.push_back(task);
}

void Executor::add(control::TimeDomain &timedomain) {
	task::Periodic task(timedomain.getName().c_str(), timedomain.getPeriod(), timedomain, timedomain.getRealtime());
	tasks.push_back(task);
}

void Executor::prefault_stack() {
	unsigned char dummy[8*1024] = {};
}

bool Executor::lock_memory() {
	return (mlockall(MCL_CURRENT | MCL_FUTURE) != -1);
}

bool Executor::set_priority(int nice) {
	struct sched_param schedulingParam;
	schedulingParam.sched_priority = (Executor::basePriority - nice);
	return (sched_setscheduler(0, SCHED_FIFO, &schedulingParam) != -1);
}

void Executor::stop() {
	running = false;
	auto &instance = Executor::instance();
#ifdef ECMASTERLIB_FOUND
	if(instance.etherCATStack) instance.cv->notify_one();
#endif
}

void Executor::useRosTimeForExecutor() {
	useRosTime = true;
}

void Executor::syncWithGazebo(ros::CallbackQueue* syncRosCallbackQueue)
{
	std::cout << "sync executor with gazebo" << std::endl;
	syncWithGazeboIsSet = true;
	this->syncRosCallbackQueue = syncRosCallbackQueue;
}

void Executor::assignPriorities() {
	std::vector<task::Periodic*> priorityAssignments;

	// add task to list of priority assignments
	traverse(tasks, [&priorityAssignments] (task::Periodic *task) {
		priorityAssignments.push_back(task);
	});

	// sort list of priority assignments
	std::sort(priorityAssignments.begin(), priorityAssignments.end(), [] (task::Periodic *a, task::Periodic *b) -> bool {
		if (a->getRealtime() == b->getRealtime())
			return (a->getPeriod() < b->getPeriod());
		else
			return a->getRealtime();
	});

	// assign priorities
	int nice = 1;
	for (auto t: priorityAssignments) {
		if (t->getRealtime()) {
			t->setNice(nice++);
		}
	}
}

void Executor::run() {
	log.trace() << "starting executor with base period " << period << " sec and priority " << basePriority;

	if (period == 0.0)
		throw std::runtime_error("period of executor not set");

	log.trace() << "assigning priorities";
	assignPriorities();

	Runnable *mainTask = nullptr;

	if (this->mainTask != nullptr) {
		mainTask = &this->mainTask->getTask();
		log.trace() << "setting '" << this->mainTask->getName() << "' as main task";
	}

	std::vector<std::shared_ptr<TaskThread>> threads; // smart pointer used because async objects must not be copied
	task::HarmonicTaskList taskList;
	task::Periodic executorTask("executor", period, this, true);

	counter.monitors = this->mainTask->monitors;

	createThreads(log, tasks, executorTask, threads, taskList);

	using seconds = std::chrono::duration<double, std::chrono::seconds::period>;

	// TODO: implement this with ready-flag (wait for all threads to be ready instead of blind sleep)
	std::this_thread::sleep_for(seconds(1)); // wait 1 sec to allow threads to be created

	if (!set_priority(0))
		log.error() << "could not set realtime priority";

	prefault_stack();

	if (!lock_memory())
		log.error() << "could not lock memory in RAM";

	bool useDefaultExecutor = true;
#ifdef ECMASTERLIB_FOUND
	if (etherCATStack) {
		if (useRosTime || syncWithGazeboIsSet) log.error() << "Can't use both etherCAT and RosTime to sync executor";
		log.trace() << "starting execution synced to etcherCAT stack";
		useDefaultExecutor = false;
		while (running) {
			std::unique_lock<std::mutex> lk(*m);
			cv->wait(lk);
			lk.unlock();

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
		}
	}
#endif
#ifdef ROS_FOUND
	if (useRosTime) {
		log.trace() << "starting execution synced to rosTime";
		useDefaultExecutor = false;
		long periodNsec = static_cast<long>(period * 1.0e9);
		long next_cycle = ros::Time::now().toNSec()+periodNsec;

// 		auto next_cycle = std::chrono::steady_clock::now() + seconds(period);
		while (running) {
			while (ros::Time::now().toNSec() < next_cycle && running) usleep(10);

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
			next_cycle += periodNsec;
		}

	}
	else if (syncWithGazeboIsSet) {
		log.trace() << "starting execution synced to gazebo";
		useDefaultExecutor = false;

		auto timeOld = ros::Time::now();
		auto timeNew = ros::Time::now();
		static bool first = true;
		while (running) {
			while (syncRosCallbackQueue->isEmpty() && running) usleep(1);

			timeNew = ros::Time::now();
			if (!first) {
				while (timeOld == timeNew) {
					usleep(1);	// waits for new rosTime beeing published
					timeNew = ros::Time::now();
				}
			}
			timeOld = timeNew;

			syncRosCallbackQueue->callAvailable();
			ros::getGlobalCallbackQueue()->callAvailable();

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
		}

	}
#endif
	if (useDefaultExecutor) {
		log.trace() << "starting periodic execution";
		auto next_cycle = std::chrono::steady_clock::now() + seconds(period);
		while (running) {
			std::this_thread::sleep_until(next_cycle);

			counter.tick();
			taskList.run();
			if (mainTask != nullptr)
				mainTask->run();
			counter.tock();
			next_cycle += seconds(period);
		}
	}

	log.trace() << "stopping all threads";

	for (auto &t: threads)
		t->async.stop();

	log.trace() << "joining all threads";

	for (auto &t: threads)
		t->async.join();

	log.trace() << "exiting executor";
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2009-2010, Piotr Korzuszek
 * 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 <organization> 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 HOLDER 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.
 */

#include "RemoteCar.h"

#include "math/Float.h"

namespace Net
{

const int PASS_TIME = 500;

class RemoteCarImpl
{
	public:

		// To preserve lags, there are two car instances.
		// The old one is car physics situated when car position didn't change.
		// The new one is car physics forced by remote player.
		//
		// When new packet is received only the new car is positioned at new
		// place and moving from one position to another is made step by step
		// to make things smooth.

		Race::Car m_phantomCar;

		// Smooth pass float
		// 0.0 is old car, 1.0 is new car
		Math::Float m_passFloat;

		mutable CL_Pointf m_pos;

		mutable CL_Angle m_rot;
};

RemoteCar::RemoteCar() :
	m_impl(new RemoteCarImpl())
{
	// empty
}

RemoteCar::~RemoteCar()
{
	// empty
}

void RemoteCar::update(unsigned int p_elapsedMS)
{
	Car::update(p_elapsedMS);

	m_impl->m_passFloat.update(p_elapsedMS);
	const float newCarRatio = m_impl->m_passFloat.get();

	if (fabs(newCarRatio - 1.0f) > 0.01) {
		m_impl->m_phantomCar.update(p_elapsedMS);
	}
}

void RemoteCar::deserialize(const CL_NetGameEvent &p_data)
{
	CL_NetGameEvent ev("");
	serialize(&ev);
	m_impl->m_phantomCar.deserialize(ev);

	Car::deserialize(p_data);

	// start passing
	m_impl->m_passFloat.animate(0.0f, 1.0f, PASS_TIME);
}

const CL_Pointf& RemoteCar::getPosition() const
{
	const CL_Pointf &thisPos = Car::getPosition();

	const float newCarRatio = m_impl->m_passFloat.get();

	if (fabs(newCarRatio - 1.0f) > 0.01) {
		const CL_Pointf &phanPos = m_impl->m_phantomCar.getPosition();

		const CL_Vec2f delta = (thisPos - phanPos) * newCarRatio;
		m_impl->m_pos = phanPos + delta;

		return m_impl->m_pos;
	}

	return thisPos;
}

const CL_Angle &RemoteCar::getCorpseAngle() const
{
	const CL_Angle &thisAngle = Car::getCorpseAngle();

//	const float newCarRatio = m_impl->m_passFloat.get();
//
//	if (fabs(newCarRatio - 1.0f) > 0.01) {
//		const CL_Angle &phanAngle = m_impl->m_phantomCar.getCorpseAngle();
//
//		const CL_Angle delta = (thisAngle - phanAngle) * newCarRatio;
//		m_impl->m_rot = phanAngle + delta;
//
//		return m_impl->m_rot;
//	}

	return thisAngle;
}

}
<commit_msg>Fix RemoteCar<commit_after>/*
 * Copyright (c) 2009-2010, Piotr Korzuszek
 * 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 <organization> 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 HOLDER 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.
 */

#include "RemoteCar.h"

#include "math/Float.h"

namespace Net
{

const int PASS_TIME = 250;

class RemoteCarImpl
{
	public:

		// To preserve lags, there are two car instances.
		// The old one is car physics situated when car position didn't change.
		// The new one is car physics forced by remote player.
		//
		// When new packet is received only the new car is positioned at new
		// place and moving from one position to another is made step by step
		// to make things smooth.

		Race::Car m_phantomCar;

		// Smooth pass float
		// 0.0 is old car, 1.0 is new car
		Math::Float m_passFloat;

		mutable CL_Pointf m_pos;

		mutable CL_Angle m_rot;
};

RemoteCar::RemoteCar() :
	m_impl(new RemoteCarImpl())
{
	// empty
}

RemoteCar::~RemoteCar()
{
	// empty
}

void RemoteCar::update(unsigned int p_elapsedMS)
{
	Car::update(p_elapsedMS);
	m_impl->m_phantomCar.update(p_elapsedMS);
	m_impl->m_passFloat.update(p_elapsedMS);
}

void RemoteCar::deserialize(const CL_NetGameEvent &p_data)
{
	CL_NetGameEvent ev("");
	serialize(&ev);
	m_impl->m_phantomCar.deserialize(ev);

	Car::deserialize(p_data);

	// start passing
	m_impl->m_passFloat.animate(0.0f, 1.0f, PASS_TIME);
}

const CL_Pointf& RemoteCar::getPosition() const
{
	const CL_Pointf &thisPos = Car::getPosition();

	const float newCarRatio = m_impl->m_passFloat.get();

	if (fabs(newCarRatio - 1.0f) > 0.01) {
		const CL_Pointf &phanPos = m_impl->m_phantomCar.getPosition();

		const CL_Vec2f delta = (thisPos - phanPos) * newCarRatio;
		m_impl->m_pos = phanPos + delta;

		return m_impl->m_pos;
	}

	return thisPos;
}

const CL_Angle &RemoteCar::getCorpseAngle() const
{
	const CL_Angle &thisAngle = Car::getCorpseAngle();

	const float newCarRatio = m_impl->m_passFloat.get();

	if (fabs(newCarRatio - 1.0f) > 0.01) {
		const CL_Angle &phanAngle = m_impl->m_phantomCar.getCorpseAngle();

		const CL_Angle delta = (thisAngle - phanAngle) * newCarRatio;
		m_impl->m_rot = phanAngle + delta;

		return m_impl->m_rot;
	}

	return thisAngle;
}

}
<|endoftext|>