<commit_before>/*
 * Copyright (c) 2012 Bernhard Firner and Rutgers University
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * or visit http://www.gnu.org/licenses/gpl-2.0.html
 */

/*******************************************************************************
 * This file defines a class that simplifies connecting to the world model
 * as a solver.
 ******************************************************************************/

#include "solver_world_connection.hpp"

#include <algorithm>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#include <sys/types.h>
#include <sys/socket.h>

//Send a handshake and a type declaration message.
bool SolverWorldModel::reconnect() {
  //Reset connection status and set to true after the handshake.
  _connected = false;
  if (s) {
    std::cout<<"Connected to the GRAIL world model.\n";
  } else {
    //Otherwise try to make a new connection
    ClientSocket s2(AF_INET, SOCK_STREAM, 0, port, ip);
    if (not s2) {
      std::cerr<<"Failed to connect to the GRAIL world model.\n";
      return false;
    }
    else {
      s = std::move(s2);
    }
  }

  //Try to get the handshake message
  {
    std::vector<unsigned char> handshake = world_model::solver::makeHandshakeMsg();

    //Send the handshake message
    s.send(handshake);
    std::vector<unsigned char> raw_message(handshake.size());
    size_t length = s.receive(raw_message);

    //Check if the handshake message failed
    if (not (length == handshake.size() and
          std::equal(handshake.begin(), handshake.end(), raw_message.begin()) )) {
      std::cerr<<"Failure during solver handshake with world model.\n";
      return false;
    }
  }

  //Send the type announcement message
  try {
    s.send(world_model::solver::makeTypeAnnounceMsg(types, origin));
  }
  catch (std::runtime_error err) {
    std::cerr<<"Problem sending type announce message: "<<err.what()<<'\n';
    return false;
  }

  //Clear the old thread if one was running
  if (running) {
    interrupted = true;
    on_demand_tracker.join();
  }

  ss.previous_unfinished.clear();
  running = true;
  interrupted = false;
  //Start the on_demand status tracking thread
  on_demand_tracker = std::thread(std::mem_fun(&SolverWorldModel::trackOnDemands), this);
  _connected = true;
  return true;
}

static std::string toString(const std::u16string& str) {
  return std::string(str.begin(), str.end());
}

void SolverWorldModel::trackOnDemands() {
  using world_model::solver::MessageID;
  while (not interrupted) {
    std::vector<unsigned char> in_buff = ss.getNextMessage(interrupted);
    if (5 <= in_buff.size()) {
      MessageID message_type = (MessageID)in_buff[4];
      if (message_type == MessageID::start_on_demand) {
        std::vector<std::tuple<uint32_t, std::vector<std::u16string>>> trans =
          world_model::solver::decodeStartOnDemand(in_buff);
        std::unique_lock<std::mutex> lck(trans_mutex);
        for (auto I = trans.begin(); I != trans.end(); ++I) {
          std::cerr<<"OnDemand "<<std::get<0>(*I)<<" has "<<std::get<1>(*I).size()<<" URI requests.\n";
          std::vector<std::u16string>& requests = std::get<1>(*I);
          for (std::u16string& request : requests) {
            //Store the regex pattern sent by the world model.
            std::cerr<<"Enabling on_demand: "<<std::get<0>(*I)<<" with string "<<toString(request)<<'\n';

            OnDemandArgs ta;
            ta.request = request;
            int err = regcomp(&ta.exp, toString(ta.request).c_str(), REG_EXTENDED);
            if (0 != err) {
              ta.valid = false;
              std::cerr<<"Error compiling regular expression "<<toString(ta.request)<<" in on_demand request to solver client.\n";
            }
            else {
              ta.valid = true;
            }
            on_demand_on[std::get<0>(*I)].insert(ta);
          }
        }
      }
      else if (message_type == MessageID::stop_on_demand) {
        std::vector<std::tuple<uint32_t, std::vector<std::u16string>>> trans =
          world_model::solver::decodeStopOnDemand(in_buff);
        std::unique_lock<std::mutex> lck(trans_mutex);
        for (auto I = trans.begin(); I != trans.end(); ++I) {
          uint32_t attr_name = std::get<0>(*I);
          std::vector<std::u16string>& requests = std::get<1>(*I);
          for (std::u16string& request : requests) {
            //Remove the regex that was sent by the world model
            std::cerr<<"Disabling on_demand: "<<attr_name<<" with request "<<toString(request)<<'\n';
            if (on_demand_on.end() != on_demand_on.find(attr_name)) {
              std::multiset<OnDemandArgs>& uri_set = on_demand_on[attr_name];
              auto J = std::find_if(uri_set.begin(), uri_set.end(),
                  [&](const OnDemandArgs& ta) { return ta.request == request;});
              if (J != uri_set.end()) {
                OnDemandArgs ta = *J;
                if (ta.valid) {
                  regfree(&ta.exp);
                }
                uri_set.erase(J);
              }
            }
          }
        }
      }
      else if (message_type == MessageID::keep_alive) {
        //Send a keep alive message in reply to a keep alive from
        //the server. This makes sure that we are replying at less
        //than the sever's timeout period.
        std::unique_lock<std::mutex> lck(send_mutex);
        s.send(world_model::solver::makeKeepAlive());
      }
    }
    else {
      std::cerr<<"Got an invalid sized message (size = "<<in_buff.size()<<'\n';
    }
  }
}

SolverWorldModel::SolverWorldModel(std::string ip, uint16_t port, std::vector<std::pair<std::u16string, bool>>& types, std::u16string origin) : s(AF_INET, SOCK_STREAM, 0, port, ip), ss(s) {
  this->origin = origin;
  //Store the alias types that this solver will use
  for (auto I = types.begin(); I != types.end(); ++I) {
    world_model::solver::AliasType at{(uint32_t)(this->types.size()+1), I->first, I->second};
    this->types.push_back(at);
    aliases[at.type] = at.alias;
    if (I->second) {
      if (on_demand_on.end() == on_demand_on.find(at.alias)) {
        on_demand_on[at.alias] = std::multiset<OnDemandArgs>();
      }
    }
  }
  //Store these values so that we can reconnect later
  this->ip = ip;
  this->port = port;

  reconnect();
}

SolverWorldModel::~SolverWorldModel() {
  if (running) {
    interrupted = true;
    on_demand_tracker.join();
  }
}

void SolverWorldModel::addTypes(std::vector<std::pair<std::u16string, bool>>& new_types) {
  //Store the alias types that this solver will use
	std::vector<world_model::solver::AliasType> new_aliases;
  for (auto I = new_types.begin(); I != new_types.end(); ++I) {
    world_model::solver::AliasType at{(uint32_t)(this->types.size()+1), I->first, I->second};
    this->types.push_back(at);
    aliases[at.type] = at.alias;
    if (I->second) {
      if (on_demand_on.end() == on_demand_on.find(at.alias)) {
        on_demand_on[at.alias] = std::multiset<OnDemandArgs>();
      }
    }
		new_aliases.push_back(at);
  }
  //Update the world model with a new type announcement message
  try {
    std::unique_lock<std::mutex> lck(send_mutex);
    s.send(world_model::solver::makeTypeAnnounceMsg(new_aliases, origin));
  }
  catch (std::runtime_error err) {
    std::cerr<<"Problem sending type announce message: "<<err.what()<<'\n';
  }
}

bool SolverWorldModel::connected() {
  return _connected;
}

void SolverWorldModel::sendData(std::vector<AttrUpdate>& solution, bool create_uris) {
  using world_model::solver::SolutionData;
  std::vector<SolutionData> sds;
  for (auto I = solution.begin(); I != solution.end(); ++I) {
    std::unique_lock<std::mutex> lck(trans_mutex);
    if (aliases.end() != aliases.find(I->type)) {
      uint32_t alias = aliases[I->type];
      //TODO Let the user check this themselves, it should be up to them
      //whether or not to send data
      //Send if this is not a on_demand or it is a on_demand but is requested
      if (on_demand_on.end() == on_demand_on.find(alias)) {
        SolutionData sd{alias, I->time, I->target, I->data};
        sds.push_back(sd);
      }
      else {
        //Find if any patterns match this information
        if (std::any_of(on_demand_on[alias].begin(), on_demand_on[alias].end(),
              [&](const OnDemandArgs& ta) {
              if (not ta.valid) { return false;}
              regmatch_t pmatch;
              int match = regexec(&ta.exp, toString(I->target).c_str(), 1, &pmatch, 0);
              return (0 == match and 0 == pmatch.rm_so and I->target.size() == pmatch.rm_eo); })) {
          SolutionData sd{alias, I->time, I->target, I->data};
          sds.push_back(sd);
        }
      }
    }
  }

  //Allow sending an empty message (if all of the solutions are unrequested
  //on_demand solutions) to serve as a keep alive.
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeSolutionMsg(create_uris, sds));
}

void SolverWorldModel::createURI(world_model::URI uri, world_model::grail_time created) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeCreateURI(uri, created, origin));
}

void SolverWorldModel::expireURI(world_model::URI uri, world_model::grail_time expires) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeExpireURI(uri, expires, origin));
}

void SolverWorldModel::deleteURI(world_model::URI uri) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeDeleteURI(uri, origin));
}

void SolverWorldModel::expireURIAttribute(world_model::URI uri, std::u16string name, world_model::grail_time expires) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeExpireAttribute(uri, name, origin, expires));
}

void SolverWorldModel::deleteURIAttribute(world_model::URI uri, std::u16string name) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeDeleteAttribute(uri, name, origin));
}

