<commit_before>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_EXAMPLES_LINEARELLIPTIC_OS2014_HH
#define DUNE_HDD_EXAMPLES_LINEARELLIPTIC_OS2014_HH

#define DUNE_HDD_LINEARELLIPTIC_TESTCASES_BASE_DISABLE_WARNING

#include <boost/numeric/conversion/cast.hpp>

#include <dune/fem/misc/mpimanager.hh>

#include <dune/stuff/common/logging.hh>
#include <dune/stuff/functions/expression.hh>

#include <dune/pymor/parameters/base.hh>

#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/operators/projections.hh>
#include <dune/gdt/operators/prolongations.hh>
#include <dune/gdt/playground/products/elliptic-swipdg.hh>

#include <dune/hdd/linearelliptic/testcases/OS2014.hh>
#include <dune/hdd/linearelliptic/testcases/spe10.hh>
#include <dune/hdd/linearelliptic/discretizations/block-swipdg.hh>
#include <dune/hdd/linearelliptic/estimators/block-swipdg.hh>

namespace internal {

class Initializer
{
public:
  Initializer(const ssize_t info_log_levels,
              const ssize_t debug_log_levels,
              const bool enable_warnings,
              const bool enable_colors,
              const std::string info_color,
              const std::string debug_color,
              const std::string warn_color)
  {
    try {
      int argc = 0;
      char** argv = new char* [0];
      Dune::Fem::MPIManager::initialize(argc, argv);
    } catch (...) {}
    DSC::TimedLogger().create(info_log_levels,
                              debug_log_levels,
                              enable_warnings,
                              enable_colors,
                              info_color,
                              debug_color,
                              warn_color);
    DSC::TimedLogger().get("OS2014.initializer").info() << "creating grid and problem... " << std::endl;
  }
}; // class Initializer

template< class TestCaseType >
class Example
  : Initializer
{
public:
  typedef typename TestCaseType::GridType GridType;
  typedef double RangeFieldType;
  typedef Dune::HDD::LinearElliptic::Discretizations::BlockSWIPDG< GridType, RangeFieldType, 1 > DiscretizationType;
  typedef typename DiscretizationType::VectorType VectorType;

private:
  typedef Dune::HDD::LinearElliptic::Estimators::BlockSWIPDG< typename DiscretizationType::AnsatzSpaceType,
                                                              VectorType,
                                                              typename DiscretizationType::ProblemType,
                                                              GridType > Estimator;

public:
  Example(const std::string partitioning = "[1 1 1]",
          const DUNE_STUFF_SSIZE_T num_refinements = 0,
          const std::vector< std::string > products = {},
          const ssize_t info_log_levels  = 0,
          const ssize_t debug_log_levels = -1,
          const bool enable_warnings = true,
          const bool enable_colors   = true,
          const std::string info_color  = DSC::TimedLogging::default_info_color(),
          const std::string debug_color = DSC::TimedLogging::default_debug_color(),
          const std::string warn_color  = DSC::TimedLogging::default_warning_color())
    : Initializer(info_log_levels,
                  debug_log_levels,
                  enable_warnings,
                  enable_colors,
                  info_color,
                  debug_color,
                  warn_color)
    , test_case_({{"mu", Dune::Pymor::Parameter("mu", 1)},     // <- it does not matter which parameters we give to the
                  {"mu_hat", Dune::Pymor::Parameter("mu", 1)}, //    test case here, since we use test_case_.problem()
                  {"mu_bar", Dune::Pymor::Parameter("mu", 1)}, //    (which is the parametric problem) anyway
                  {"mu_minimizing", Dune::Pymor::Parameter("mu", 1)}},
                 partitioning,
                 boost::numeric_cast< size_t >(num_refinements))
    , reference_test_case_({{"mu", Dune::Pymor::Parameter("mu", 1)},
                            {"mu_hat", Dune::Pymor::Parameter("mu", 1)},
                            {"mu_bar", Dune::Pymor::Parameter("mu", 1)},
                            {"mu_minimizing", Dune::Pymor::Parameter("mu", 1)}},
                           partitioning,
                           boost::numeric_cast< size_t >(num_refinements + 1))
    , discretization_(*test_case_.reference_provider(),
                      test_case_.boundary_info(),
                      test_case_.problem(),
                      products)
    , reference_discretization_(*reference_test_case_.reference_provider(),
                                reference_test_case_.boundary_info(),
                                reference_test_case_.problem(),
                                products)
  {
    auto logger = DSC::TimedLogger().get("OS2014.example");
    logger.info() << "initializing discretization... " << std::flush;
    discretization_.init();
    reference_discretization_.init();
    logger.info() << "done (grid has " << discretization_.grid_view().indexSet().size(0)
                  << " elements, discretization has " << discretization_.ansatz_space()->mapper().size() << " DoFs)"
                  << std::endl;
  } // ... OS2014Spe10Model1Example(...)

  const TestCaseType& test_case() const
  {
    return test_case_;
  }

  DiscretizationType& discretization()
  {
    return discretization_;
  }

  DiscretizationType* discretization_and_return_ptr() const
  {
    return new DiscretizationType(discretization_);
  }

  VectorType project(const std::string expression) const
  {
    using namespace Dune;
    typedef typename DiscretizationType::AnsatzSpaceType AnsatzSpaceType;
    typedef GDT::DiscreteFunction< AnsatzSpaceType, VectorType > DiscreteFunctionType;
    DiscreteFunctionType discrete_function(*discretization_.ansatz_space());

    typedef Stuff::Functions::Expression< typename DiscreteFunctionType::EntityType,
                                          typename DiscreteFunctionType::DomainFieldType,
                                          DiscreteFunctionType::dimDomain,
                                          typename DiscreteFunctionType::RangeFieldType,
                                          DiscreteFunctionType::dimRange > ExpressionFunctionType;
    ExpressionFunctionType func("x", expression);

    GDT::Operators::Projection< typename DiscretizationType::GridViewType > projection(discretization_.grid_view());
    projection.apply(func, discrete_function);

    return discrete_function.vector();
  } // ... project(...)

  RangeFieldType compute_error(const VectorType& solution,
                               const std::string product_type = "",
                               const Dune::Pymor::Parameter mu = Dune::Pymor::Parameter(),
                               const Dune::Pymor::Parameter mu_product = Dune::Pymor::Parameter())
  {
    const std::string type = (product_type.empty() && reference_discretization_.available_products().size() == 1)
                             ? reference_discretization_.available_products()[0]
                             : product_type;
    // wrap solution into a discrete function
    using namespace Dune;
    typedef typename DiscretizationType::AnsatzSpaceType AnsatzSpaceType;
    typedef GDT::ConstDiscreteFunction< AnsatzSpaceType, VectorType > ConstDiscreteFunctionType;
    ConstDiscreteFunctionType coarse_solution(*discretization_.ansatz_space(), solution);
    // prolong to reference grid view
    typedef GDT::DiscreteFunction< AnsatzSpaceType, VectorType > DiscreteFunctionType;
    DiscreteFunctionType fine_solution(*reference_discretization_.ansatz_space());
    GDT::Operators::Prolongation< typename DiscretizationType::GridViewType >
        prolongation_operator(reference_discretization_.grid_view());
    prolongation_operator.apply(coarse_solution, fine_solution);
    // compute reference solution
    DiscreteFunctionType reference_solution(*reference_discretization_.ansatz_space());
    reference_discretization_.solve(reference_solution.vector(), mu);
    // compute error
    const auto product = reference_discretization_.get_product(type).freeze_parameter(mu_product);
    const auto difference = reference_solution.vector() - fine_solution.vector();
    return std::sqrt(product.apply2(difference, difference));
  } // ... compute_error(...)

  RangeFieldType compute_jump_norm(const VectorType& solution_vector,
                                   const Dune::Pymor::Parameter mu_product = Dune::Pymor::Parameter())
  {
    using namespace Dune;
    typedef typename DiscretizationType::AnsatzSpaceType AnsatzSpaceType;
    typedef GDT::ConstDiscreteFunction< AnsatzSpaceType, VectorType > ConstDiscreteFunctionType;
    ConstDiscreteFunctionType solution(*discretization_.ansatz_space(), solution_vector);
    const auto diffusion_factor = discretization_.problem().diffusion_factor()->with_mu(mu_product);
    const auto diffusion_tensor = discretization_.problem().diffusion_tensor()->with_mu(mu_product);
    typedef GDT::Products::EllipticSWIPDGPenaltyLocalizable
        < typename DiscretizationType::GridViewType,
          typename DiscretizationType::ProblemType::DiffusionFactorType::NonparametricType,
          ConstDiscreteFunctionType,
          ConstDiscreteFunctionType,
          RangeFieldType,
          typename DiscretizationType::ProblemType::DiffusionTensorType::NonparametricType > ProductType;
    ProductType penalty_product(discretization_.grid_view(),
                                solution,
                                solution,
                                *diffusion_factor,
                                *diffusion_tensor,
                                2);
    return std::sqrt(penalty_product.apply2());
  } // ... compute_jump_norm(...)

  std::vector< std::string > available_estimators() const
  {
    return Estimator::available();
  }

  RangeFieldType estimate(const VectorType& vector,
                          const std::string type,
                          const Dune::Pymor::Parameter mu_hat = Dune::Pymor::Parameter(),
                          const Dune::Pymor::Parameter mu_bar = Dune::Pymor::Parameter(),
                          const Dune::Pymor::Parameter mu     = Dune::Pymor::Parameter())
  {
    return Estimator::estimate(*discretization_.ansatz_space(),
                               vector,
                               discretization_.problem(),
                               type,
                               {{"mu_hat",        mu_hat},
                                {"mu_bar",        mu_bar},
                                {"mu",            mu},
                                {"mu_minimizing", Dune::Pymor::Parameter("mu", 0.1)}});
  } // ... estimate(...)

public:
  TestCaseType test_case_;
  TestCaseType reference_test_case_;
  DiscretizationType discretization_;
  DiscretizationType reference_discretization_;
}; // class Example

} // namespace internal