<commit_msg>Initialize @running variable to false (no listening thread).<commit_after>/*
 * Copyright (c) 2012 Bernhard Firner and Rutgers University
 * All rights reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
 * or visit http://www.gnu.org/licenses/gpl-2.0.html
 */

/*******************************************************************************
 * This file defines a class that simplifies connecting to the world model
 * as a solver.
 ******************************************************************************/

#include "solver_world_connection.hpp"

#include <algorithm>
#include <iostream>
#include <string>
#include <tuple>
#include <vector>

#include <sys/types.h>
#include <sys/socket.h>

//Send a handshake and a type declaration message.
bool SolverWorldModel::reconnect() {
  //Reset connection status and set to true after the handshake.
  _connected = false;
  if (s) {
    std::cout<<"Connected to the GRAIL world model.\n";
  } else {
    //Otherwise try to make a new connection
    ClientSocket s2(AF_INET, SOCK_STREAM, 0, port, ip);
    if (not s2) {
      std::cerr<<"Failed to connect to the GRAIL world model.\n";
      return false;
    }
    else {
      s = std::move(s2);
    }
  }

  //Try to get the handshake message
  {
    std::vector<unsigned char> handshake = world_model::solver::makeHandshakeMsg();

    //Send the handshake message
    s.send(handshake);
    std::vector<unsigned char> raw_message(handshake.size());
    size_t length = s.receive(raw_message);

    //Check if the handshake message failed
    if (not (length == handshake.size() and
          std::equal(handshake.begin(), handshake.end(), raw_message.begin()) )) {
      std::cerr<<"Failure during solver handshake with world model.\n";
      return false;
    }
  }

  //Send the type announcement message
  try {
    s.send(world_model::solver::makeTypeAnnounceMsg(types, origin));
  }
  catch (std::runtime_error err) {
    std::cerr<<"Problem sending type announce message: "<<err.what()<<'\n';
    return false;
  }

  //Clear the old thread if one was running
  if (running) {
    interrupted = true;
    on_demand_tracker.join();
  }

  ss.previous_unfinished.clear();
  running = true;
  interrupted = false;
  //Start the on_demand status tracking thread
  on_demand_tracker = std::thread(std::mem_fun(&SolverWorldModel::trackOnDemands), this);
  _connected = true;
  return true;
}

static std::string toString(const std::u16string& str) {
  return std::string(str.begin(), str.end());
}

void SolverWorldModel::trackOnDemands() {
  using world_model::solver::MessageID;
  while (not interrupted) {
    std::vector<unsigned char> in_buff = ss.getNextMessage(interrupted);
    if (5 <= in_buff.size()) {
      MessageID message_type = (MessageID)in_buff[4];
      if (message_type == MessageID::start_on_demand) {
        std::vector<std::tuple<uint32_t, std::vector<std::u16string>>> trans =
          world_model::solver::decodeStartOnDemand(in_buff);
        std::unique_lock<std::mutex> lck(trans_mutex);
        for (auto I = trans.begin(); I != trans.end(); ++I) {
          std::cerr<<"OnDemand "<<std::get<0>(*I)<<" has "<<std::get<1>(*I).size()<<" URI requests.\n";
          std::vector<std::u16string>& requests = std::get<1>(*I);
          for (std::u16string& request : requests) {
            //Store the regex pattern sent by the world model.
            std::cerr<<"Enabling on_demand: "<<std::get<0>(*I)<<" with string "<<toString(request)<<'\n';

            OnDemandArgs ta;
            ta.request = request;
            int err = regcomp(&ta.exp, toString(ta.request).c_str(), REG_EXTENDED);
            if (0 != err) {
              ta.valid = false;
              std::cerr<<"Error compiling regular expression "<<toString(ta.request)<<" in on_demand request to solver client.\n";
            }
            else {
              ta.valid = true;
            }
            on_demand_on[std::get<0>(*I)].insert(ta);
          }
        }
      }
      else if (message_type == MessageID::stop_on_demand) {
        std::vector<std::tuple<uint32_t, std::vector<std::u16string>>> trans =
          world_model::solver::decodeStopOnDemand(in_buff);
        std::unique_lock<std::mutex> lck(trans_mutex);
        for (auto I = trans.begin(); I != trans.end(); ++I) {
          uint32_t attr_name = std::get<0>(*I);
          std::vector<std::u16string>& requests = std::get<1>(*I);
          for (std::u16string& request : requests) {
            //Remove the regex that was sent by the world model
            std::cerr<<"Disabling on_demand: "<<attr_name<<" with request "<<toString(request)<<'\n';
            if (on_demand_on.end() != on_demand_on.find(attr_name)) {
              std::multiset<OnDemandArgs>& uri_set = on_demand_on[attr_name];
              auto J = std::find_if(uri_set.begin(), uri_set.end(),
                  [&](const OnDemandArgs& ta) { return ta.request == request;});
              if (J != uri_set.end()) {
                OnDemandArgs ta = *J;
                if (ta.valid) {
                  regfree(&ta.exp);
                }
                uri_set.erase(J);
              }
            }
          }
        }
      }
      else if (message_type == MessageID::keep_alive) {
        //Send a keep alive message in reply to a keep alive from
        //the server. This makes sure that we are replying at less
        //than the sever's timeout period.
        std::unique_lock<std::mutex> lck(send_mutex);
        s.send(world_model::solver::makeKeepAlive());
      }
    }
    else {
      std::cerr<<"Got an invalid sized message (size = "<<in_buff.size()<<'\n';
    }
  }
}

SolverWorldModel::SolverWorldModel(std::string ip, uint16_t port, std::vector<std::pair<std::u16string, bool>>& types, std::u16string origin) : s(AF_INET, SOCK_STREAM, 0, port, ip), ss(s) {
  running = false;
  this->origin = origin;
  //Store the alias types that this solver will use
  for (auto I = types.begin(); I != types.end(); ++I) {
    world_model::solver::AliasType at{(uint32_t)(this->types.size()+1), I->first, I->second};
    this->types.push_back(at);
    aliases[at.type] = at.alias;
    if (I->second) {
      if (on_demand_on.end() == on_demand_on.find(at.alias)) {
        on_demand_on[at.alias] = std::multiset<OnDemandArgs>();
      }
    }
  }
  //Store these values so that we can reconnect later
  this->ip = ip;
  this->port = port;

  reconnect();
}

SolverWorldModel::~SolverWorldModel() {
  if (running) {
    interrupted = true;
    on_demand_tracker.join();
  }
}

void SolverWorldModel::addTypes(std::vector<std::pair<std::u16string, bool>>& new_types) {
  //Store the alias types that this solver will use
	std::vector<world_model::solver::AliasType> new_aliases;
  for (auto I = new_types.begin(); I != new_types.end(); ++I) {
    world_model::solver::AliasType at{(uint32_t)(this->types.size()+1), I->first, I->second};
    this->types.push_back(at);
    aliases[at.type] = at.alias;
    if (I->second) {
      if (on_demand_on.end() == on_demand_on.find(at.alias)) {
        on_demand_on[at.alias] = std::multiset<OnDemandArgs>();
      }
    }
		new_aliases.push_back(at);
  }
  //Update the world model with a new type announcement message
  try {
    std::unique_lock<std::mutex> lck(send_mutex);
    s.send(world_model::solver::makeTypeAnnounceMsg(new_aliases, origin));
  }
  catch (std::runtime_error err) {
    std::cerr<<"Problem sending type announce message: "<<err.what()<<'\n';
  }
}

bool SolverWorldModel::connected() {
  return _connected;
}

void SolverWorldModel::sendData(std::vector<AttrUpdate>& solution, bool create_uris) {
  using world_model::solver::SolutionData;
  std::vector<SolutionData> sds;
  for (auto I = solution.begin(); I != solution.end(); ++I) {
    std::unique_lock<std::mutex> lck(trans_mutex);
    if (aliases.end() != aliases.find(I->type)) {
      uint32_t alias = aliases[I->type];
      //TODO Let the user check this themselves, it should be up to them
      //whether or not to send data
      //Send if this is not a on_demand or it is a on_demand but is requested
      if (on_demand_on.end() == on_demand_on.find(alias)) {
        SolutionData sd{alias, I->time, I->target, I->data};
        sds.push_back(sd);
      }
      else {
        //Find if any patterns match this information
        if (std::any_of(on_demand_on[alias].begin(), on_demand_on[alias].end(),
              [&](const OnDemandArgs& ta) {
              if (not ta.valid) { return false;}
              regmatch_t pmatch;
              int match = regexec(&ta.exp, toString(I->target).c_str(), 1, &pmatch, 0);
              return (0 == match and 0 == pmatch.rm_so and I->target.size() == pmatch.rm_eo); })) {
          SolutionData sd{alias, I->time, I->target, I->data};
          sds.push_back(sd);
        }
      }
    }
  }

  //Allow sending an empty message (if all of the solutions are unrequested
  //on_demand solutions) to serve as a keep alive.
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeSolutionMsg(create_uris, sds));
}

void SolverWorldModel::createURI(world_model::URI uri, world_model::grail_time created) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeCreateURI(uri, created, origin));
}

void SolverWorldModel::expireURI(world_model::URI uri, world_model::grail_time expires) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeExpireURI(uri, expires, origin));
}

void SolverWorldModel::deleteURI(world_model::URI uri) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeDeleteURI(uri, origin));
}

void SolverWorldModel::expireURIAttribute(world_model::URI uri, std::u16string name, world_model::grail_time expires) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeExpireAttribute(uri, name, origin, expires));
}

void SolverWorldModel::deleteURIAttribute(world_model::URI uri, std::u16string name) {
  std::unique_lock<std::mutex> lck(send_mutex);
  s.send(world_model::solver::makeDeleteAttribute(uri, name, origin));
}

<|endoftext|>


<commit_before>
// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#include <boost/test/unit_test.hpp>

#include "Grappa.hpp"
#include "CompletionEvent.hpp"
#include "ParallelLoop.hpp"
#include "Collective.hpp"

#include <string>

DECLARE_uint64( num_starting_workers );
DEFINE_uint64( num_test_workers, 4, "Number of workers for the tests");
DEFINE_uint64( iters_per_task, 10000, "Iterations per task" );
DEFINE_string( test_type, "yields", "options: {yields,sequential_updates, sequential_updates16" );
DEFINE_uint64( private_array_size, 1, "Size of private array of 8-bytes for each task" );

using namespace Grappa;

CompletionEvent * final;
CompletionEvent * task_barrier;

struct SixteenBytes {
  uint64_t val1;
  uint64_t val2;
};

struct Cacheline {
  uint64_t val;
  char padding[56];
};

uint64_t * values8;
SixteenBytes * values16;

// core-shared counter for counting progress
uint64_t numst;
uint64_t waitCount;
bool running;

BOOST_AUTO_TEST_SUITE( ContextSwitchRate_tests );

void user_main( void * args ) {
  srand((unsigned int)Grappa_walltime());

  // must have enough threads because they all join a barrier
  BOOST_CHECK( FLAGS_num_test_workers < FLAGS_num_starting_workers );

  if (FLAGS_test_type.compare("yields")==0) {
    BOOST_MESSAGE( "Test yields" );
    {
      struct runtimes_t {
        double runtime_avg, runtime_min, runtime_max;
      };
      runtimes_t r;

      on_all_cores( [&r] {
        // per core timing
        double start, end;
        bool started = false;

        final = new CompletionEvent(FLAGS_num_test_workers);
        task_barrier = new CompletionEvent(FLAGS_num_test_workers);

        for ( uint64_t t=0; t<FLAGS_num_test_workers; t++ ) {
          privateTask( [&started,&start] {
            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // first task to exit the local barrier will start the timer
            if ( !started ) {
              start = Grappa_walltime();
              started = true;
            }

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
              Grappa_yield();
            }

            final->complete();
          });
        }

        BOOST_MESSAGE( "waiting" );
        final->wait();
        end = Grappa_walltime();
        double runtime = end-start;
        BOOST_MESSAGE( "took time " << runtime );

        Grappa::barrier();
        BOOST_MESSAGE( "all done" );

        // sort out timing

        double r_sum = Grappa::allreduce<double, collective_add>( runtime );
        double r_min = Grappa::allreduce<double, collective_min>( runtime );
        double r_max = Grappa::allreduce<double, collective_max>( runtime );
        if ( Grappa::mycore()==0 ) {
          r.runtime_avg = r_sum / Grappa::cores();
          r.runtime_min = r_min;
          r.runtime_max = r_max;
        }
      });

      BOOST_MESSAGE( "cores_time_avg = " << r.runtime_avg
                      << ", cores_time_max = " << r.runtime_max
                      << ", cores_time_min = " << r.runtime_min);
    }
  } else if (FLAGS_test_type.compare("cvwakes")==0) {
    BOOST_MESSAGE( "Test cv wakes" );
    {
      struct runtimes_t {
        double runtime_avg, runtime_min, runtime_max;
      };
      runtimes_t r;

      on_all_cores( [&r] {
        // per core timing
        double start, end;

        ConditionVariable cvs[FLAGS_num_test_workers];
        bool asleep[FLAGS_num_test_workers];
        for( int i=0; i<FLAGS_num_test_workers; i++) { asleep[i] = false; }

        final = new CompletionEvent(1);
        task_barrier = new CompletionEvent(FLAGS_num_test_workers);

        running = false;
        waitCount = 0;
        numst = 0;

        for ( uint64_t t=0; t<FLAGS_num_test_workers; t++ ) {
          privateTask( [&asleep,&start,&cvs] {
            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // first task to exit the local barrier will start the timer
            if ( !running ) {
              start = Grappa_walltime();
              running = true;
            }

            uint64_t tid = numst++;

            uint64_t partner = (tid + FLAGS_num_test_workers/2)%FLAGS_num_test_workers;
            uint64_t total_iters = FLAGS_iters_per_task*FLAGS_num_test_workers;

            // do the work
            while( waitCount++ < total_iters ) {
              if ( asleep[partner] ) {   // TODO also test just wake up case
                Grappa::signal( &cvs[partner] );
              }
              asleep[tid] = true;
              Grappa::wait( &cvs[tid] );
              asleep[tid] = false;
            }

            // only first
            if ( running ) {
              final->complete();  // signal to finish as soon as the parent task gets scheduled
              running = false;
            }
          });
        }

        BOOST_MESSAGE( "waiting" );
        final->wait();
        end = Grappa_walltime();
        double runtime = end-start;
        BOOST_MESSAGE( "took time " << runtime );

        // wake all
        for (int i=0; i<FLAGS_num_test_workers; i++) { Grappa::signal(&cvs[i]); }
        BOOST_MESSAGE( "woke all" );

        Grappa::barrier();

        BOOST_MESSAGE( "all done" );

        // sort out timing

        double r_sum = Grappa::allreduce<double, collective_add>( runtime );
        double r_min = Grappa::allreduce<double, collective_min>( runtime );
        double r_max = Grappa::allreduce<double, collective_max>( runtime );
        if ( Grappa::mycore()==0 ) {
          r.runtime_avg = r_sum / Grappa::cores();
          r.runtime_min = r_min;
          r.runtime_max = r_max;
        }
        BOOST_MESSAGE( "done reduce" );
      });

      BOOST_MESSAGE( "cores_time_avg = " << r.runtime_avg
                      << ", cores_time_max = " << r.runtime_max
                      << ", cores_time_min = " << r.runtime_min);
    }

  } else if (FLAGS_test_type.compare("sequential_updates")==0) {
    BOOST_MESSAGE( "Test sequential_updates" );
    {

      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values8 = new uint64_t[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
          // wait for all to start (to hack scheduler yield)
          task_barrier->complete();
          task_barrier->wait();

          // do the work
          for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            values8[t] += 1;
            Grappa_yield();
          }
          final->complete();
        });
      }

      final->wait();
      double end = Grappa_walltime();

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else if (FLAGS_test_type.compare("sequential_updates16")==0) {

    BOOST_MESSAGE( "Test sequential_updates16" );
    {
      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values16 = new SixteenBytes[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            values16[t].val1 += 1;
            values16[t].val2 += 1;
            Grappa_yield();
            }
            final->complete();
            });
      }

      final->wait();
      double end = Grappa_walltime();

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else if (FLAGS_test_type.compare("private_array")==0) {

    BOOST_MESSAGE( "Test private_array" );
    {
      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values8 = new uint64_t[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
            uint64_t myarray[FLAGS_private_array_size];

            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            for (uint64_t j=0; j<FLAGS_private_array_size; j++) {
            myarray[j] += 1;
            }
            Grappa_yield();
            }
            values8[t] = myarray[rand()%FLAGS_private_array_size];
            final->complete();
            });
      }

      final->wait();
      double end = Grappa_walltime();

      BOOST_MESSAGE( "result = " << values8[rand()%FLAGS_num_starting_workers] );

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else if (FLAGS_test_type.compare("private_array_bycache")==0) {

    BOOST_MESSAGE( "Test private_array_bycache" );
    {
      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values8 = new uint64_t[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
            Cacheline myarray[FLAGS_private_array_size];

            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            for (uint64_t j=0; j<FLAGS_private_array_size; j++) {
            myarray[j].val += 1;
            }
            Grappa_yield();
            }
            values8[t] = myarray[rand()%FLAGS_private_array_size].val;
            final->complete();
            });
      }

      final->wait();
      double end = Grappa_walltime();

      BOOST_MESSAGE( "result = " << values8[rand()%FLAGS_num_starting_workers] );

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else {
    BOOST_CHECK( false ); // Unrecognized test_type
  }

  BOOST_MESSAGE( "user main is exiting" );
}

BOOST_AUTO_TEST_CASE( test1 ) {

  Grappa_init( &(boost::unit_test::framework::master_test_suite().argc),
                &(boost::unit_test::framework::master_test_suite().argv) );

  Grappa_activate();

  DVLOG(1) << "Spawning user main Thread....";
  Grappa_run_user_main( &user_main, (void*)NULL );
  VLOG(5) << "run_user_main returned";
  CHECK( Grappa_done() );

  Grappa_finish( 0 );
}

BOOST_AUTO_TEST_SUITE_END();

<commit_msg>context switch tests: allocate CVs on the heap, add statistics output<commit_after>
// Copyright 2010-2012 University of Washington. All Rights Reserved.
// LICENSE_PLACEHOLDER
// This software was created with Government support under DE
// AC05-76RL01830 awarded by the United States Department of
// Energy. The Government has certain rights in the software.

#include <boost/test/unit_test.hpp>

#include "Grappa.hpp"
#include "CompletionEvent.hpp"
#include "ParallelLoop.hpp"
#include "Collective.hpp"
#include "Statistics.hpp"

#include <string>

DECLARE_uint64( num_starting_workers );
DEFINE_uint64( num_test_workers, 4, "Number of workers for the tests");
DEFINE_uint64( iters_per_task, 10000, "Iterations per task" );
DEFINE_string( test_type, "yields", "options: {yields,sequential_updates, sequential_updates16" );
DEFINE_uint64( private_array_size, 1, "Size of private array of 8-bytes for each task" );