template< class GridImp >
class Spe10Model1Example
  : public internal::Example< Dune::HDD::LinearElliptic::TestCases::Spe10::ParametricBlockModel1< GridImp > >
{
  static_assert(GridImp::dimension == 2, "Only available in 2d!");
  typedef internal::Example< Dune::HDD::LinearElliptic::TestCases::Spe10::ParametricBlockModel1< GridImp > > BaseType;

public:
  template< class... Args >
  Spe10Model1Example(Args&& ...args)
    : BaseType(std::forward< Args >(args)...)
  {}
}; // class Spe10Model1Example

template< class GridImp >
class OS2014Example
  : public internal::Example< Dune::HDD::LinearElliptic::TestCases::OS2014::ParametricBlockConvergence< GridImp > >
{
  static_assert(GridImp::dimension == 2, "Only available in 2d!");
  typedef internal::Example
      < Dune::HDD::LinearElliptic::TestCases::OS2014::ParametricBlockConvergence< GridImp > > BaseType;

public:
  template< class... Args >
  OS2014Example(Args&& ...args)
    : BaseType(std::forward< Args >(args)...)
  {}
}; // class OS2014Example

#endif // DUNE_HDD_EXAMPLES_LINEARELLIPTIC_OS2014_HH
<commit_msg>[examples.linearelliptic.OS2014] circumvent freeze_parameter() of product<commit_after>// This file is part of the dune-hdd project:
//   http://users.dune-project.org/projects/dune-hdd
// Copyright holders: Felix Schindler
// License: BSD 2-Clause License (http://opensource.org/licenses/BSD-2-Clause)

#ifndef DUNE_HDD_EXAMPLES_LINEARELLIPTIC_OS2014_HH
#define DUNE_HDD_EXAMPLES_LINEARELLIPTIC_OS2014_HH

#define DUNE_HDD_LINEARELLIPTIC_TESTCASES_BASE_DISABLE_WARNING

#include <boost/numeric/conversion/cast.hpp>

#include <dune/fem/misc/mpimanager.hh>

#include <dune/stuff/common/logging.hh>
#include <dune/stuff/functions/expression.hh>

#include <dune/pymor/parameters/base.hh>

#include <dune/gdt/discretefunction/default.hh>
#include <dune/gdt/operators/projections.hh>
#include <dune/gdt/operators/prolongations.hh>
#include <dune/gdt/playground/products/elliptic-swipdg.hh>

#include <dune/hdd/linearelliptic/testcases/OS2014.hh>
#include <dune/hdd/linearelliptic/testcases/spe10.hh>
#include <dune/hdd/linearelliptic/discretizations/block-swipdg.hh>
#include <dune/hdd/linearelliptic/estimators/block-swipdg.hh>

namespace internal {

class Initializer
{
public:
  Initializer(const ssize_t info_log_levels,
              const ssize_t debug_log_levels,
              const bool enable_warnings,
              const bool enable_colors,
              const std::string info_color,
              const std::string debug_color,
              const std::string warn_color)
  {
    try {
      int argc = 0;
      char** argv = new char* [0];
      Dune::Fem::MPIManager::initialize(argc, argv);
    } catch (...) {}
    DSC::TimedLogger().create(info_log_levels,
                              debug_log_levels,
                              enable_warnings,
                              enable_colors,
                              info_color,
                              debug_color,
                              warn_color);
    DSC::TimedLogger().get("OS2014.initializer").info() << "creating grid and problem... " << std::endl;
  }
}; // class Initializer

template< class TestCaseType >
class Example
  : Initializer
{
public:
  typedef typename TestCaseType::GridType GridType;
  typedef double RangeFieldType;
  typedef Dune::HDD::LinearElliptic::Discretizations::BlockSWIPDG< GridType, RangeFieldType, 1 > DiscretizationType;
  typedef typename DiscretizationType::VectorType VectorType;

private:
  typedef Dune::HDD::LinearElliptic::Estimators::BlockSWIPDG< typename DiscretizationType::AnsatzSpaceType,
                                                              VectorType,
                                                              typename DiscretizationType::ProblemType,
                                                              GridType > Estimator;

public:
  Example(const std::string partitioning = "[1 1 1]",
          const DUNE_STUFF_SSIZE_T num_refinements = 0,
          const std::vector< std::string > products = {},
          const ssize_t info_log_levels  = 0,
          const ssize_t debug_log_levels = -1,
          const bool enable_warnings = true,
          const bool enable_colors   = true,
          const std::string info_color  = DSC::TimedLogging::default_info_color(),
          const std::string debug_color = DSC::TimedLogging::default_debug_color(),
          const std::string warn_color  = DSC::TimedLogging::default_warning_color())
    : Initializer(info_log_levels,
                  debug_log_levels,
                  enable_warnings,
                  enable_colors,
                  info_color,
                  debug_color,
                  warn_color)
    , test_case_({{"mu", Dune::Pymor::Parameter("mu", 1)},     // <- it does not matter which parameters we give to the
                  {"mu_hat", Dune::Pymor::Parameter("mu", 1)}, //    test case here, since we use test_case_.problem()
                  {"mu_bar", Dune::Pymor::Parameter("mu", 1)}, //    (which is the parametric problem) anyway
                  {"mu_minimizing", Dune::Pymor::Parameter("mu", 1)}},
                 partitioning,
                 boost::numeric_cast< size_t >(num_refinements))
    , reference_test_case_({{"mu", Dune::Pymor::Parameter("mu", 1)},
                            {"mu_hat", Dune::Pymor::Parameter("mu", 1)},
                            {"mu_bar", Dune::Pymor::Parameter("mu", 1)},
                            {"mu_minimizing", Dune::Pymor::Parameter("mu", 1)}},
                           partitioning,
                           boost::numeric_cast< size_t >(num_refinements + 1))
    , discretization_(*test_case_.reference_provider(),
                      test_case_.boundary_info(),
                      test_case_.problem(),
                      products)
    , reference_discretization_(*reference_test_case_.reference_provider(),
                                reference_test_case_.boundary_info(),
                                reference_test_case_.problem(),
                                products)
  {
    auto logger = DSC::TimedLogger().get("OS2014.example");
    logger.info() << "initializing discretization... " << std::flush;
    discretization_.init();
    reference_discretization_.init();
    logger.info() << "done (grid has " << discretization_.grid_view().indexSet().size(0)
                  << " elements, discretization has " << discretization_.ansatz_space()->mapper().size() << " DoFs)"
                  << std::endl;
  } // ... OS2014Spe10Model1Example(...)

  const TestCaseType& test_case() const
  {
    return test_case_;
  }

  DiscretizationType& discretization()
  {
    return discretization_;
  }

  DiscretizationType* discretization_and_return_ptr() const
  {
    return new DiscretizationType(discretization_);
  }

  VectorType project(const std::string expression) const
  {
    using namespace Dune;
    typedef typename DiscretizationType::AnsatzSpaceType AnsatzSpaceType;
    typedef GDT::DiscreteFunction< AnsatzSpaceType, VectorType > DiscreteFunctionType;
    DiscreteFunctionType discrete_function(*discretization_.ansatz_space());

    typedef Stuff::Functions::Expression< typename DiscreteFunctionType::EntityType,
                                          typename DiscreteFunctionType::DomainFieldType,
                                          DiscreteFunctionType::dimDomain,
                                          typename DiscreteFunctionType::RangeFieldType,
                                          DiscreteFunctionType::dimRange > ExpressionFunctionType;
    ExpressionFunctionType func("x", expression);

    GDT::Operators::Projection< typename DiscretizationType::GridViewType > projection(discretization_.grid_view());
    projection.apply(func, discrete_function);

    return discrete_function.vector();
  } // ... project(...)

  RangeFieldType compute_error(const VectorType& solution,
                               const std::string product_type = "",
                               const Dune::Pymor::Parameter mu = Dune::Pymor::Parameter(),
                               const Dune::Pymor::Parameter mu_product = Dune::Pymor::Parameter())
  {
    const std::string type = (product_type.empty() && reference_discretization_.available_products().size() == 1)
                             ? reference_discretization_.available_products()[0]
                             : product_type;
    // wrap solution into a discrete function
    using namespace Dune;
    typedef typename DiscretizationType::AnsatzSpaceType AnsatzSpaceType;
    typedef GDT::ConstDiscreteFunction< AnsatzSpaceType, VectorType > ConstDiscreteFunctionType;
    ConstDiscreteFunctionType coarse_solution(*discretization_.ansatz_space(), solution);
    // prolong to reference grid view
    typedef GDT::DiscreteFunction< AnsatzSpaceType, VectorType > DiscreteFunctionType;
    DiscreteFunctionType fine_solution(*reference_discretization_.ansatz_space());
    GDT::Operators::Prolongation< typename DiscretizationType::GridViewType >
        prolongation_operator(reference_discretization_.grid_view());
    prolongation_operator.apply(coarse_solution, fine_solution);
    // compute reference solution
    DiscreteFunctionType reference_solution(*reference_discretization_.ansatz_space());
    reference_discretization_.solve(reference_solution.vector(), mu);
    // compute error
    const auto difference = reference_solution.vector() - fine_solution.vector();
    const auto product = reference_discretization_.get_product(type);
    return std::sqrt(product.apply2(difference, difference, mu_product));
  } // ... compute_error(...)

  RangeFieldType compute_jump_norm(const VectorType& solution_vector,
                                   const Dune::Pymor::Parameter mu_product = Dune::Pymor::Parameter())
  {
    using namespace Dune;
    typedef typename DiscretizationType::AnsatzSpaceType AnsatzSpaceType;
    typedef GDT::ConstDiscreteFunction< AnsatzSpaceType, VectorType > ConstDiscreteFunctionType;
    ConstDiscreteFunctionType solution(*discretization_.ansatz_space(), solution_vector);
    const auto diffusion_factor = discretization_.problem().diffusion_factor()->with_mu(mu_product);
    const auto diffusion_tensor = discretization_.problem().diffusion_tensor()->with_mu(mu_product);
    typedef GDT::Products::EllipticSWIPDGPenaltyLocalizable
        < typename DiscretizationType::GridViewType,
          typename DiscretizationType::ProblemType::DiffusionFactorType::NonparametricType,
          ConstDiscreteFunctionType,
          ConstDiscreteFunctionType,
          RangeFieldType,
          typename DiscretizationType::ProblemType::DiffusionTensorType::NonparametricType > ProductType;
    ProductType penalty_product(discretization_.grid_view(),
                                solution,
                                solution,
                                *diffusion_factor,
                                *diffusion_tensor,
                                2);
    return std::sqrt(penalty_product.apply2());
  } // ... compute_jump_norm(...)

  std::vector< std::string > available_estimators() const
  {
    return Estimator::available();
  }

  RangeFieldType estimate(const VectorType& vector,
                          const std::string type,
                          const Dune::Pymor::Parameter mu_hat = Dune::Pymor::Parameter(),
                          const Dune::Pymor::Parameter mu_bar = Dune::Pymor::Parameter(),
                          const Dune::Pymor::Parameter mu     = Dune::Pymor::Parameter())
  {
    return Estimator::estimate(*discretization_.ansatz_space(),
                               vector,
                               discretization_.problem(),
                               type,
                               {{"mu_hat",        mu_hat},
                                {"mu_bar",        mu_bar},
                                {"mu",            mu},
                                {"mu_minimizing", Dune::Pymor::Parameter("mu", 0.1)}});
  } // ... estimate(...)

public:
  TestCaseType test_case_;
  TestCaseType reference_test_case_;
  DiscretizationType discretization_;
  DiscretizationType reference_discretization_;
}; // class Example

} // namespace internal