using namespace Grappa;

CompletionEvent * final;
CompletionEvent * task_barrier;

struct SixteenBytes {
  uint64_t val1;
  uint64_t val2;
};

struct Cacheline {
  uint64_t val;
  char padding[56];
};

uint64_t * values8;
SixteenBytes * values16;

// core-shared counter for counting progress
uint64_t numst;
uint64_t waitCount; // TODO: for traces, change to SimpleStatistic
bool running;

BOOST_AUTO_TEST_SUITE( ContextSwitchRate_tests );

void user_main( void * args ) {
  srand((unsigned int)Grappa_walltime());

  // must have enough threads because they all join a barrier
  BOOST_CHECK( FLAGS_num_test_workers < FLAGS_num_starting_workers );

  if (FLAGS_test_type.compare("yields")==0) {
    BOOST_MESSAGE( "Test yields" );
    {
      struct runtimes_t {
        double runtime_avg, runtime_min, runtime_max;
      };
      runtimes_t r;

      on_all_cores( [&r] {
        // per core timing
        double start, end;
        running = false;

        final = new CompletionEvent(FLAGS_num_test_workers);
        task_barrier = new CompletionEvent(FLAGS_num_test_workers);

        for ( uint64_t t=0; t<FLAGS_num_test_workers; t++ ) {
          privateTask( [&start] {
            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // first task to exit the local barrier will start the timer
            if ( !running ) {
              Grappa::Statistics::reset();
              start = Grappa_walltime();
              running = true;
            }

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
              Grappa_yield();
            }

            final->complete();
          });
        }

        BOOST_MESSAGE( "waiting" );
        final->wait();
        end = Grappa_walltime();
        double runtime = end-start;
        BOOST_MESSAGE( "took time " << runtime );

        Grappa::barrier();
        BOOST_MESSAGE( "all done" );

        // sort out timing

        double r_sum = Grappa::allreduce<double, collective_add>( runtime );
        double r_min = Grappa::allreduce<double, collective_min>( runtime );
        double r_max = Grappa::allreduce<double, collective_max>( runtime );
        if ( Grappa::mycore()==0 ) {
          r.runtime_avg = r_sum / Grappa::cores();
          r.runtime_min = r_min;
          r.runtime_max = r_max;
        }
      });

      Grappa::Statistics::merge_and_print();

      BOOST_MESSAGE( "cores_time_avg = " << r.runtime_avg
                      << ", cores_time_max = " << r.runtime_max
                      << ", cores_time_min = " << r.runtime_min);
    }
  } else if (FLAGS_test_type.compare("cvwakes")==0) {
    BOOST_MESSAGE( "Test cv wakes" );
    {
      struct runtimes_t {
        double runtime_avg, runtime_min, runtime_max;
      };
      runtimes_t r;

      on_all_cores( [&r] {
        // per core timing
        double start, end;

        ConditionVariable * cvs = new ConditionVariable[FLAGS_num_test_workers];
        bool * asleep = new bool[FLAGS_num_test_workers];
        for( int i=0; i<FLAGS_num_test_workers; i++) { asleep[i] = false; }

        final = new CompletionEvent(1);
        task_barrier = new CompletionEvent(FLAGS_num_test_workers);

        running = false;
        waitCount = 0;
        numst = 0;

        for ( uint64_t t=0; t<FLAGS_num_test_workers; t++ ) {
          privateTask( [asleep,&start,cvs] {
            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // first task to exit the local barrier will start the timer
            if ( !running ) {
              // can safely reset statistics here because
              // no messages are sent between cores in the
              // timed portion
              Grappa::Statistics::reset();
              start = Grappa_walltime();
              running = true;
            }

            uint64_t tid = numst++;

            uint64_t partner = (tid + FLAGS_num_test_workers/2)%FLAGS_num_test_workers;
            uint64_t total_iters = FLAGS_iters_per_task*FLAGS_num_test_workers;

            // do the work
            while( waitCount++ < total_iters ) {
              if ( asleep[partner] ) {   // TODO also test just wake up case
                Grappa::signal( &cvs[partner] );
              }
              asleep[tid] = true;
              Grappa::wait( &cvs[tid] );
              asleep[tid] = false;
            }

            // only first
            if ( running ) {
              final->complete();  // signal to finish as soon as the parent task gets scheduled
              running = false;
            }
          });
        }

        BOOST_MESSAGE( "waiting" );
        final->wait();
        end = Grappa_walltime();
        double runtime = end-start;
        BOOST_MESSAGE( "took time " << runtime );

        // wake all
        for (int i=0; i<FLAGS_num_test_workers; i++) { Grappa::signal(&cvs[i]); }
        BOOST_MESSAGE( "woke all" );

        Grappa::barrier();

        BOOST_MESSAGE( "all done" );

        // sort out timing

        double r_sum = Grappa::allreduce<double, collective_add>( runtime );
        double r_min = Grappa::allreduce<double, collective_min>( runtime );
        double r_max = Grappa::allreduce<double, collective_max>( runtime );
        if ( Grappa::mycore()==0 ) {
          r.runtime_avg = r_sum / Grappa::cores();
          r.runtime_min = r_min;
          r.runtime_max = r_max;
        }
      });

      Grappa::Statistics::merge_and_print();

      BOOST_MESSAGE( "cores_time_avg = " << r.runtime_avg
                      << ", cores_time_max = " << r.runtime_max
                      << ", cores_time_min = " << r.runtime_min);
    }

  } else if (FLAGS_test_type.compare("sequential_updates")==0) {
    BOOST_MESSAGE( "Test sequential_updates" );
    {

      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values8 = new uint64_t[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
          // wait for all to start (to hack scheduler yield)
          task_barrier->complete();
          task_barrier->wait();

          // do the work
          for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            values8[t] += 1;
            Grappa_yield();
          }
          final->complete();
        });
      }

      final->wait();
      double end = Grappa_walltime();

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else if (FLAGS_test_type.compare("sequential_updates16")==0) {

    BOOST_MESSAGE( "Test sequential_updates16" );
    {
      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values16 = new SixteenBytes[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            values16[t].val1 += 1;
            values16[t].val2 += 1;
            Grappa_yield();
            }
            final->complete();
            });
      }

      final->wait();
      double end = Grappa_walltime();

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else if (FLAGS_test_type.compare("private_array")==0) {

    BOOST_MESSAGE( "Test private_array" );
    {
      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values8 = new uint64_t[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
            uint64_t myarray[FLAGS_private_array_size];

            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            for (uint64_t j=0; j<FLAGS_private_array_size; j++) {
            myarray[j] += 1;
            }
            Grappa_yield();
            }
            values8[t] = myarray[rand()%FLAGS_private_array_size];
            final->complete();
            });
      }

      final->wait();
      double end = Grappa_walltime();

      BOOST_MESSAGE( "result = " << values8[rand()%FLAGS_num_starting_workers] );

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else if (FLAGS_test_type.compare("private_array_bycache")==0) {

    BOOST_MESSAGE( "Test private_array_bycache" );
    {
      final = new CompletionEvent(FLAGS_num_starting_workers);
      task_barrier = new CompletionEvent(FLAGS_num_starting_workers);
      values8 = new uint64_t[FLAGS_num_starting_workers];

      double start = Grappa_walltime();

      for ( uint64_t t=0; t<FLAGS_num_starting_workers; t++ ) {
        privateTask( [t] {
            Cacheline myarray[FLAGS_private_array_size];

            // wait for all to start (to hack scheduler yield)
            task_barrier->complete();
            task_barrier->wait();

            // do the work
            for ( uint64_t i=0; i<FLAGS_iters_per_task; i++ ) {
            for (uint64_t j=0; j<FLAGS_private_array_size; j++) {
            myarray[j].val += 1;
            }
            Grappa_yield();
            }
            values8[t] = myarray[rand()%FLAGS_private_array_size].val;
            final->complete();
            });
      }

      final->wait();
      double end = Grappa_walltime();

      BOOST_MESSAGE( "result = " << values8[rand()%FLAGS_num_starting_workers] );

      double runtime = end-start;
      BOOST_MESSAGE( "time = " << runtime << ", avg_switch_time = " << runtime/(FLAGS_num_starting_workers*FLAGS_iters_per_task) );
    }
  } else {
    BOOST_CHECK( false ); // Unrecognized test_type
  }

  BOOST_MESSAGE( "user main is exiting" );
}

BOOST_AUTO_TEST_CASE( test1 ) {

  Grappa_init( &(boost::unit_test::framework::master_test_suite().argc),
                &(boost::unit_test::framework::master_test_suite().argv) );

  Grappa_activate();

  DVLOG(1) << "Spawning user main Thread....";
  Grappa_run_user_main( &user_main, (void*)NULL );
  VLOG(5) << "run_user_main returned";
  CHECK( Grappa_done() );

  Grappa_finish( 0 );
}

BOOST_AUTO_TEST_SUITE_END();

<|endoftext|>


<commit_before>/*
The MIT License (MIT)

Copyright (c) 2016 Liav Turkia and Shahar Sandhaus

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#define CATCH_CONFIG_RUNNER
#include <Catch.h>

int main(int argc, char* const argv[]) {
	//constant? get it?
	const int result = Catch::Session().run(argc, argv);

	system("pause");

	return result;
}
<commit_msg>Removed pause from testng<commit_after>/*
The MIT License (MIT)

Copyright (c) 2016 Liav Turkia and Shahar Sandhaus

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#define CATCH_CONFIG_RUNNER
#include <Catch.h>

int main(int argc, char* const argv[]) {
	//constant? get it?
	const int result = Catch::Session().run(argc, argv);

	return result;
}
<|endoftext|>


<commit_before>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "system_wrappers/interface/cpu_info.h"

#if defined(_WIN32)
#include <Windows.h>
#elif defined(WEBRTC_MAC)
#include <sys/sysctl.h>
#include <sys/types.h>
#elif defined(WEBRTC_ANDROID)
// Not implemented yet, might be possible to use Linux implementation
#else // defined(WEBRTC_LINUX)
#include <sys/sysinfo.h>
#endif

#include "trace.h"

namespace webrtc {

WebRtc_UWord32 CpuInfo::number_of_cores_ = 0;

WebRtc_UWord32 CpuInfo::DetectNumberOfCores() {
  if (!number_of_cores_) {
#if defined(_WIN32)
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    number_of_cores_ = static_cast<WebRtc_UWord32>(si.dwNumberOfProcessors);
    WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
                 "Available number of cores:%d", number_of_cores_);

#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
    number_of_cores_ = get_nprocs();
    WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
                 "Available number of cores:%d", number_of_cores_);

#elif defined(WEBRTC_MAC)
    int name[] = {CTL_HW, HW_AVAILCPU};
    int ncpu;
    size_t size = sizeof(ncpu);
    if (0 == sysctl(name, 2, &ncpu, &size, NULL, 0)) {
      number_of_cores_ = static_cast<WebRtc_UWord32>(ncpu);
      WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
                   "Available number of cores:%d", number_of_cores_);
    } else {
      WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
                   "Failed to get number of cores");
      number_of_cores_ = 1;
    }
#else
    WEBRTC_TRACE(kTraceWarning, kTraceUtility, -1,
                 "No function to get number of cores");
    number_of_cores_ = 1;
#endif
  }
  return number_of_cores_;
}

} // namespace webrtc
<commit_msg>compile fix for get_nprocs() with uClibc<commit_after>/*
 *  Copyright (c) 2011 The WebRTC project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */

#include "system_wrappers/interface/cpu_info.h"

#if defined(_WIN32)
#include <Windows.h>
#elif defined(WEBRTC_MAC)
#include <sys/sysctl.h>
#include <sys/types.h>
#elif defined(WEBRTC_ANDROID)
// Not implemented yet, might be possible to use Linux implementation
#else // defined(WEBRTC_LINUX)
#include <unistd.h>  // required for get_nprocs() with uClibc
#include <sys/sysinfo.h>
#endif

#include "trace.h"

namespace webrtc {

WebRtc_UWord32 CpuInfo::number_of_cores_ = 0;

WebRtc_UWord32 CpuInfo::DetectNumberOfCores() {
  if (!number_of_cores_) {
#if defined(_WIN32)
    SYSTEM_INFO si;
    GetSystemInfo(&si);
    number_of_cores_ = static_cast<WebRtc_UWord32>(si.dwNumberOfProcessors);
    WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
                 "Available number of cores:%d", number_of_cores_);

#elif defined(WEBRTC_LINUX) && !defined(WEBRTC_ANDROID)
    number_of_cores_ = get_nprocs();
    WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
                 "Available number of cores:%d", number_of_cores_);

#elif defined(WEBRTC_MAC)
    int name[] = {CTL_HW, HW_AVAILCPU};
    int ncpu;
    size_t size = sizeof(ncpu);
    if (0 == sysctl(name, 2, &ncpu, &size, NULL, 0)) {
      number_of_cores_ = static_cast<WebRtc_UWord32>(ncpu);
      WEBRTC_TRACE(kTraceStateInfo, kTraceUtility, -1,
                   "Available number of cores:%d", number_of_cores_);
    } else {
      WEBRTC_TRACE(kTraceError, kTraceUtility, -1,
                   "Failed to get number of cores");
      number_of_cores_ = 1;
    }
#else
    WEBRTC_TRACE(kTraceWarning, kTraceUtility, -1,
                 "No function to get number of cores");
    number_of_cores_ = 1;
#endif
  }
  return number_of_cores_;
}

} // namespace webrtc
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>

using namespace std;

template <typename T> class HeapSort {
    // make A[root] the max value of the subtree
    void heapify(vector<T> &A, int root, int end) {
        int max_val_idx = root;
        int left = 2 * root + 1, right = left + 1;

        if (left < end && A[left] > A[max_val_idx])
            max_val_idx = left;
        if (right < end && A[right] > A[max_val_idx])
            max_val_idx = right;

        if (max_val_idx != root) {
            swap(A[root], A[max_val_idx]);
            heapify(A, max_val_idx, end);
        }
    }

  public:
    void hs(vector<T> &A) {
        for(int i = A.size() / 2 - 1; i >= 0; --i)
            heapify(A, i, A.size());

        for(int i = A.size() - 1; i >= 0; --i) {
            swap(A[0], A[i]);
            heapify(A, 0, i);
        }
    }
};

int main() {
    vector<int> unsorted = {3, 2, 1, 5, 9, 7, 4};
    HeapSort<int> sorter;
    sorter.hs(unsorted);
    for (auto x : unsorted)
        cout << x << ' ';
    cout << endl;

    return 0;
}<commit_msg>update the comments to help understand better<commit_after>#include <iostream>
#include <vector>

using namespace std;

template <typename T> class HeapSort {
    // make A[root-end) a heap
    void heapify(vector<T> &A, int root, int end) {
        int left = 2 * root + 1, right = left + 1;

        int max_of_three = root; // max of root and its childs
        if (left < end && A[left] > A[max_of_three])
            max_of_three = left;
        if (right < end && A[right] > A[max_of_three])
            max_of_three = right;

        if (max_of_three != root) {
            swap(A[root], A[max_of_three]);
            heapify(A, max_of_three, end);
        }
    }

  public:
    void hs(vector<T> &A) {
        // pre-build whole vector as heap, O(n)
        for (int i = A.size() / 2 - 1; i >= 0; --i)
            heapify(A, i, A.size());

        // O(nlogn)
        // for each step:
        // select max, move down root to correct position
        for (int i = A.size() - 1; i >= 0; --i) {
            swap(A[0], A[i]);
            heapify(A, 0, i);
        }
    }
};

int main() {
    vector<int> unsorted = {3, 2, 1, 5, 9, 7, 4};
    HeapSort<int> sorter;
    sorter.hs(unsorted);

    for (auto x : unsorted)
        cout << x << ' ';
    cout << endl;

    return 0;
}<|endoftext|>


<commit_before>/*
  HarwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

extern "C" {
  #include <stdio.h>
  #include <string.h>
  #include <inttypes.h>
  #include "Serial.h"
}

#include "HardwareSerial.h"

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(uint8_t uart)
{
  if(uart == 0){
    _uart = 0;
  }else{
    _uart = 1;
  }
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(long speed)
{
  uart_init(_uart, speed);
}

uint8_t HardwareSerial::available(void)
{
  return uart_available(_uart);
}

int HardwareSerial::read(void)
{
  return uart_read(_uart);
}

void HardwareSerial::print(char c)
{
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(char c[])
{
  uart_write(_uart, c, strlen(c));
}

void HardwareSerial::print(uint8_t b)
{
  char c = b;
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(int n)
{
  print((long) n);
}

void HardwareSerial::print(long n)
{
  if (n < 0) {
    print('-');
    n = -n;
  }
  printNumber(n, 10);
}

void HardwareSerial::print(unsigned long n)
{
  printNumber(n, 10);
}

void HardwareSerial::print(long n, int base)
{
  if (base == 0)
    print((char) n);
  else if (base == 10)
    print(n);
  else
    printNumber(n, base);
}

void HardwareSerial::println(void)
{
  print('\n');
}

void HardwareSerial::println(char c)
{
  print(c);
  println();
}

void HardwareSerial::println(char c[])
{
  uart_write(_uart, c, strlen(c));
  println();
}

void HardwareSerial::println(uint8_t b)
{
  print(b);
  println();
}

void HardwareSerial::println(int n)
{
  println((long) n);
}

void HardwareSerial::println(long n)
{
  print(n);
  println();
}

void HardwareSerial::println(unsigned long n)
{
  print(n);
  println();
}

void HardwareSerial::println(long n, int base)
{
  print(n, base);
  println();
}

// Private Methods /////////////////////////////////////////////////////////////

void HardwareSerial::printNumber(unsigned long n, uint8_t base)
{
  uint8_t buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  int i = 0;
  if (n == 0) {
    print('0');
    return;
  }
  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }
  for (i--; i >= 0; i--){
    print((char)(buf[i] < 10 ? '0' + buf[i] : 'A' + buf[i] - 10));
  }
}

// Preinstantiate Objects //////////////////////////////////////////////////////

HardwareSerial Serial = HardwareSerial(0);
//HardwareSerial Serial1 = HardwareSerial(1);

<commit_msg>Serial.println() now sends '\r', '\n' (instead of just '\n')<commit_after>/*
  HarwareSerial.cpp - Hardware serial library for Wiring
  Copyright (c) 2006 Nicholas Zambetti.  All right reserved.

  This library is free software; you can redistribute it and/or
  modify it under the terms of the GNU Lesser General Public
  License as published by the Free Software Foundation; either
  version 2.1 of the License, or (at your option) any later version.

  This library is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  Lesser General Public License for more details.

  You should have received a copy of the GNU Lesser General Public
  License along with this library; if not, write to the Free Software
  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
*/

extern "C" {
  #include <stdio.h>
  #include <string.h>
  #include <inttypes.h>
  #include "Serial.h"
}