template< class GridImp >
class Spe10Model1Example
  : public internal::Example< Dune::HDD::LinearElliptic::TestCases::Spe10::ParametricBlockModel1< GridImp > >
{
  static_assert(GridImp::dimension == 2, "Only available in 2d!");
  typedef internal::Example< Dune::HDD::LinearElliptic::TestCases::Spe10::ParametricBlockModel1< GridImp > > BaseType;

public:
  template< class... Args >
  Spe10Model1Example(Args&& ...args)
    : BaseType(std::forward< Args >(args)...)
  {}
}; // class Spe10Model1Example

template< class GridImp >
class OS2014Example
  : public internal::Example< Dune::HDD::LinearElliptic::TestCases::OS2014::ParametricBlockConvergence< GridImp > >
{
  static_assert(GridImp::dimension == 2, "Only available in 2d!");
  typedef internal::Example
      < Dune::HDD::LinearElliptic::TestCases::OS2014::ParametricBlockConvergence< GridImp > > BaseType;

public:
  template< class... Args >
  OS2014Example(Args&& ...args)
    : BaseType(std::forward< Args >(args)...)
  {}
}; // class OS2014Example

#endif // DUNE_HDD_EXAMPLES_LINEARELLIPTIC_OS2014_HH
<|endoftext|>


<commit_before>#ifndef EXAMPLES_MPI_DOMAIN_PARTITION_HPP
#define EXAMPLES_MPI_DOMAIN_PARTITION_HPP

#include <vector>
#include <utility>

#include <boost/foreach.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/adapted/boost_array.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>

BOOST_GEOMETRY_REGISTER_BOOST_ARRAY_CS(cs::cartesian)

template <int NDIM>
class domain_partition {
    public:
        typedef boost::array<ptrdiff_t, NDIM>      point;
        typedef boost::geometry::model::box<point> box;
        typedef std::pair<box, int>                process;

        domain_partition(point lo, point hi, int num_processes) {
            split(box(lo, hi), num_processes);

            for(int i = 0; i < num_processes; ++i)
                rtree.insert( std::make_pair(subdomains[i], i) );
        }

        std::pair<int, ptrdiff_t> index(point p) const {
            namespace bgi = boost::geometry::index;

            BOOST_FOREACH(const process &v, rtree | bgi::adaptors::queried(bgi::intersects(p)) )
            {
                return std::make_pair(v.second, local_index(v.first, p));
            }

            // Unreachable:
            return std::make_pair(0, 0l);
        }

        size_t size(size_t process) const {
            if (process >= subdomains.size()) return 0;

            point lo = subdomains[process].min_corner();
            point hi = subdomains[process].max_corner();

            size_t v = 1;

            for(int i = 0; i < NDIM; ++i)
                v *= hi[i] - lo[i] + 1;

            return v;
        }

        box domain(size_t process) const {
            if (process < subdomains.size())
                return subdomains[process];
            else {
                boost::array<ptrdiff_t, 3> lo = { { 0,  0,  0} };
                boost::array<ptrdiff_t, 3> hi = { {-1, -1, -1} };
                return box(lo, hi);
            }
        }
    private:
        std::vector<box> subdomains;

        boost::geometry::index::rtree<
            process,
            boost::geometry::index::quadratic<16>
            > rtree;

        static ptrdiff_t local_index(box domain, point p) {
            point lo = domain.min_corner();
            point hi = domain.max_corner();

            ptrdiff_t stride = 1, idx = 0;
            for(int i = 0; i < NDIM; ++i) {
                idx += (p[i] - lo[i]) * stride;
                stride *= hi[i] - lo[i] + 1;
            }

            return idx;
        }

        void split(box domain, int np) {
            if (np == 1) {
                subdomains.push_back(domain);
                return;
            }

            point lo = domain.min_corner();
            point hi = domain.max_corner();

            // Get longest dimension of the domain
            int wd = 0;
            for(int i = 1; i < NDIM; ++i)
                if (hi[i] - lo[i] > hi[wd] - lo[wd]) wd = i;

            ptrdiff_t mid = lo[wd] + (hi[wd] - lo[wd]) * (np / 2) / np;

            box sd1 = domain;
            box sd2 = domain;

            sd1.max_corner()[wd] = mid;
            sd2.min_corner()[wd] = mid + 1;

            split(sd1, np / 2);
            split(sd2, np - np / 2);
        }
};

#endif
<commit_msg>Fix domain_partition for dimensions other than 3<commit_after>#ifndef EXAMPLES_MPI_DOMAIN_PARTITION_HPP
#define EXAMPLES_MPI_DOMAIN_PARTITION_HPP

#include <vector>
#include <utility>

#include <boost/foreach.hpp>
#include <boost/geometry.hpp>
#include <boost/geometry/geometries/adapted/boost_array.hpp>
#include <boost/geometry/geometries/box.hpp>
#include <boost/geometry/index/rtree.hpp>

BOOST_GEOMETRY_REGISTER_BOOST_ARRAY_CS(cs::cartesian)

template <int NDIM>
class domain_partition {
    public:
        typedef boost::array<ptrdiff_t, NDIM>      point;
        typedef boost::geometry::model::box<point> box;
        typedef std::pair<box, int>                process;

        domain_partition(point lo, point hi, int num_processes) {
            split(box(lo, hi), num_processes);

            for(int i = 0; i < num_processes; ++i)
                rtree.insert( std::make_pair(subdomains[i], i) );
        }

        std::pair<int, ptrdiff_t> index(point p) const {
            namespace bgi = boost::geometry::index;

            BOOST_FOREACH(const process &v, rtree | bgi::adaptors::queried(bgi::intersects(p)) )
            {
                return std::make_pair(v.second, local_index(v.first, p));
            }

            // Unreachable:
            return std::make_pair(0, 0l);
        }

        size_t size(size_t process) const {
            if (process >= subdomains.size()) return 0;

            point lo = subdomains[process].min_corner();
            point hi = subdomains[process].max_corner();

            size_t v = 1;

            for(int i = 0; i < NDIM; ++i)
                v *= hi[i] - lo[i] + 1;

            return v;
        }

        box domain(size_t process) const {
            if (process < subdomains.size())
                return subdomains[process];
            else {
                point lo;
                point hi;
                for(int i = 0; i < NDIM; ++i) {
                    lo[i] = 0;
                    hi[i] = -1;
                }
                return box(lo, hi);
            }
        }
    private:
        std::vector<box> subdomains;

        boost::geometry::index::rtree<
            process,
            boost::geometry::index::quadratic<16>
            > rtree;

        static ptrdiff_t local_index(box domain, point p) {
            point lo = domain.min_corner();
            point hi = domain.max_corner();

            ptrdiff_t stride = 1, idx = 0;
            for(int i = 0; i < NDIM; ++i) {
                idx += (p[i] - lo[i]) * stride;
                stride *= hi[i] - lo[i] + 1;
            }

            return idx;
        }

        void split(box domain, int np) {
            if (np == 1) {
                subdomains.push_back(domain);
                return;
            }

            point lo = domain.min_corner();
            point hi = domain.max_corner();

            // Get longest dimension of the domain
            int wd = 0;
            for(int i = 1; i < NDIM; ++i)
                if (hi[i] - lo[i] > hi[wd] - lo[wd]) wd = i;

            ptrdiff_t mid = lo[wd] + (hi[wd] - lo[wd]) * (np / 2) / np;

            box sd1 = domain;
            box sd2 = domain;

            sd1.max_corner()[wd] = mid;
            sd2.min_corner()[wd] = mid + 1;

            split(sd1, np / 2);
            split(sd2, np - np / 2);
        }
};