#include "HardwareSerial.h"

// Constructors ////////////////////////////////////////////////////////////////

HardwareSerial::HardwareSerial(uint8_t uart)
{
  if(uart == 0){
    _uart = 0;
  }else{
    _uart = 1;
  }
}

// Public Methods //////////////////////////////////////////////////////////////

void HardwareSerial::begin(long speed)
{
  uart_init(_uart, speed);
}

uint8_t HardwareSerial::available(void)
{
  return uart_available(_uart);
}

int HardwareSerial::read(void)
{
  return uart_read(_uart);
}

void HardwareSerial::print(char c)
{
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(char c[])
{
  uart_write(_uart, c, strlen(c));
}

void HardwareSerial::print(uint8_t b)
{
  char c = b;
  uart_write(_uart, &c, 1);
}

void HardwareSerial::print(int n)
{
  print((long) n);
}

void HardwareSerial::print(long n)
{
  if (n < 0) {
    print('-');
    n = -n;
  }
  printNumber(n, 10);
}

void HardwareSerial::print(unsigned long n)
{
  printNumber(n, 10);
}

void HardwareSerial::print(long n, int base)
{
  if (base == 0)
    print((char) n);
  else if (base == 10)
    print(n);
  else
    printNumber(n, base);
}

void HardwareSerial::println(void)
{
  print('\r');
  print('\n');
}

void HardwareSerial::println(char c)
{
  print(c);
  println();
}

void HardwareSerial::println(char c[])
{
  uart_write(_uart, c, strlen(c));
  println();
}

void HardwareSerial::println(uint8_t b)
{
  print(b);
  println();
}

void HardwareSerial::println(int n)
{
  println((long) n);
}

void HardwareSerial::println(long n)
{
  print(n);
  println();
}

void HardwareSerial::println(unsigned long n)
{
  print(n);
  println();
}

void HardwareSerial::println(long n, int base)
{
  print(n, base);
  println();
}

// Private Methods /////////////////////////////////////////////////////////////

void HardwareSerial::printNumber(unsigned long n, uint8_t base)
{
  uint8_t buf[8 * sizeof(long)]; // Assumes 8-bit chars.
  int i = 0;
  if (n == 0) {
    print('0');
    return;
  }
  while (n > 0) {
    buf[i++] = n % base;
    n /= base;
  }
  for (i--; i >= 0; i--){
    print((char)(buf[i] < 10 ? '0' + buf[i] : 'A' + buf[i] - 10));
  }
}

// Preinstantiate Objects //////////////////////////////////////////////////////

HardwareSerial Serial = HardwareSerial(0);
//HardwareSerial Serial1 = HardwareSerial(1);

<|endoftext|>


<commit_before>#include <red_black_tree.hpp>
#include <catch.hpp>

SCENARIO("default constructor")
{
	RedBlackTree<int> rbt;
	REQUIRE(rbt._root() == rbt._NIL());
}

SCENARIO("insert")
{
  RedBlackTree<int> rbt;
  rbt.insert(5);
  REQUIRE(rbt.findElement(5) != 0);
}

SCENARIO("insert2", "[init]")
{
  RedBlackTree<int> rbt;
  rbt.insert(2);
  rbt.insert(3);
  rbt.insert(4);
  REQUIRE(tree._root() == tree.findElement(3));
  REQUIRE(tree._color(3) == 1);
  REQUIRE(tree._color(2) == 0);
  REQUIRE(tree._color(4) == 0);
  REQUIRE(tree.findElement(2) != 0);
  REQUIRE(tree.findElement(3) != 0);
  REQUIRE(tree.findElement(4) != 0);
}
<commit_msg>Create init.cpp<commit_after>#include <red_black_tree.hpp>
#include <catch.hpp>

SCENARIO("default constructor")
{
	RedBlackTree<int> rbt;
	REQUIRE(rbt._root() == rbt._NIL());
}

SCENARIO("insert")
{
  RedBlackTree<int> rbt;
  rbt.insert(5);
  REQUIRE(rbt.findElement(5) != 0);
}

SCENARIO("insert2", "[init]")
{
  RedBlackTree<int> rbt;
  rbt.insert(2);
  rbt.insert(3);
  rbt.insert(4);
  REQUIRE(rbt._root() == rbt.findElement(3));
  REQUIRE(rbt._color(3) == 1);
  REQUIRE(rbt._color(2) == 0);
  REQUIRE(rbt._color(4) == 0);
  REQUIRE(rbt.findElement(2) != 0);
  REQUIRE(rbt.findElement(3) != 0);
  REQUIRE(rbt.findElement(4) != 0);
}
<|endoftext|>


<commit_before>#include <binary_search_tree.hpp>
#include <catch.hpp>

SCENARIO("default constructor")
{
	BinarySearchTree<int> bst;
	REQUIRE(bst.root() == nullptr);
	REQUIRE(bst.count() == 0);
}

<commit_msg>Update init.cpp<commit_after>#include <binary_search_tree.hpp>
#include <catch.hpp>

SCENARIO("default constructor")
{
	BinarySearchTree<int> bst;
	REQUIRE(bst.root() == nullptr);
	REQUIRE(bst.count() == 0);
}

SCENARIO("insertElement")
{
	BinarySearchTree<int> bst;
	bst.insert(7);
	REQUIRE(bst.findElement() == 7);
	REQUIRE(bst.count() == 1);
}
<|endoftext|>


<commit_before>// Copyright (c) 2019 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "mfx_common.h"
#if defined(MFX_ENABLE_H265_VIDEO_ENCODE)

#include "hevcehw_g12_caps.h"

using namespace HEVCEHW;
using namespace HEVCEHW::Gen12;

void Caps::Query1NoCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push)
{
    Push(BLK_SetDefaultsCallChain,
        [this](const mfxVideoParam&, mfxVideoParam&, StorageRW& strg) -> mfxStatus
    {
        auto& defaults = Glob::Defaults::GetOrConstruct(strg);
        auto& bSet = defaults.SetForFeature[GetID()];
        MFX_CHECK(!bSet, MFX_ERR_NONE);

        defaults.GetMaxNumRef.Push([](
            Gen9::Defaults::TChain<std::tuple<mfxU16, mfxU16>>::TExt
            , const Gen9::Defaults::Param& dpar)
        {
            const mfxU16 nRef[3][2][7] =
            {
                {   // VME
                    { 4, 4, 3, 3, 3, 1, 1 },
                    { 2, 2, 1, 1, 1, 1, 1 }
                },
                {   // VDENC P
                    { 3, 3, 2, 2, 2, 1, 1 },
                    { 3, 3, 2, 2, 2, 1, 1 }
                },
                {   // Gen12 VDENC RA B
                    { 2, 2, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 }
                }
            };
            bool    bBFrames = (dpar.mvp.mfx.GopRefDist > 1);
            bool    bVDEnc   = IsOn(dpar.mvp.mfx.LowPower);
            mfxU16  tu       = dpar.mvp.mfx.TargetUsage;
            mfxU32  idx      = bVDEnc * (1 + bBFrames);

            CheckRangeOrSetDefault<mfxU16>(tu, 1, 7, 4);
            --tu;

            return std::make_tuple(
                std::min<mfxU16>(nRef[idx][0][tu], dpar.caps.MaxNum_Reference0)
                , std::min<mfxU16>(nRef[idx][1][tu], dpar.caps.MaxNum_Reference1));
        });

        bSet = true;

        return MFX_ERR_NONE;
    });
}

void Caps::Query1WithCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push)
{
    Push(BLK_HardcodeCaps
        , [this](const mfxVideoParam&, mfxVideoParam& par, StorageRW& strg) -> mfxStatus
    {
        auto& caps = Glob::EncodeCaps::Get(strg);

        caps.SliceIPOnly                = IsOn(par.mfx.LowPower) && (par.mfx.TargetUsage == 7);
        caps.msdk.bSingleSliceMultiTile = false;

        caps.YUV422ReconSupport |= (!caps.Color420Only && IsOff(par.mfx.LowPower));

        SetSpecificCaps(caps);

        return MFX_ERR_NONE;
    });
}

#endif //defined(MFX_ENABLE_H265_VIDEO_ENCODE)
<commit_msg>[HEVCe-r] Corrected def. num. ref. list. calc. on TGL+<commit_after>// Copyright (c) 2019-2020 Intel Corporation
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

#include "mfx_common.h"
#if defined(MFX_ENABLE_H265_VIDEO_ENCODE)

#include "hevcehw_g12_caps.h"

using namespace HEVCEHW;
using namespace HEVCEHW::Gen12;