#endif
<|endoftext|>


<commit_before>/* OpenSceneGraph example, osghangglide.
*
*  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 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 <math.h>

#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Texture2D>
#include <osg/TexEnv>
#include <osg/StateSet>

#include <osgDB/ReadFile>

#include "terrain_coords.h"
#include "terrain_texcoords.h"

using namespace osg;

void getDatabaseCenterRadius( float dbcenter[3], float *dbradius )
{
    int i;
    double n=0.0;
    double center[3] = { 0.0f, 0.0f, 0.0f };
    float  cnt;

    cnt = 39 * 38;
    for( i = 0; i < cnt; i++ )
    {
        center[0] += (double)vertex[i][0];
        center[1] += (double)vertex[i][1];
        center[2] += (double)vertex[i][2];

        n = n + 1.0;
    }

    center[0] /= n;
    center[1] /= n;
    center[2] /= n;

    float r = 0.0;

    //    for( i = 0; i < sizeof( vertex ) / (sizeof( float[3] )); i++ )
    for( i = 0; i < cnt; i++ )
    {
        double d = sqrt(
            (((double)vertex[i][0] - center[0]) * ((double)vertex[i][0] - center[0])) +
            (((double)vertex[i][1] - center[1]) * ((double)vertex[i][1] - center[1])) +
            (((double)vertex[i][2] - center[2]) * ((double)vertex[i][2] - center[2]))  );

        if( d > (double)r ) r = (float)d;

    }

    *dbradius = r;
    dbcenter[0] = (float)center[0];
    dbcenter[1] = (float)center[1];
    dbcenter[2] = (float)center[2];

    int index = 19 * 39 + 19;
    dbcenter[0] = vertex[index][0] - 0.15;
    dbcenter[1] = vertex[index][1];
    dbcenter[2] = vertex[index][2] + 0.35;

}

Node *makeTerrain( void )
{
    int m, n;
    int  i, j;
    float dbcenter[3];
    float dbradius;

    getDatabaseCenterRadius( dbcenter, &dbradius );

    m = (sizeof( vertex ) /(sizeof( float[3])))/39;
    n = 39;

    Vec3Array& v    = *(new Vec3Array(m*n));
    Vec2Array& t    = *(new Vec2Array(m*n));
    Vec4Array& col  = *(new Vec4Array(1));

    col[0][0] = col[0][1] = col[0][2] = col[0][3] = 1.0f;

    for( i = 0; i < m * n; i++ )
    {
        v[i][0] = vertex[i][0] - dbcenter[0];
        v[i][1] = vertex[i][1] - dbcenter[1];
        v[i][2] = vertex[i][2];

        t[i][0] = texcoord[i][0] + 0.025;
        t[i][1] = texcoord[i][1];
    }

    Geometry *geom = new Geometry;

    geom->setVertexArray( &v );
    geom->setTexCoordArray( 0, &t );

    geom->setColorArray( &col, Array::BIND_OVERALL );

    for( i = 0; i < m-2; i++ )
    {
        DrawElementsUShort* elements = new DrawElementsUShort(PrimitiveSet::TRIANGLE_STRIP);
        elements->reserve(39*2);
        for( j = 0; j < n; j++ )
        {
            elements->push_back((i+0)*n+j);
            elements->push_back((i+1)*n+j);
        }
        geom->addPrimitiveSet(elements);
    }

    Texture2D *tex = new Texture2D;

    tex->setImage(osgDB::readImageFile("Images/lz.rgb"));

    StateSet *dstate = new StateSet;
    dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
    dstate->setTextureAttributeAndModes(0, tex, StateAttribute::ON );
    dstate->setTextureAttribute(0, new TexEnv );

    geom->setStateSet( dstate );

    Geode *geode = new Geode;
    geode->addDrawable( geom );

    return geode;
}
<commit_msg>Fixed warning<commit_after>/* OpenSceneGraph example, osghangglide.
*
*  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 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 <math.h>

#include <osg/Geode>
#include <osg/Geometry>
#include <osg/Texture2D>
#include <osg/TexEnv>
#include <osg/StateSet>

#include <osgDB/ReadFile>

#include "terrain_coords.h"
#include "terrain_texcoords.h"

using namespace osg;

void getDatabaseCenterRadius( float dbcenter[3], float *dbradius )
{
    int i;
    double n=0.0;
    double center[3] = { 0.0f, 0.0f, 0.0f };
    float  cnt;

    cnt = 39 * 38;
    for( i = 0; i < cnt; i++ )
    {
        center[0] += (double)vertex[i][0];
        center[1] += (double)vertex[i][1];
        center[2] += (double)vertex[i][2];

        n = n + 1.0;
    }

    center[0] /= n;
    center[1] /= n;
    center[2] /= n;

    float r = 0.0;

    //    for( i = 0; i < sizeof( vertex ) / (sizeof( float[3] )); i++ )
    for( i = 0; i < cnt; i++ )
    {
        double d = sqrt(
            (((double)vertex[i][0] - center[0]) * ((double)vertex[i][0] - center[0])) +
            (((double)vertex[i][1] - center[1]) * ((double)vertex[i][1] - center[1])) +
            (((double)vertex[i][2] - center[2]) * ((double)vertex[i][2] - center[2]))  );

        if( d > (double)r ) r = (float)d;

    }

    *dbradius = r;
    dbcenter[0] = (float)center[0];
    dbcenter[1] = (float)center[1];
    dbcenter[2] = (float)center[2];

    int index = 19 * 39 + 19;
    dbcenter[0] = vertex[index][0] - 0.15;
    dbcenter[1] = vertex[index][1];
    dbcenter[2] = vertex[index][2] + 0.35;

}

Node *makeTerrain( void )
{
    int m, n;
    int  i, j;
    float dbcenter[3];
    float dbradius;

    getDatabaseCenterRadius( dbcenter, &dbradius );

    m = (sizeof( vertex ) /(sizeof( float[3])))/39;
    n = 39;

    Vec3Array& v    = *(new Vec3Array(m*n));
    Vec2Array& t    = *(new Vec2Array(m*n));
    Vec4Array& col  = *(new Vec4Array(1));

    col[0][0] = col[0][1] = col[0][2] = col[0][3] = 1.0f;

    for( i = 0; i < m * n; i++ )
    {
        float* vc = vertex[i];
        v[i][0] = vc[0] - dbcenter[0];
        v[i][1] = vc[1] - dbcenter[1];
        v[i][2] = vc[2];

        float* tc = texcoord[i];
        t[i][0] = tc[0];
        t[i][1] = tc[1];
    }

    Geometry *geom = new Geometry;

    geom->setVertexArray( &v );
    geom->setTexCoordArray( 0, &t );

    geom->setColorArray( &col, Array::BIND_OVERALL );

    for( i = 0; i < m-2; i++ )
    {
        DrawElementsUShort* elements = new DrawElementsUShort(PrimitiveSet::TRIANGLE_STRIP);
        elements->reserve(39*2);
        for( j = 0; j < n; j++ )
        {
            elements->push_back((i+0)*n+j);
            elements->push_back((i+1)*n+j);
        }
        geom->addPrimitiveSet(elements);
    }

    Texture2D *tex = new Texture2D;

    tex->setImage(osgDB::readImageFile("Images/lz.rgb"));

    StateSet *dstate = new StateSet;
    dstate->setMode( GL_LIGHTING, StateAttribute::OFF );
    dstate->setTextureAttributeAndModes(0, tex, StateAttribute::ON );
    dstate->setTextureAttribute(0, new TexEnv );

    geom->setStateSet( dstate );

    Geode *geode = new Geode;
    geode->addDrawable( geom );

    return geode;
}
<|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS ooo19126 (1.6.342); FILE MERGED 2005/09/05 17:23:06 rt 1.6.342.1: #i54170# Change license header: remove SISSL<commit_after><|endoftext|>


<commit_before>#include <stdio.h>
#include <cmath>
#include <boost/shared_ptr.hpp>
#include <lcm/lcm-cpp.hpp>
#include "lcmtypes/drc_lcmtypes.hpp"
#include <ConciseArgs>
#include <string>
#include <deque>
using namespace std;

class App{
  public:
    App(boost::shared_ptr<lcm::LCM> &lcm_, bool is_left);

    ~App(){
    }

  private:
    boost::shared_ptr<lcm::LCM> lcm_;
    bool is_left;

    std::vector < float > command_pos_;
    std::vector<float> sensed_pos_;

    //////////////////////////////////////
    void commandHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::joint_command_t* msg);
    void stateHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::hand_state_t* msg);
};

App::App(boost::shared_ptr<lcm::LCM> &lcm_, bool is_left):
   lcm_(lcm_), is_left(is_left){

  lcm_->subscribe(is_left ? "L_HAND_JOINT_COMMANDS":"R_HAND_JOINT_COMMANDS",
                                        &App::commandHandler, this);

  lcm_->subscribe(is_left ? "SANDIA_LEFT_STATE":"SANDIA_RIGHT_STATE",
                                        &App::stateHandler, this);

}

void App::commandHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  drc::joint_command_t* msg){

  std::cout << "got command\n";
  std::vector<float> v_float( msg->position.begin(),  msg->position.end());
  command_pos_ = v_float;

}

void App::stateHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  drc::hand_state_t* msg){

  sensed_pos_ = msg->joint_position;
  std::cout << "got state\n";

  if (command_pos_.size() != sensed_pos_.size()){
    //std::cout << "sensed and commanded don't match\n";
    return;
  }

  std::vector <float> diffs;
  for (size_t i=0; i < command_pos_.size() ; i++){
    diffs.push_back( fabs( command_pos_[i] - sensed_pos_[i] ) );
  }
  std::vector <float> finger_diffs(4,0.0);
  finger_diffs[0] = diffs[0] + diffs[1] + diffs[2];
  finger_diffs[1] = diffs[3] + diffs[4] + diffs[5];
  finger_diffs[2] = diffs[6] + diffs[7] + diffs[8];
  finger_diffs[3] = diffs[9] + diffs[10] + diffs[11];

  std::cout << diffs[9] << " " << diffs[10] << " " << diffs[11] << "\n";

  if (finger_diffs[3] > 0.2){
    std::cout << finger_diffs[3] << " BIG==================\n";
  }else{
    std::cout << finger_diffs[3] << "SMALL\n";
  }

}

int main(int argc, char *argv[]){
  bool lhand=false, rhand=false;
  ConciseArgs opt(argc, (char**)argv);
  opt.add(rhand, "r", "right","Process right hand message");
  opt.add(lhand, "l", "left","Process left hand message");

  opt.parse();
  if(rhand && lhand){
    printf("Only one hand at a time.\n");
    return 1;
  }
  if(!rhand && !lhand){
    printf("Please specify a hand. Type -h for usage.\n");
    return 1;
  }

  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM() );
  if(!lcm->good())
    return 1;

  App app(lcm, lhand);
  while(0 == lcm->handle());
  return 0;
}
<commit_msg>map raw diff values to 0 to 1 with hand-tuned logistic function. not yet published to LCM<commit_after>#include <stdio.h>
#include <cmath>
#include <boost/shared_ptr.hpp>
#include <lcm/lcm-cpp.hpp>
#include "lcmtypes/drc_lcmtypes.hpp"
#include <ConciseArgs>
#include <string>
#include <deque>
using namespace std;

class App{
  public:
    App(boost::shared_ptr<lcm::LCM> &lcm_, bool is_left);

    ~App(){
    }

  private:
    boost::shared_ptr<lcm::LCM> lcm_;
    bool is_left;

    std::vector < float > command_pos_;
    std::vector<float> sensed_pos_;

    //////////////////////////////////////
    void commandHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::joint_command_t* msg);
    void stateHandler(const lcm::ReceiveBuffer* rbuf,
                             const std::string& channel, const  drc::hand_state_t* msg);
};

App::App(boost::shared_ptr<lcm::LCM> &lcm_, bool is_left):
   lcm_(lcm_), is_left(is_left){

  lcm_->subscribe(is_left ? "L_HAND_JOINT_COMMANDS":"R_HAND_JOINT_COMMANDS",
                                        &App::commandHandler, this);

  lcm_->subscribe(is_left ? "SANDIA_LEFT_STATE":"SANDIA_RIGHT_STATE",
                                        &App::stateHandler, this);

}

void App::commandHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  drc::joint_command_t* msg){

  std::cout << "got command\n";
  std::vector<float> v_float( msg->position.begin(),  msg->position.end());
  command_pos_ = v_float;

}
// logistic function F(x)=1/(1+e^{-b_1 (x-b_0)})
float logit(float x, float b0=0, float b1=1){
  return 1.0/(1.0+exp(-(b1*(x-b0))));
}

void App::stateHandler(const lcm::ReceiveBuffer* rbuf,
     const std::string& channel, const  drc::hand_state_t* msg){

  sensed_pos_ = msg->joint_position;
  std::cout << "got state\n";

  if (command_pos_.size() != sensed_pos_.size()){
    //std::cout << "sensed and commanded don't match\n";
    return;
  }

  std::vector <float> diffs;
  for (size_t i=0; i < command_pos_.size() ; i++){
    diffs.push_back( fabs( command_pos_[i] - sensed_pos_[i] ) );
  }
  std::vector <float> finger_diffs(4,0.0);
  finger_diffs[0] = diffs[0] + diffs[1] + diffs[2];
  finger_diffs[1] = diffs[3] + diffs[4] + diffs[5];
  finger_diffs[2] = diffs[6] + diffs[7] + diffs[8];
  finger_diffs[3] = diffs[9] + diffs[10] + diffs[11];

  std::cout << diffs[9] << " " << diffs[10] << " " << diffs[11] << "\n";

  if (finger_diffs[3] > 0.2){
    std::cout << finger_diffs[3] << " BIG==================\n";
  }else{
    std::cout << finger_diffs[3] << "SMALL\n";
  }

  std::cout << "logit(finger_diffs[0])=" << logit(finger_diffs[0],0.1,60) << endl;
  std::cout << "logit(finger_diffs[1])=" << logit(finger_diffs[1],0.1,60) << endl;
  std::cout << "logit(finger_diffs[2])=" << logit(finger_diffs[2],0.1,60) << endl;
  std::cout << "logit(finger_diffs[3])=" << logit(finger_diffs[3],0.1,60) << endl;

}

int main(int argc, char *argv[]){
  bool lhand=false, rhand=false;
  ConciseArgs opt(argc, (char**)argv);
  opt.add(rhand, "r", "right","Process right hand message");
  opt.add(lhand, "l", "left","Process left hand message");

  opt.parse();
  if(rhand && lhand){
    printf("Only one hand at a time.\n");
    return 1;
  }
  if(!rhand && !lhand){
    printf("Please specify a hand. Type -h for usage.\n");
    return 1;
  }

  boost::shared_ptr<lcm::LCM> lcm(new lcm::LCM() );
  if(!lcm->good())
    return 1;

  App app(lcm, lhand);
  while(0 == lcm->handle());
  return 0;
}
<|endoftext|>


<commit_before>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tray.h"

#include <QMessageBox>
#include <QSharedMemory>
#include <QtGui>
#include <QRegExp>
#include <QDesktopServices>
#include <QUrl>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // disable Maximize functionality
    setWindowFlags( (windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);
    //setFixedWidth(600);
    //setFixedHeight(270);

    // overrides the window title defined in mainwindow.ui
    setWindowTitle(APP_NAME_AND_VERSION);

    createActions();

    createTrayIcon();

    // fetch version numbers from the daemons and set label text
    ui->label_Nginx_Version->setText( getNginxVersion() );
    ui->label_PHP_Version->setText( getPHPVersion() );
    ui->label_MariaDb_Version->setText( getMariaVersion() );
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::createTrayIcon()
{
    // The tray icon is an instance of the QSystemTrayIcon class.
    // To check whether a system tray is present on the user's desktop,
    // we call the static QSystemTrayIcon::isSystemTrayAvailable() function.
    if (false == QSystemTrayIcon::isSystemTrayAvailable())
    {
        QMessageBox::critical(0, APP_NAME, tr("You don't have a system tray."));
        //return 1;
    }
    else
    {
        // instantiate and attach the tray icon to the system tray
        trayIcon = new Tray(qApp);
        trayIcon->show();

        // handle clicks on the icon
        connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
                this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));
    }
}

void MainWindow::createActions()
 {
     minimizeAction = new QAction(tr("Mi&nimize"), this);
     connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));

     restoreAction = new QAction(tr("&Restore"), this);
     connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));

     quitAction = new QAction(tr("&Quit"), this);
     // qApp is global pointer to QApplication
     connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));

     // PushButtons:: Website, ReportBug, Donate
     connect(ui->pushButton_Website, SIGNAL(clicked()), this, SLOT(goToWebsite()));
     connect(ui->pushButton_GoogleGroup, SIGNAL(clicked()), this, SLOT(goToGoogleGroup()));
     connect(ui->pushButton_ReportBug, SIGNAL(clicked()), this, SLOT(goToReportIssue()));
     connect(ui->pushButton_Donate, SIGNAL(clicked()), this, SLOT(goToDonate()));

     // PushButtons: Configuration, Help, About, Close
     connect(ui->pushButton_Configuration, SIGNAL(clicked()), this, SLOT(openConfigurationDialog()));
     connect(ui->pushButton_Help, SIGNAL(clicked()), this, SLOT(openHelpDialog()));
     connect(ui->pushButton_About, SIGNAL(clicked()), this, SLOT(openAboutDialog()));
     connect(ui->pushButton_Close, SIGNAL(clicked()), qApp, SLOT(quit()));

     // Actions - Start
     //connect(ui->pushButton_StartNginx, SIGNAL(clicked()), trayIcon, SLOT(runNginx()));
     //connect(ui->pushButton_StartPHP, SIGNAL(clicked()), trayIcon, SLOT(runPhp()));
     //connect(ui->pushButton_StartMariaDb, SIGNAL(clicked()), trayIcon, SLOT(runMySQL()));

     // Actions - Stop
    // connect(ui->pushButton_StopNginx, SIGNAL(clicked()), trayIcon, SLOT(stopNginx()));
    // connect(ui->pushButton_StopPHP, SIGNAL(clicked()), trayIcon, SLOT(stopPhp()));
     //connect(ui->pushButton_StopMariaDb, SIGNAL(clicked()), trayIcon, SLOT(stopMySQL()));
 }

void MainWindow::changeEvent(QEvent *event)
{
    switch (event->type())
    {
        //case QEvent::LanguageChange:
        //    this->ui->retranslateUi(this);
        //    break;
        case QEvent::WindowStateChange:
            {
                // minimize to tray (do not minimize to taskbar)
                if (this->windowState() & Qt::WindowMinimized)
                {
                    // @todo provide configuration options to let the user decide on this
                    //if (Preferences::instance().minimizeToTray())
                    //{
                        QTimer::singleShot(0, this, SLOT(hide()));
                    //}
                }

                break;
            }
        default:
            break;
    }

    QMainWindow::changeEvent(event);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (trayIcon->isVisible()) {
        QMessageBox::information(this, APP_NAME,
                                 tr("The program will keep running in the system tray.
"
                                    "To terminate the program, choose Quit in the context menu of the system tray."));
        hide();

        // do not propagate the event to the base class
        event->ignore();
    }
}

void MainWindow::setVisible(bool visible)
 {
     minimizeAction->setEnabled(visible);
     restoreAction->setEnabled(isMaximized() || !visible);
     QMainWindow::setVisible(visible);
 }

void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
        case QSystemTrayIcon::Trigger:
        case QSystemTrayIcon::DoubleClick:
        //case QSystemTrayIcon::MiddleClick:

            // clicking the tray icon, when the main window is hidden, shows the main window
            if(!isVisible()) {
                setVisible(true);
                setWindowState( windowState() & ( ~Qt::WindowMinimized | Qt::WindowActive ) );
            }
            else {
                // clicking the tray icon, when the main window is shown, hides it
                setVisible(false);
            }

            break;
        default:;
    }
}

QString MainWindow::getNginxVersion()
{
    QProcess* processNginx;

    processNginx = new QProcess(this);
    //processNginx->setWorkingDirectory(cfgNginxDir);
    //processNginx->start("./nginx", QStringList() << "-v");
    processNginx->waitForFinished(-1);

    //QString p_stdout = processNginx->readAllStandardOutput();
    QString p_stderr = processNginx->readAllStandardError();

    // test
    QString p_stdout = "nginx version: nginx/1.1.11";

    qDebug() << p_stdout;
    qDebug() << p_stderr;

    return parseVersionNumber(p_stdout);
}

QString MainWindow::getMariaVersion()
{
    QProcess* processMaria;

    processMaria = new QProcess(this);
    //processMaria->setWorkingDirectory(cfgMariaDir);
    processMaria->start("./mysqld", QStringList() << "-V"); // upper-case V
    processMaria->waitForFinished(-1);

    //QString p_stdout = processMaria->readAllStandardOutput();
    QString p_stderr = processMaria->readAllStandardError();

    // test
    QString p_stdout = "mysql  Ver 15.1 Distrib 5.5.23-MariaDB, for Win32 (x86)";

    qDebug() << p_stdout;
    qDebug() << p_stderr;

    return parseVersionNumber(p_stdout.mid(15));
}

QString MainWindow::getPHPVersion()
{
    QProcess* processPhp;

    processPhp = new QProcess(this);
    //processPhp->setWorkingDirectory(cfgPHPDir);
    //processPhp->start(cfgPHPDir+cfgPHPExec, QStringList() << "-v");
    processPhp->waitForFinished(-1);

    //QString p_stdout = processPhp->readAllStandardOutput();
    QString p_stderr = processPhp->readAllStandardError();

    // test
    QString p_stdout = "PHP 5.4.0 (cli) (built: Feb 29 2012 19:06:50)";

    qDebug() << p_stdout;
    qDebug() << p_stderr;

    return parseVersionNumber(p_stdout);
}

QString MainWindow::parseVersionNumber(QString stringWithVersion)
{
    qDebug() << stringWithVersion;

    // The RegExp for matching version numbers is (\d+\.)?(\d+\.)?(\d+\.)?(\*|\d+)
    // The following one is escaped:
    QRegExp regex("(\\d+\\.)?(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)");

    // match
    regex.indexIn(stringWithVersion);

    qDebug() << regex.cap(0);
    QString cap = regex.cap(0);
    return cap;

// Leave this for debugging reasons
//    int pos = 0;
//    while((pos = regex.indexIn(stringWithVersion, pos)) != -1)
//    {
//        qDebug() << "Match at pos " << pos
//                 << " with length " << regex.matchedLength()
//                 << ", captured = " << regex.capturedTexts().at(0).toLatin1().data()
//                 << ".\n";
//        pos += regex.matchedLength();
//    }
}

void MainWindow::goToWebsite()
{
    QDesktopServices::openUrl(QUrl("http://wpn-xm.org/"));
}

void MainWindow::goToGoogleGroup()
{
    QDesktopServices::openUrl(QUrl("http://groups.google.com/group/wpn-xm/"));
}

void MainWindow::goToReportIssue()
{
    QDesktopServices::openUrl(QUrl("https://github.com/jakoch/WPN-XM/issues/"));
}

void MainWindow::goToDonate()
{
    QDesktopServices::openUrl(QUrl("http://wpn-xm.org/#donate"));
}

void MainWindow::openHelpDialog()
{

}

void MainWindow::openConfigurationDialog()
{

}

void MainWindow::openAboutDialog()
{

}

<commit_msg>connected signal to slot added method setLabelStatusActive set default value disabled on status labels<commit_after>#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "tray.h"

#include <QMessageBox>
#include <QSharedMemory>
#include <QtGui>
#include <QRegExp>
#include <QDesktopServices>
#include <QUrl>

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // disable Maximize functionality
    setWindowFlags( (windowFlags() | Qt::CustomizeWindowHint) & ~Qt::WindowMaximizeButtonHint);
    //setFixedWidth(600);
    //setFixedHeight(270);

    // overrides the window title defined in mainwindow.ui
    setWindowTitle(APP_NAME_AND_VERSION);

    createActions();

    createTrayIcon();

    // fetch version numbers from the daemons and set label text accordingly
    ui->label_Nginx_Version->setText( getNginxVersion() );
    ui->label_PHP_Version->setText( getPHPVersion() );
    ui->label_MariaDb_Version->setText( getMariaVersion() );

    // the initial state of daemon status icons is disabled
    ui->label_Nginx_Status->setEnabled(false);
    ui->label_PHP_Status->setEnabled(false);
    ui->label_MariaDB_Status->setEnabled(false);
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::setLabelStatusActive(QString label, bool enabled)
{
    if(label == "nginx")
    {
        ui->label_Nginx_Status->setEnabled(enabled);
    }

    if(label == "php")
    {
        ui->label_PHP_Status->setEnabled(enabled);
    }

    if(label == "nginx")
    {
        ui->label_MariaDB_Status->setEnabled(enabled);
    }
}

void MainWindow::createTrayIcon()
{
    // The tray icon is an instance of the QSystemTrayIcon class.
    // To check whether a system tray is present on the user's desktop,
    // we call the static QSystemTrayIcon::isSystemTrayAvailable() function.
    if (false == QSystemTrayIcon::isSystemTrayAvailable())
    {
        QMessageBox::critical(0, APP_NAME, tr("You don't have a system tray."));
        //return 1;
    }
    else
    {
        // instantiate and attach the tray icon to the system tray
        trayIcon = new Tray(qApp);
        trayIcon->show();

        // handle clicks on the icon
        connect(trayIcon, SIGNAL(activated(QSystemTrayIcon::ActivationReason)),
                this, SLOT(iconActivated(QSystemTrayIcon::ActivationReason)));

        // if process state of a daemon changes, then change the label status in UI::MainWindow too
        connect(trayIcon, SIGNAL(signalSetLabelStatusActive(QString, bool)),
                this, SLOT(setLabelStatusActive(QString, bool)));
    }
}

void MainWindow::createActions()
 {
     minimizeAction = new QAction(tr("Mi&nimize"), this);
     connect(minimizeAction, SIGNAL(triggered()), this, SLOT(hide()));

     restoreAction = new QAction(tr("&Restore"), this);
     connect(restoreAction, SIGNAL(triggered()), this, SLOT(showNormal()));

     quitAction = new QAction(tr("&Quit"), this);
     // qApp is global pointer to QApplication
     connect(quitAction, SIGNAL(triggered()), qApp, SLOT(quit()));

     // PushButtons:: Website, ReportBug, Donate
     connect(ui->pushButton_Website, SIGNAL(clicked()), this, SLOT(goToWebsite()));
     connect(ui->pushButton_GoogleGroup, SIGNAL(clicked()), this, SLOT(goToGoogleGroup()));
     connect(ui->pushButton_ReportBug, SIGNAL(clicked()), this, SLOT(goToReportIssue()));
     connect(ui->pushButton_Donate, SIGNAL(clicked()), this, SLOT(goToDonate()));

     // PushButtons: Configuration, Help, About, Close
     connect(ui->pushButton_Configuration, SIGNAL(clicked()), this, SLOT(openConfigurationDialog()));
     connect(ui->pushButton_Help, SIGNAL(clicked()), this, SLOT(openHelpDialog()));
     connect(ui->pushButton_About, SIGNAL(clicked()), this, SLOT(openAboutDialog()));
     connect(ui->pushButton_Close, SIGNAL(clicked()), qApp, SLOT(quit()));

     // Actions - Start
     //connect(ui->pushButton_StartNginx, SIGNAL(clicked()), trayIcon, SLOT(runNginx()));
     //connect(ui->pushButton_StartPHP, SIGNAL(clicked()), trayIcon, SLOT(runPhp()));
     //connect(ui->pushButton_StartMariaDb, SIGNAL(clicked()), trayIcon, SLOT(runMySQL()));

     // Actions - Stop
    // connect(ui->pushButton_StopNginx, SIGNAL(clicked()), trayIcon, SLOT(stopNginx()));
    // connect(ui->pushButton_StopPHP, SIGNAL(clicked()), trayIcon, SLOT(stopPhp()));
     //connect(ui->pushButton_StopMariaDb, SIGNAL(clicked()), trayIcon, SLOT(stopMySQL()));
 }

void MainWindow::changeEvent(QEvent *event)
{
    switch (event->type())
    {
        //case QEvent::LanguageChange:
        //    this->ui->retranslateUi(this);
        //    break;
        case QEvent::WindowStateChange:
            {
                // minimize to tray (do not minimize to taskbar)
                if (this->windowState() & Qt::WindowMinimized)
                {
                    // @todo provide configuration options to let the user decide on this
                    //if (Preferences::instance().minimizeToTray())
                    //{
                        QTimer::singleShot(0, this, SLOT(hide()));
                    //}
                }

                break;
            }
        default:
            break;
    }

    QMainWindow::changeEvent(event);
}

void MainWindow::closeEvent(QCloseEvent *event)
{
    if (trayIcon->isVisible()) {
        QMessageBox::information(this, APP_NAME,
                                 tr("The program will keep running in the system tray.
"
                                    "To terminate the program, choose Quit in the context menu of the system tray."));
        hide();

        // do not propagate the event to the base class
        event->ignore();
    }
}

void MainWindow::setVisible(bool visible)
 {
     minimizeAction->setEnabled(visible);
     restoreAction->setEnabled(isMaximized() || !visible);
     QMainWindow::setVisible(visible);
 }

void MainWindow::iconActivated(QSystemTrayIcon::ActivationReason reason)
{
    switch (reason) {
        case QSystemTrayIcon::Trigger:
        case QSystemTrayIcon::DoubleClick:
        //case QSystemTrayIcon::MiddleClick:

            // clicking the tray icon, when the main window is hidden, shows the main window
            if(!isVisible()) {
                setVisible(true);
                setWindowState( windowState() & ( ~Qt::WindowMinimized | Qt::WindowActive ) );
            }
            else {
                // clicking the tray icon, when the main window is shown, hides it
                setVisible(false);
            }

            break;
        default:;
    }
}

QString MainWindow::getNginxVersion()
{
    QProcess* processNginx;

    processNginx = new QProcess(this);
    //processNginx->setWorkingDirectory(cfgNginxDir);
    //processNginx->start("./nginx", QStringList() << "-v");
    processNginx->waitForFinished(-1);

    //QString p_stdout = processNginx->readAllStandardOutput();
    QString p_stderr = processNginx->readAllStandardError();

    // test
    QString p_stdout = "nginx version: nginx/1.1.11";

    qDebug() << p_stdout;
    qDebug() << p_stderr;

    return parseVersionNumber(p_stdout);
}

QString MainWindow::getMariaVersion()
{
    QProcess* processMaria;

    processMaria = new QProcess(this);
    //processMaria->setWorkingDirectory(cfgMariaDir);
    processMaria->start("./mysqld", QStringList() << "-V"); // upper-case V
    processMaria->waitForFinished(-1);

    //QString p_stdout = processMaria->readAllStandardOutput();
    QString p_stderr = processMaria->readAllStandardError();

    // test
    QString p_stdout = "mysql  Ver 15.1 Distrib 5.5.23-MariaDB, for Win32 (x86)";

    qDebug() << p_stdout;
    qDebug() << p_stderr;

    return parseVersionNumber(p_stdout.mid(15));
}

QString MainWindow::getPHPVersion()
{
    QProcess* processPhp;

    processPhp = new QProcess(this);
    //processPhp->setWorkingDirectory(cfgPHPDir);
    //processPhp->start(cfgPHPDir+cfgPHPExec, QStringList() << "-v");
    processPhp->waitForFinished(-1);

    //QString p_stdout = processPhp->readAllStandardOutput();
    QString p_stderr = processPhp->readAllStandardError();

    // test
    QString p_stdout = "PHP 5.4.0 (cli) (built: Feb 29 2012 19:06:50)";

    qDebug() << p_stdout;
    qDebug() << p_stderr;

    return parseVersionNumber(p_stdout);
}

QString MainWindow::parseVersionNumber(QString stringWithVersion)
{
    qDebug() << stringWithVersion;

    // The RegExp for matching version numbers is (\d+\.)?(\d+\.)?(\d+\.)?(\*|\d+)
    // The following one is escaped:
    QRegExp regex("(\\d+\\.)?(\\d+\\.)?(\\d+\\.)?(\\*|\\d+)");

    // match
    regex.indexIn(stringWithVersion);

    qDebug() << regex.cap(0);
    QString cap = regex.cap(0);
    return cap;

// Leave this for debugging reasons
//    int pos = 0;
//    while((pos = regex.indexIn(stringWithVersion, pos)) != -1)
//    {
//        qDebug() << "Match at pos " << pos
//                 << " with length " << regex.matchedLength()
//                 << ", captured = " << regex.capturedTexts().at(0).toLatin1().data()
//                 << ".\n";
//        pos += regex.matchedLength();
//    }
}

void MainWindow::goToWebsite()
{
    QDesktopServices::openUrl(QUrl("http://wpn-xm.org/"));
}

void MainWindow::goToGoogleGroup()
{
    QDesktopServices::openUrl(QUrl("http://groups.google.com/group/wpn-xm/"));
}

void MainWindow::goToReportIssue()
{
    QDesktopServices::openUrl(QUrl("https://github.com/jakoch/WPN-XM/issues/"));
}

void MainWindow::goToDonate()
{
    QDesktopServices::openUrl(QUrl("http://wpn-xm.org/#donate"));
}

void MainWindow::openHelpDialog()
{

}

void MainWindow::openConfigurationDialog()
{

}

void MainWindow::openAboutDialog()
{
    QMessageBox::about(this, tr("About WPN-XM"),
              tr(""  APP_NAME_AND_VERSION "

"
                 "License: GNU/GPL v3+.

"
                 "Author(s): Yann Le Moigne (c) 2010, Jens-Andr Koch (c) 2011 - onwards.

"
                 "Website: http://wpn-xm.org/
"
                 "Github: https://github.com/jakoch/WPN-XM/"));
}
<|endoftext|>


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

#include <config.h>

// When defined, different heap allocators can be used via an environment
// variable set before running the program.  This may reduce the amount
// of inlining that we get with malloc/free/etc.  Disabling makes it
// so that only tcmalloc can be used.
#define ENABLE_DYNAMIC_ALLOCATOR_SWITCHING

// TODO(mbelshe): Ensure that all calls to tcmalloc have the proper call depth
// from the "user code" so that debugging tools (HeapChecker) can work.

// __THROW is defined in glibc systems.  It means, counter-intuitively,
// "This function will never throw an exception."  It's an optional
// optimization tool, but we may need to use it to match glibc prototypes.
#ifndef __THROW    // I guess we're not on a glibc system
# define __THROW   // __THROW is just an optimization, so ok to make it ""
#endif

// new_mode behaves similarly to MSVC's _set_new_mode.
// If flag is 0 (default), calls to malloc will behave normally.
// If flag is 1, calls to malloc will behave like calls to new,
// and the std_new_handler will be invoked on failure.
// Can be set by calling _set_new_mode().
static int new_mode = 0;

typedef enum {
  TCMALLOC,    // TCMalloc is the default allocator.
  JEMALLOC,    // JEMalloc
  WINDEFAULT,  // Windows Heap
  WINLFH,      // Windows LFH Heap
} Allocator;

// This is the default allocator.
static Allocator allocator = TCMALLOC;

// We include tcmalloc and the win_allocator to get as much inlining as
// possible.
#include "tcmalloc.cc"
#include "win_allocator.cc"

// Forward declarations from jemalloc.
extern "C" {
void* je_malloc(size_t s);
void* je_realloc(void* p, size_t s);
void je_free(void* s);
size_t je_msize(void* p);
bool je_malloc_init_hard();
}

extern "C" {

// Call the new handler, if one has been set.
// Returns true on successfully calling the handler, false otherwise.
inline bool call_new_handler(bool nothrow) {
  // Get the current new handler.  NB: this function is not
  // thread-safe.  We make a feeble stab at making it so here, but
  // this lock only protects against tcmalloc interfering with
  // itself, not with other libraries calling set_new_handler.
  std::new_handler nh;
  {
    SpinLockHolder h(&set_new_handler_lock);
    nh = std::set_new_handler(0);
    (void) std::set_new_handler(nh);
  }
#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
  if (!nh)
    return false;
  // Since exceptions are disabled, we don't really know if new_handler
  // failed.  Assume it will abort if it fails.
  (*nh)();
  return false;  // break out of the retry loop.
#else
  // If no new_handler is established, the allocation failed.
  if (!nh) {
    if (nothrow)
      return 0;
    throw std::bad_alloc();
  }
  // Otherwise, try the new_handler.  If it returns, retry the
  // allocation.  If it throws std::bad_alloc, fail the allocation.
  // if it throws something else, don't interfere.
  try {
    (*nh)();
  } catch (const std::bad_alloc&) {
    if (!nothrow)
      throw;
    return p;
  }
#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
}

void* malloc(size_t size) __THROW {
  void* ptr;
  for (;;) {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
    switch (allocator) {
      case JEMALLOC:
        ptr = je_malloc(size);
        break;
      case WINDEFAULT:
      case WINLFH:
        ptr = win_heap_malloc(size);
        break;
      case TCMALLOC:
      default:
        ptr = do_malloc(size);
        break;
    }
#else
    // TCMalloc case.
    ptr = do_malloc(size);
#endif
    if (ptr)
      return ptr;

    if (!new_mode || !call_new_handler(true))
      break;
  }
  return ptr;
}

void free(void* p) __THROW {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  switch (allocator) {
    case JEMALLOC:
      je_free(p);
      return;
    case WINDEFAULT:
    case WINLFH:
      win_heap_free(p);
      return;
  }
#endif
  // TCMalloc case.
  do_free(p);
}

void* realloc(void* ptr, size_t size) __THROW {
  void* new_ptr;
  for (;;) {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
    switch (allocator) {
      case JEMALLOC:
        new_ptr = je_realloc(ptr, size);
        break;
      case WINDEFAULT:
      case WINLFH:
        new_ptr = win_heap_realloc(ptr, size);
        break;
      case TCMALLOC:
      default:
        new_ptr = do_realloc(ptr, size);
        break;
    }
#else
    // TCMalloc case.
    new_ptr = do_realloc(ptr, size);
#endif

    // Subtle warning:  NULL return does not alwas indicate out-of-memory.  If
    // the requested new size is zero, realloc should free the ptr and return
    // NULL.
    if (new_ptr || !size)
      return new_ptr;
    if (!new_mode || !call_new_handler(true))
      break;
  }
  return new_ptr;
}

// TODO(mbelshe): Implement this for other allocators.
void malloc_stats(void) __THROW {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  switch (allocator) {
    case JEMALLOC:
      // No stats.
      return;
    case WINDEFAULT:
    case WINLFH:
      // No stats.
      return;
  }
#endif
  tc_malloc_stats();
}

#ifdef WIN32

extern "C" size_t _msize(void* p) {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  switch (allocator) {
    case JEMALLOC:
      return je_msize(p);
    case WINDEFAULT:
    case WINLFH:
      return win_heap_msize(p);
  }
#endif
  return MallocExtension::instance()->GetAllocatedSize(p);
}

// This is included to resolve references from libcmt.
extern "C" intptr_t _get_heap_handle() {
  return 0;
}

// The CRT heap initialization stub.
extern "C" int _heap_init() {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  const char* override = GetenvBeforeMain("CHROME_ALLOCATOR");
  if (override) {
    if (!stricmp(override, "jemalloc"))
      allocator = JEMALLOC;
    else if (!stricmp(override, "winheap"))
      allocator = WINDEFAULT;
    else if (!stricmp(override, "winlfh"))
      allocator = WINLFH;
    else if (!stricmp(override, "tcmalloc"))
      allocator = TCMALLOC;
  }

  switch (allocator) {
    case JEMALLOC:
      return je_malloc_init_hard() ? 0 : 1;
    case WINDEFAULT:
      return win_heap_init(false) ? 1 : 0;
    case WINLFH:
      return win_heap_init(true) ? 1 : 0;
    case TCMALLOC:
    default:
      // fall through
      break;
  }
#endif
  // Initializing tcmalloc.
  // We intentionally leak this object.  It lasts for the process
  // lifetime.  Trying to teardown at _heap_term() is so late that
  // you can't do anything useful anyway.
  new TCMallocGuard();
  return 1;
}

// The CRT heap cleanup stub.
extern "C" void _heap_term() {}

// We set this to 1 because part of the CRT uses a check of _crtheap != 0
// to test whether the CRT has been initialized.  Once we've ripped out
// the allocators from libcmt, we need to provide this definition so that
// the rest of the CRT is still usable.
extern "C" void* _crtheap = reinterpret_cast<void*>(1);

#endif  // WIN32

#include "generic_allocators.cc"

}  // extern C
<commit_msg>Set JEMalloc as the default allocator (instead of TCMalloc)<commit_after>// Copyright (c) 2009 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include <config.h>

// When defined, different heap allocators can be used via an environment
// variable set before running the program.  This may reduce the amount
// of inlining that we get with malloc/free/etc.  Disabling makes it
// so that only tcmalloc can be used.
#define ENABLE_DYNAMIC_ALLOCATOR_SWITCHING

// TODO(mbelshe): Ensure that all calls to tcmalloc have the proper call depth
// from the "user code" so that debugging tools (HeapChecker) can work.

// __THROW is defined in glibc systems.  It means, counter-intuitively,
// "This function will never throw an exception."  It's an optional
// optimization tool, but we may need to use it to match glibc prototypes.
#ifndef __THROW    // I guess we're not on a glibc system
# define __THROW   // __THROW is just an optimization, so ok to make it ""
#endif

// new_mode behaves similarly to MSVC's _set_new_mode.
// If flag is 0 (default), calls to malloc will behave normally.
// If flag is 1, calls to malloc will behave like calls to new,
// and the std_new_handler will be invoked on failure.
// Can be set by calling _set_new_mode().
static int new_mode = 0;

typedef enum {
  TCMALLOC,    // TCMalloc is the default allocator.
  JEMALLOC,    // JEMalloc
  WINDEFAULT,  // Windows Heap
  WINLFH,      // Windows LFH Heap
} Allocator;

// This is the default allocator.
static Allocator allocator = JEMALLOC;

// We include tcmalloc and the win_allocator to get as much inlining as
// possible.
#include "tcmalloc.cc"
#include "win_allocator.cc"

// Forward declarations from jemalloc.
extern "C" {
void* je_malloc(size_t s);
void* je_realloc(void* p, size_t s);
void je_free(void* s);
size_t je_msize(void* p);
bool je_malloc_init_hard();
}

extern "C" {

// Call the new handler, if one has been set.
// Returns true on successfully calling the handler, false otherwise.
inline bool call_new_handler(bool nothrow) {
  // Get the current new handler.  NB: this function is not
  // thread-safe.  We make a feeble stab at making it so here, but
  // this lock only protects against tcmalloc interfering with
  // itself, not with other libraries calling set_new_handler.
  std::new_handler nh;
  {
    SpinLockHolder h(&set_new_handler_lock);
    nh = std::set_new_handler(0);
    (void) std::set_new_handler(nh);
  }
#if (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
  if (!nh)
    return false;
  // Since exceptions are disabled, we don't really know if new_handler
  // failed.  Assume it will abort if it fails.
  (*nh)();
  return false;  // break out of the retry loop.
#else
  // If no new_handler is established, the allocation failed.
  if (!nh) {
    if (nothrow)
      return 0;
    throw std::bad_alloc();
  }
  // Otherwise, try the new_handler.  If it returns, retry the
  // allocation.  If it throws std::bad_alloc, fail the allocation.
  // if it throws something else, don't interfere.
  try {
    (*nh)();
  } catch (const std::bad_alloc&) {
    if (!nothrow)
      throw;
    return p;
  }
#endif  // (defined(__GNUC__) && !defined(__EXCEPTIONS)) || (defined(_HAS_EXCEPTIONS) && !_HAS_EXCEPTIONS)
}

void* malloc(size_t size) __THROW {
  void* ptr;
  for (;;) {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
    switch (allocator) {
      case JEMALLOC:
        ptr = je_malloc(size);
        break;
      case WINDEFAULT:
      case WINLFH:
        ptr = win_heap_malloc(size);
        break;
      case TCMALLOC:
      default:
        ptr = do_malloc(size);
        break;
    }
#else
    // TCMalloc case.
    ptr = do_malloc(size);
#endif
    if (ptr)
      return ptr;

    if (!new_mode || !call_new_handler(true))
      break;
  }
  return ptr;
}

void free(void* p) __THROW {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  switch (allocator) {
    case JEMALLOC:
      je_free(p);
      return;
    case WINDEFAULT:
    case WINLFH:
      win_heap_free(p);
      return;
  }
#endif
  // TCMalloc case.
  do_free(p);
}

void* realloc(void* ptr, size_t size) __THROW {
  void* new_ptr;
  for (;;) {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
    switch (allocator) {
      case JEMALLOC:
        new_ptr = je_realloc(ptr, size);
        break;
      case WINDEFAULT:
      case WINLFH:
        new_ptr = win_heap_realloc(ptr, size);
        break;
      case TCMALLOC:
      default:
        new_ptr = do_realloc(ptr, size);
        break;
    }
#else
    // TCMalloc case.
    new_ptr = do_realloc(ptr, size);
#endif

    // Subtle warning:  NULL return does not alwas indicate out-of-memory.  If
    // the requested new size is zero, realloc should free the ptr and return
    // NULL.
    if (new_ptr || !size)
      return new_ptr;
    if (!new_mode || !call_new_handler(true))
      break;
  }
  return new_ptr;
}

// TODO(mbelshe): Implement this for other allocators.
void malloc_stats(void) __THROW {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  switch (allocator) {
    case JEMALLOC:
      // No stats.
      return;
    case WINDEFAULT:
    case WINLFH:
      // No stats.
      return;
  }
#endif
  tc_malloc_stats();
}

#ifdef WIN32

extern "C" size_t _msize(void* p) {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  switch (allocator) {
    case JEMALLOC:
      return je_msize(p);
    case WINDEFAULT:
    case WINLFH:
      return win_heap_msize(p);
  }
#endif
  return MallocExtension::instance()->GetAllocatedSize(p);
}

// This is included to resolve references from libcmt.
extern "C" intptr_t _get_heap_handle() {
  return 0;
}

// The CRT heap initialization stub.
extern "C" int _heap_init() {
#ifdef ENABLE_DYNAMIC_ALLOCATOR_SWITCHING
  const char* override = GetenvBeforeMain("CHROME_ALLOCATOR");
  if (override) {
    if (!stricmp(override, "jemalloc"))
      allocator = JEMALLOC;
    else if (!stricmp(override, "winheap"))
      allocator = WINDEFAULT;
    else if (!stricmp(override, "winlfh"))
      allocator = WINLFH;
    else if (!stricmp(override, "tcmalloc"))
      allocator = TCMALLOC;
  }

  switch (allocator) {
    case JEMALLOC:
      return je_malloc_init_hard() ? 0 : 1;
    case WINDEFAULT:
      return win_heap_init(false) ? 1 : 0;
    case WINLFH:
      return win_heap_init(true) ? 1 : 0;
    case TCMALLOC:
    default:
      // fall through
      break;
  }
#endif
  // Initializing tcmalloc.
  // We intentionally leak this object.  It lasts for the process
  // lifetime.  Trying to teardown at _heap_term() is so late that
  // you can't do anything useful anyway.
  new TCMallocGuard();
  return 1;
}

// The CRT heap cleanup stub.
extern "C" void _heap_term() {}

// We set this to 1 because part of the CRT uses a check of _crtheap != 0
// to test whether the CRT has been initialized.  Once we've ripped out
// the allocators from libcmt, we need to provide this definition so that
// the rest of the CRT is still usable.
extern "C" void* _crtheap = reinterpret_cast<void*>(1);

#endif  // WIN32

#include "generic_allocators.cc"

}  // extern C
<|endoftext|>