void Caps::Query1NoCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push)
{
    Push(BLK_SetDefaultsCallChain,
        [this](const mfxVideoParam&, mfxVideoParam&, StorageRW& strg) -> mfxStatus
    {
        auto& defaults = Glob::Defaults::GetOrConstruct(strg);
        auto& bSet = defaults.SetForFeature[GetID()];
        MFX_CHECK(!bSet, MFX_ERR_NONE);

        defaults.GetMaxNumRef.Push([](
            Gen9::Defaults::TChain<std::tuple<mfxU16, mfxU16>>::TExt
            , const Gen9::Defaults::Param& dpar)
        {
            const mfxU16 nRef[3][2][7] =
            {
                {   // VME
                    { 4, 4, 3, 3, 3, 1, 1 },
                    { 2, 2, 1, 1, 1, 1, 1 }
                },
                {   // VDENC P
                    { 3, 3, 2, 2, 2, 1, 1 },
                    { 3, 3, 2, 2, 2, 1, 1 }
                },
                {   // Gen12 VDENC RA B
                    { 2, 2, 1, 1, 1, 1, 1 },
                    { 1, 1, 1, 1, 1, 1, 1 }
                }
            };
            bool    bBFrames = (dpar.mvp.mfx.GopRefDist > 1);
            bool    bVDEnc   = IsOn(dpar.mvp.mfx.LowPower);
            mfxU16  tu       = dpar.mvp.mfx.TargetUsage;
            mfxU32  idx      = bVDEnc * (1 + bBFrames);

            CheckRangeOrSetDefault<mfxU16>(tu, 1, 7, 4);
            --tu;

            /* Same way like on Gen9 or Gen11 platforms */
            mfxU16 numRefFrame = dpar.mvp.mfx.NumRefFrame + !dpar.mvp.mfx.NumRefFrame * 16;

            return std::make_tuple(
                std::min<mfxU16>(nRef[idx][0][tu], std::min<mfxU16>(dpar.caps.MaxNum_Reference0, numRefFrame))
                , std::min<mfxU16>(nRef[idx][1][tu], std::min<mfxU16>(dpar.caps.MaxNum_Reference1, numRefFrame)));
        });

        bSet = true;

        return MFX_ERR_NONE;
    });
}

void Caps::Query1WithCaps(const FeatureBlocks& /*blocks*/, TPushQ1 Push)
{
    Push(BLK_HardcodeCaps
        , [this](const mfxVideoParam&, mfxVideoParam& par, StorageRW& strg) -> mfxStatus
    {
        auto& caps = Glob::EncodeCaps::Get(strg);

        caps.SliceIPOnly                = IsOn(par.mfx.LowPower) && (par.mfx.TargetUsage == 7);
        caps.msdk.bSingleSliceMultiTile = false;

        caps.YUV422ReconSupport |= (!caps.Color420Only && IsOff(par.mfx.LowPower));

        SetSpecificCaps(caps);

        return MFX_ERR_NONE;
    });
}

#endif //defined(MFX_ENABLE_H265_VIDEO_ENCODE)
<|endoftext|>


<commit_before>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

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.
==============================================================================*/

#include <fcntl.h>
#ifndef _WIN32
#include <sys/mman.h>
#else
#include <windows.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "tensorflow/lite/allocation.h"
#include "tensorflow/lite/core/api/error_reporter.h"

namespace tflite {

#ifdef _WIN32
static constexpr void* MAP_FAILED = nullptr;

MMAPAllocation::MMAPAllocation(const char* filename,
                               ErrorReporter* error_reporter)
    : Allocation(error_reporter)
    , mmapped_buffer_(MAP_FAILED)
    , file_handle_( nullptr )
    , file_mapping_( nullptr ) {

  file_handle_ = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
  if (file_handle_ == INVALID_HANDLE_VALUE) {
    error_reporter_->Report("Could not open '%s'.", filename);
    return;
  }

  buffer_size_bytes_ = GetFileSize( file_handle_, nullptr );

  file_mapping_ = CreateFileMapping(file_handle_, NULL, PAGE_READONLY, 0, 0, NULL);
  if (file_mapping_ == NULL)
    return;

  mmapped_buffer_ = MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, buffer_size_bytes_);

  if (mmapped_buffer_ == MAP_FAILED) {
    error_reporter_->Report("Mmap of '%s' failed.", filename);
    return;
  }
}

MMAPAllocation::~MMAPAllocation() {
   if (valid()) {
     UnmapViewOfFile( mmapped_buffer_ );
   }

   if (file_mapping_ != nullptr) {
    CloseHandle( file_mapping_ );
   }

   if (file_handle_ != nullptr){
    CloseHandle( file_handle_ );
   }

}

#else
MMAPAllocation::MMAPAllocation(const char* filename,
                               ErrorReporter* error_reporter)
    : Allocation(error_reporter), mmapped_buffer_(MAP_FAILED) {
  mmap_fd_ = open(filename, O_RDONLY);
  if (mmap_fd_ == -1) {
    error_reporter_->Report("Could not open '%s'.", filename);
    return;
  }
  struct stat sb;
  fstat(mmap_fd_, &sb);
  buffer_size_bytes_ = sb.st_size;
  mmapped_buffer_ =
      mmap(nullptr, buffer_size_bytes_, PROT_READ, MAP_SHARED, mmap_fd_, 0);
  if (mmapped_buffer_ == MAP_FAILED) {
    error_reporter_->Report("Mmap of '%s' failed.", filename);
    return;
  }
}

MMAPAllocation::~MMAPAllocation() {
  if (valid()) {
    munmap(const_cast<void*>(mmapped_buffer_), buffer_size_bytes_);
  }
  if (mmap_fd_ != -1) close(mmap_fd_);
}
#endif

const void* MMAPAllocation::base() const { return mmapped_buffer_; }

size_t MMAPAllocation::bytes() const { return buffer_size_bytes_; }

bool MMAPAllocation::valid() const { return mmapped_buffer_ != MAP_FAILED; }

bool MMAPAllocation::IsSupported() { return true; }

}  // namespace tflite
<commit_msg>Use nullptr<commit_after>/* Copyright 2018 The TensorFlow Authors. All Rights Reserved.

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.
==============================================================================*/

#include <fcntl.h>
#ifndef _WIN32
#include <sys/mman.h>
#else
#include <windows.h>
#endif
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include "tensorflow/lite/allocation.h"
#include "tensorflow/lite/core/api/error_reporter.h"

namespace tflite {

#ifdef _WIN32
static constexpr void* MAP_FAILED = nullptr;

MMAPAllocation::MMAPAllocation(const char* filename,
                               ErrorReporter* error_reporter)
    : Allocation(error_reporter)
    , mmapped_buffer_(MAP_FAILED)
    , file_handle_(nullptr)
    , file_mapping_(nullptr) {

  file_handle_ = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, 0);
  if (file_handle_ == INVALID_HANDLE_VALUE) {
    error_reporter_->Report("Could not open '%s'.", filename);
    return;
  }

  buffer_size_bytes_ = GetFileSize( file_handle_, nullptr );

  file_mapping_ = CreateFileMapping(file_handle_, NULL, PAGE_READONLY, 0, 0, NULL);
  if (file_mapping_ == nullptr)
    return;

  mmapped_buffer_ = MapViewOfFile(file_mapping_, FILE_MAP_READ, 0, 0, buffer_size_bytes_);

  if (mmapped_buffer_ == MAP_FAILED) {
    error_reporter_->Report("Mmap of '%s' failed.", filename);
    return;
  }
}

MMAPAllocation::~MMAPAllocation() {
  if (valid()) {
     UnmapViewOfFile( mmapped_buffer_ );
  }

  if (file_mapping_ != nullptr) {
    CloseHandle( file_mapping_ );
  }

  if (file_handle_ != nullptr){
    CloseHandle(file_handle_);
  }
}

#else
MMAPAllocation::MMAPAllocation(const char* filename,
                               ErrorReporter* error_reporter)
    : Allocation(error_reporter), mmapped_buffer_(MAP_FAILED) {
  mmap_fd_ = open(filename, O_RDONLY);
  if (mmap_fd_ == -1) {
    error_reporter_->Report("Could not open '%s'.", filename);
    return;
  }
  struct stat sb;
  fstat(mmap_fd_, &sb);
  buffer_size_bytes_ = sb.st_size;
  mmapped_buffer_ =
      mmap(nullptr, buffer_size_bytes_, PROT_READ, MAP_SHARED, mmap_fd_, 0);
  if (mmapped_buffer_ == MAP_FAILED) {
    error_reporter_->Report("Mmap of '%s' failed.", filename);
    return;
  }
}

MMAPAllocation::~MMAPAllocation() {
  if (valid()) {
    munmap(const_cast<void*>(mmapped_buffer_), buffer_size_bytes_);
  }
  if (mmap_fd_ != -1) close(mmap_fd_);
}
#endif

const void* MMAPAllocation::base() const { return mmapped_buffer_; }

size_t MMAPAllocation::bytes() const { return buffer_size_bytes_; }

bool MMAPAllocation::valid() const { return mmapped_buffer_ != MAP_FAILED; }

bool MMAPAllocation::IsSupported() { return true; }

}  // namespace tflite
<|endoftext|>


<commit_before>#ifndef SMARTPOINTERS_HPP_
#define SMARTPOINTERS_HPP_

#define NOMINMAX // Removes windows min and max macros
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include "FAST/Exception.hpp"
#include "FAST/Reporter.hpp"
#include "FAST/Paths.hpp"

#define FAST_OBJECT(className)                                  \
    public:                                                     \
        typedef SharedPointer<className> pointer;               \
        static SharedPointer<className> New() {                       \
            className * ptr = new className();                  \
            SharedPointer<className> smartPtr(ptr);                   \
            ptr->setPtr(smartPtr);                              \
                                                                \
            return smartPtr;                                    \
        }                                                       \
        virtual std::string getNameOfClass() const {            \
            return std::string(#className);                     \
        };                                                      \
        static std::string getStaticNameOfClass() {             \
            return std::string(#className);                     \
        };                                                      \
    private:                                                    \
        void setPtr(className::pointer ptr) {                   \
            mPtr = ptr;                                         \
        }                                                       \

namespace fast {

template <class T>
class SharedPointer;

template <class T>
class WeakPointer {
    public:
        WeakPointer() {};
        WeakPointer(const SharedPointer<T> object) {
            mWeakPtr = object.getPtr();
        }
        SharedPointer<T> lock() const {
            return SharedPointer<T>(mWeakPtr.lock());
        };
        boost::weak_ptr<T> getPtr() const { return mWeakPtr; };
        WeakPointer<T> &operator=(const SharedPointer<T> &other);
        bool operator==(const WeakPointer<T> &other) const {
            // Check if the two weak pointers, point to the same objecs
            SharedPointer<T> object1 = mWeakPtr.lock();
            SharedPointer<T> object2 = other.lock();
            if(object1.isValid() && object2.isValid()) {
                return object1 == object2;
            } else {
                return false;
            }
        }
    private:
        boost::weak_ptr<T> mWeakPtr;

};

class Object;

template <class T>
class SharedPointer {
    public:
        SharedPointer() {

        }
		SharedPointer(T* object) {
            mSmartPtr = boost::shared_ptr<T>(object);
        }
        template <class D>
        SharedPointer(T* p, D d) {
        	mSmartPtr = boost::shared_ptr<T>(p, d);
        }

        template <class U>
        SharedPointer(boost::shared_ptr<U> sharedPtr) {
            mSmartPtr = boost::dynamic_pointer_cast<T>(sharedPtr);
        }

        template <class U>
        SharedPointer(SharedPointer<U> object) {
            if(!object.isValid())
                throw Exception("Cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass() + " failed because object was invalid (uninitialized or deleted).");
            boost::shared_ptr<T> ptr = boost::dynamic_pointer_cast<T>(object.getPtr());
            if(ptr == NULL)
                throw Exception("Illegal cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass());
            mSmartPtr = boost::shared_ptr<T>(ptr);
        }
        template <class U>
        SharedPointer(WeakPointer<U> object) {
            if(!object.isValid())
                throw Exception("Cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass() + " failed because object was invalid (uninitialized or deleted).");
            boost::shared_ptr<T> ptr = boost::dynamic_pointer_cast<T>(object.getPtr().lock());
            if(ptr == NULL)
                throw Exception("Illegal cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass());
            mSmartPtr = boost::shared_ptr<T>(ptr);
        }

        template <class U>
        SharedPointer<T> &operator=(const SharedPointer<U> &other) {
            if(!other.isValid())
                throw Exception("Cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass() + " failed because object was invalid (uninitialized or deleted).");
            boost::shared_ptr<T> ptr = boost::dynamic_pointer_cast<T>(other.getPtr());
            if(ptr == NULL)
                throw Exception("Illegal cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass());
            mSmartPtr = boost::shared_ptr<T>(ptr);
            return *this;
        }

        template <class U>
        void swap(SharedPointer<U> &other) {
            mSmartPtr.swap(other.getReferenceToPointer());
        }

        bool isValid() const {
            // Check if smart pointer actually points to something
            return mSmartPtr.get() != NULL;
        }

        operator unsigned long int() const {
            return (unsigned long int)mSmartPtr.get();
        }

        bool operator==(const SharedPointer<T> &other) {
            return this->getPtr() == other.getPtr();
        }

        T* operator->() {
        	return mSmartPtr.get();
		}
        T* operator->() const {
        	return mSmartPtr.get();
		}
        T* get() {
        	return mSmartPtr.get();
        }

        boost::shared_ptr<T> getPtr() const { return mSmartPtr; };
        boost::shared_ptr<T> & getReferenceToPointer() { return mSmartPtr; };
    private:
        boost::shared_ptr<T> mSmartPtr;

};

template <class T>
using UniquePointer = std::unique_ptr<T>;

template <class T>
WeakPointer<T> &WeakPointer<T>::operator=(const SharedPointer<T> &other) {
    mWeakPtr = other.getPtr();
    return *this;
}

} // end namespace fast

// A custum boost hashing function for the SharedPointers so that they can be used
// in unordered data structures. TODO verify that this works
namespace boost {
template <class U>
std::size_t hash_value(fast::SharedPointer<U> const& obj) {
    return (std::size_t)obj.getPtr().get();
}
template <class U>
std::size_t hash_value(fast::WeakPointer<U> const& obj) {
    return (std::size_t)obj.lock().getPtr().get();
}
}

#endif /* SMARTPOINTERS_HPP_ */
<commit_msg>Switched to using shared_ptr and weak_ptr from std instead of boost<commit_after>#ifndef SMARTPOINTERS_HPP_
#define SMARTPOINTERS_HPP_

#define NOMINMAX // Removes windows min and max macros
#include <boost/shared_ptr.hpp>
#include <boost/weak_ptr.hpp>
#include "FAST/Exception.hpp"
#include "FAST/Reporter.hpp"
#include "FAST/Paths.hpp"

#define FAST_OBJECT(className)                                  \
    public:                                                     \
        typedef SharedPointer<className> pointer;               \
        static SharedPointer<className> New() {                       \
            className * ptr = new className();                  \
            SharedPointer<className> smartPtr(ptr);                   \
            ptr->setPtr(smartPtr);                              \
                                                                \
            return smartPtr;                                    \
        }                                                       \
        virtual std::string getNameOfClass() const {            \
            return std::string(#className);                     \
        };                                                      \
        static std::string getStaticNameOfClass() {             \
            return std::string(#className);                     \
        };                                                      \
    private:                                                    \
        void setPtr(className::pointer ptr) {                   \
            mPtr = ptr;                                         \
        }                                                       \

namespace fast {

template <class T>
class SharedPointer;

template <class T>
class WeakPointer {
    public:
        WeakPointer() {};
        WeakPointer(const SharedPointer<T> object) {
            mWeakPtr = object.getPtr();
        }
        SharedPointer<T> lock() const {
            return SharedPointer<T>(mWeakPtr.lock());
        };
        std::weak_ptr<T> getPtr() const { return mWeakPtr; };
        WeakPointer<T> &operator=(const SharedPointer<T> &other);
        bool operator==(const WeakPointer<T> &other) const {
            // Check if the two weak pointers, point to the same objecs
            SharedPointer<T> object1 = mWeakPtr.lock();
            SharedPointer<T> object2 = other.lock();
            if(object1.isValid() && object2.isValid()) {
                return object1 == object2;
            } else {
                return false;
            }
        }
    private:
        std::weak_ptr<T> mWeakPtr;

};

class Object;

template <class T>
class SharedPointer {
    public:
        SharedPointer() {

        }
		SharedPointer(T* object) {
            mSmartPtr = std::shared_ptr<T>(object);
        }
        template <class D>
        SharedPointer(T* p, D d) {
        	mSmartPtr = std::shared_ptr<T>(p, d);
        }

        template <class U>
        SharedPointer(std::shared_ptr<U> sharedPtr) {
            mSmartPtr = std::dynamic_pointer_cast<T>(sharedPtr);
        }

        template <class U>
        SharedPointer(SharedPointer<U> object) {
            if(!object.isValid())
                throw Exception("Cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass() + " failed because object was invalid (uninitialized or deleted).");
            std::shared_ptr<T> ptr = std::dynamic_pointer_cast<T>(object.getPtr());
            if(ptr == NULL)
                throw Exception("Illegal cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass());
            mSmartPtr = std::shared_ptr<T>(ptr);
        }
        template <class U>
        SharedPointer(WeakPointer<U> object) {
            if(!object.isValid())
                throw Exception("Cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass() + " failed because object was invalid (uninitialized or deleted).");
            std::shared_ptr<T> ptr = std::dynamic_pointer_cast<T>(object.getPtr().lock());
            if(ptr == NULL)
                throw Exception("Illegal cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass());
            mSmartPtr = std::shared_ptr<T>(ptr);
        }

        template <class U>
        SharedPointer<T> &operator=(const SharedPointer<U> &other) {
            if(!other.isValid())
                throw Exception("Cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass() + " failed because object was invalid (uninitialized or deleted).");
            std::shared_ptr<T> ptr = std::dynamic_pointer_cast<T>(other.getPtr());
            if(ptr == NULL)
                throw Exception("Illegal cast from " + U::getStaticNameOfClass() + " to " + T::getStaticNameOfClass());
            mSmartPtr = std::shared_ptr<T>(ptr);
            return *this;
        }

        template <class U>
        void swap(SharedPointer<U> &other) {
            mSmartPtr.swap(other.getReferenceToPointer());
        }

        bool isValid() const {
            // Check if smart pointer actually points to something
            return mSmartPtr.get() != NULL;
        }

        operator unsigned long int() const {
            return (unsigned long int)mSmartPtr.get();
        }

        bool operator==(const SharedPointer<T> &other) {
            return this->getPtr() == other.getPtr();
        }

        T* operator->() {
        	return mSmartPtr.get();
		}
        T* operator->() const {
        	return mSmartPtr.get();
		}
        T* get() {
        	return mSmartPtr.get();
        }

        std::shared_ptr<T> getPtr() const { return mSmartPtr; };
        std::shared_ptr<T> & getReferenceToPointer() { return mSmartPtr; };
    private:
        std::shared_ptr<T> mSmartPtr;

};

template <class T>
using UniquePointer = std::unique_ptr<T>;

template <class T>
WeakPointer<T> &WeakPointer<T>::operator=(const SharedPointer<T> &other) {
    mWeakPtr = other.getPtr();
    return *this;
}

} // end namespace fast

// A custum boost hashing function for the SharedPointers so that they can be used
// in unordered data structures. TODO verify that this works
namespace boost {
template <class U>
std::size_t hash_value(fast::SharedPointer<U> const& obj) {
    return (std::size_t)obj.getPtr().get();
}
template <class U>
std::size_t hash_value(fast::WeakPointer<U> const& obj) {
    return (std::size_t)obj.lock().getPtr().get();
}
}

#endif /* SMARTPOINTERS_HPP_ */
<|endoftext|>