<commit_before>#include <memory>
#include <toppra/algorithm.hpp>
#include <toppra/algorithm/toppra.hpp>
#include <toppra/constraint.hpp>
#include <toppra/constraint/linear_joint_acceleration.hpp>
#include <toppra/constraint/linear_joint_velocity.hpp>
#include <toppra/geometric_path.hpp>
#include <toppra/geometric_path/piecewise_poly_path.hpp>
#include <toppra/parametrizer/const_accel.hpp>
#include <toppra/toppra.hpp>

#include "gtest/gtest.h"

#define TEST_PRECISION 1e-6

// clang-format off

/* Code use to generate the test scenario using the Python implementation
// Diable format to keep python code identation

import toppra as ta
import numpy as np

path = ta.SplineInterpolator([0, 1, 2, 3], [[0, 0], [1, 3], [2, 4], [0, 0]])

def print_cpp_code(p):
    out = ""
    for seg_idx in range(p.cspl.c.shape[1]):
        out += "coeff{:d} << ".format(seg_idx)
        for i, t in enumerate(p.cspl.c[:, seg_idx, :].flatten().tolist()):
            if i == len(p.cspl.c[:, seg_idx, :].flatten().tolist()) - 1:
                out += "{:f};\n".format(t)
            else:
                out += "{:f}, ".format(t)
    return out

print(print_cpp_code(path))
print("breakpoints: {}".format([0, 1, 2, 3]))
x_eval = [0, 0.5, 1., 1.1, 2.5]
print("Eval for x_eval = {:}\npath(x_eval)=\n{}\npath(x_eval, 1)=\n{}\npath(x_eval, 2)=\n{}".format(
    x_eval, path(x_eval), path(x_eval, 1), path(x_eval, 2)))

pc_vel = ta.constraint.JointVelocityConstraint([1.0, 1.0])
pc_acc = ta.constraint.JointAccelerationConstraint([0.2, 0.2], discretization_scheme=0)

instance = ta.algorithm.TOPPRA([pc_vel, pc_acc], path, gridpoints=np.linspace(0, 3, 51), solver_wrapper='qpoases')
sdds, sds, _, K = instance.compute_parameterization(0, 0, return_data=True)
feasible_sets = instance.compute_feasible_sets().

 */
// clang-format on

class ProblemInstance : public testing::Test {
 public:
  ProblemInstance() {
    toppra::Matrix coeff0{4, 2}, coeff1{4, 2}, coeff2{4, 2};
    coeff0 << -0.500000, -0.500000, 1.500000, 0.500000, 0.000000, 3.000000, 0.000000,
        0.000000;
    coeff1 << -0.500000, -0.500000, 0.000000, -1.000000, 1.500000, 2.500000, 1.000000,
        3.000000;
    coeff2 << -0.500000, -0.500000, -1.500000, -2.500000, 0.000000, -1.000000, 2.000000,
        4.000000;
    toppra::Matrices coefficents = {coeff0, coeff1, coeff2};
    path = std::make_shared<toppra::PiecewisePolyPath>(coefficents, std::vector<double>{0, 1, 2, 3});
    v = toppra::LinearConstraintPtrs{
        std::make_shared<toppra::constraint::LinearJointVelocity>(
            -toppra::Vector::Ones(nDof), toppra::Vector::Ones(nDof)),
        std::make_shared<toppra::constraint::LinearJointAcceleration>(
            -0.2 * toppra::Vector::Ones(nDof), 0.2 * toppra::Vector::Ones(nDof))};
  };

  std::shared_ptr<toppra::PiecewisePolyPath> path;
  toppra::LinearConstraintPtrs v;
  int nDof = 2;
};

TEST_F(ProblemInstance, GridpointsHasCorrectShape) {
  toppra::algorithm::TOPPRA problem{v, path};
  problem.setN(50);
  problem.computePathParametrization();
  const auto& data = problem.getParameterizationData();

  ASSERT_EQ(data.gridpoints.size(), 51);
  ASSERT_TRUE(data.gridpoints.isApprox(toppra::Vector::LinSpaced(51, 0, 3)));
}

TEST_F(ProblemInstance, ControllableSets) {
  toppra::algorithm::TOPPRA problem{v, path};
  problem.setN(50);
  auto ret_code = problem.computePathParametrization();
  const auto& data = problem.getParameterizationData();
  toppra::Vector e_K_max(51);
  e_K_max << 0.06666667, 0.07624309, 0.08631706, 0.09690258, 0.1005511, 0.09982804,
      0.09979021, 0.1004364, 0.10178673, 0.10184412, 0.09655088, 0.09173679, 0.08734254,
      0.08331796, 0.07962037, 0.07621325, 0.07306521, 0.07014913, 0.0674415, 0.06492188,
      0.06257244, 0.06037764, 0.05832397, 0.05639984, 0.05459563, 0.05290407,
      0.05132158, 0.04985238, 0.04852317, 0.04745694, 0.04761905, 0.05457026,
      0.06044905, 0.06527948, 0.08479263, 0.10990991, 0.13252362, 0.15269631,
      0.15777077, 0.12111776, 0.09525987, 0.07641998, 0.06232537, 0.05154506,
      0.04314353, 0.03257513, 0.02268898, 0.01495548, 0.0088349, 0.00394283, 0.;

  ASSERT_EQ(ret_code, toppra::ReturnCode::OK)
      << "actual return code: " << (int)ret_code;
  for (int i = 0; i < 51; i++)
    EXPECT_NEAR(data.controllable_sets(i, 1), e_K_max(i), TEST_PRECISION)
        << "idx: " << i;
}

TEST_F(ProblemInstance, OutputParmetrization) {
  toppra::algorithm::TOPPRA problem{v, path};
  problem.setN(50);
  auto ret_code = problem.computePathParametrization();
  const auto& data = problem.getParameterizationData();
  toppra::Vector expected_parametrization(51);
  expected_parametrization << 0., 0.00799999, 0.01559927, 0.02295854, 0.03021812,
      0.0375065, 0.04494723, 0.05266502, 0.06079176, 0.06947278, 0.07887417, 0.08890758,
      0.08734253, 0.08331795, 0.07962036, 0.07621324, 0.0730652, 0.07014912, 0.06744149,
      0.06492187, 0.06257243, 0.06037763, 0.05832396, 0.05639983, 0.05459562,
      0.05290406, 0.05132157, 0.04985237, 0.04852316, 0.04745693, 0.04761904, 0.0285715,
      0.05376003, 0.04275653, 0.04126188, 0.04013804, 0.03912958, 0.03818766,
      0.03729606, 0.0364472, 0.03563649, 0.03486069, 0.03411724, 0.03340395, 0.03271895,
      0.03206054, 0.02268897, 0.01495547, 0.00883489, 0.00394282, 0.;

  ASSERT_EQ(ret_code, toppra::ReturnCode::OK)
      << "actual return code: " << (int)ret_code;

  for (int i = 0; i < 51; i++)
    EXPECT_NEAR(data.parametrization(i), expected_parametrization(i), TEST_PRECISION)
        << "idx: " << i
        << ", abs diff=" << data.parametrization(i) - expected_parametrization(i);

  // First and last must be zero.
  EXPECT_DOUBLE_EQ(data.parametrization(0), 0);
  EXPECT_DOUBLE_EQ(data.parametrization(50), 0);
}

TEST_F(ProblemInstance, FeasibleSets) {
  toppra::algorithm::TOPPRA problem{v, path};
  problem.setN(50);
  auto ret_code = problem.computeFeasibleSets();
  const auto& data = problem.getParameterizationData();
  toppra::Vector expected_feasible_max(51);
  expected_feasible_max << 0.06666667, 0.07624309, 0.08631706, 0.09690258, 0.1005511,
      0.09982804, 0.09979021, 0.1004364, 0.10178673, 0.10388394, 0.10679654, 0.11062383,
      0.11550389, 0.12162517, 0.12924407, 0.13871115, 0.15051124, 0.16532619,
      0.18413615, 0.20838854, 0.24029219, 0.27052997, 0.2601227, 0.2447933, 0.22462845,
      0.2, 0.17154989, 0.14013605, 0.10674847, 0.07241209, 0.04761905, 0.05457026,
      0.06044905, 0.06527948, 0.08479263, 0.10990991, 0.13252362, 0.15269631,
      0.15777077, 0.12111776, 0.09525987, 0.07641998, 0.06232537, 0.05154506,
      0.04314353, 0.03648939, 0.0311448, 0.02679888, 0.02322632, 0.02026086, 0.01777778;

  ASSERT_EQ(ret_code, toppra::ReturnCode::OK)
      << "actual return code: " << (int)ret_code;

  for (int i = 0; i < 51; i++)
    EXPECT_NEAR(data.feasible_sets(i, 1), expected_feasible_max(i), TEST_PRECISION)
        << "idx: " << i
        << ", abs diff=" << data.parametrization(i) - expected_feasible_max(i);
}

TEST_F(ProblemInstance, ParametrizeOutputTrajectory) {
  toppra::algorithm::TOPPRA problem{v, path};
  problem.setN(50);
  auto ret_code = problem.computePathParametrization();

  TOPPRA_LOG_DEBUG("Pre constructed");
  toppra::parametrizer::ConstAccel output_traj{
      path, problem.getParameterizationData().gridpoints,
      problem.getParameterizationData().parametrization};

  // Qualitative assertion
  ASSERT_TRUE(output_traj.validate());
  ASSERT_EQ(output_traj.pathInterval()[0], 0);
  ASSERT_GE(output_traj.pathInterval()[1], 0);
  auto interval = output_traj.pathInterval();

  // Qualitative assertion
  for (int i = 0; i < path->dof(); i++) {
    ASSERT_EQ(output_traj.eval_single(0)[i], path->eval_single(0)[i]);
    ASSERT_EQ(output_traj.eval_single(output_traj.pathInterval()[1])[i],
              path->eval_single(path->pathInterval()[1])[i]);
  }
}
<commit_msg>[C++] Run algo unit test for each solvers.<commit_after>#include <memory>
#include <toppra/algorithm.hpp>
#include <toppra/algorithm/toppra.hpp>
#include <toppra/constraint.hpp>
#include <toppra/constraint/linear_joint_acceleration.hpp>
#include <toppra/constraint/linear_joint_velocity.hpp>
#include <toppra/geometric_path.hpp>
#include <toppra/geometric_path/piecewise_poly_path.hpp>
#include <toppra/parametrizer/const_accel.hpp>
#ifdef BUILD_WITH_qpOASES
#include <toppra/solver/qpOASES-wrapper.hpp>
#endif
#ifdef BUILD_WITH_GLPK
#include <toppra/solver/glpk-wrapper.hpp>
#endif
#include <toppra/solver/seidel.hpp>
#include <toppra/toppra.hpp>

#include "gtest/gtest.h"

#define TEST_PRECISION 1e-6

// clang-format off

/* Code use to generate the test scenario using the Python implementation
// Diable format to keep python code identation

import toppra as ta
import numpy as np

path = ta.SplineInterpolator([0, 1, 2, 3], [[0, 0], [1, 3], [2, 4], [0, 0]])

def print_cpp_code(p):
    out = ""
    for seg_idx in range(p.cspl.c.shape[1]):
        out += "coeff{:d} << ".format(seg_idx)
        for i, t in enumerate(p.cspl.c[:, seg_idx, :].flatten().tolist()):
            if i == len(p.cspl.c[:, seg_idx, :].flatten().tolist()) - 1:
                out += "{:f};\n".format(t)
            else:
                out += "{:f}, ".format(t)
    return out

print(print_cpp_code(path))
print("breakpoints: {}".format([0, 1, 2, 3]))
x_eval = [0, 0.5, 1., 1.1, 2.5]
print("Eval for x_eval = {:}\npath(x_eval)=\n{}\npath(x_eval, 1)=\n{}\npath(x_eval, 2)=\n{}".format(
    x_eval, path(x_eval), path(x_eval, 1), path(x_eval, 2)))

pc_vel = ta.constraint.JointVelocityConstraint([1.0, 1.0])
pc_acc = ta.constraint.JointAccelerationConstraint([0.2, 0.2], discretization_scheme=0)

instance = ta.algorithm.TOPPRA([pc_vel, pc_acc], path, gridpoints=np.linspace(0, 3, 51), solver_wrapper='qpoases')
sdds, sds, _, K = instance.compute_parameterization(0, 0, return_data=True)
feasible_sets = instance.compute_feasible_sets().

 */
// clang-format on

template<typename Solver>
class ProblemInstance : public testing::Test {
 public:
  ProblemInstance() {
    toppra::Matrix coeff0{4, 2}, coeff1{4, 2}, coeff2{4, 2};
    coeff0 << -0.500000, -0.500000, 1.500000, 0.500000, 0.000000, 3.000000, 0.000000,
        0.000000;
    coeff1 << -0.500000, -0.500000, 0.000000, -1.000000, 1.500000, 2.500000, 1.000000,
        3.000000;
    coeff2 << -0.500000, -0.500000, -1.500000, -2.500000, 0.000000, -1.000000, 2.000000,
        4.000000;
    toppra::Matrices coefficents = {coeff0, coeff1, coeff2};
    path = std::make_shared<toppra::PiecewisePolyPath>(coefficents, std::vector<double>{0, 1, 2, 3});
    v = toppra::LinearConstraintPtrs{
        std::make_shared<toppra::constraint::LinearJointVelocity>(
            -toppra::Vector::Ones(nDof), toppra::Vector::Ones(nDof)),
        std::make_shared<toppra::constraint::LinearJointAcceleration>(
            -0.2 * toppra::Vector::Ones(nDof), 0.2 * toppra::Vector::Ones(nDof))};
  };

  std::shared_ptr<toppra::PiecewisePolyPath> path;
  toppra::LinearConstraintPtrs v;
  int nDof = 2;
};

using SolverTypes = ::testing::Types<
#ifdef BUILD_WITH_qpOASES
  toppra::solver::qpOASESWrapper,
#endif
#ifdef BUILD_WITH_GLPK
  // toppra::solver::GLPKWrapper, // Failure due to numerical issue.
#endif
  toppra::solver::Seidel>;
TYPED_TEST_SUITE(ProblemInstance, SolverTypes);

TYPED_TEST(ProblemInstance, ControllableSets) {
  toppra::algorithm::TOPPRA problem{this->v, this->path};
  problem.setN(50);
  problem.solver(std::make_shared<TypeParam>());
  auto ret_code = problem.computePathParametrization();
  const auto& data = problem.getParameterizationData();

  ASSERT_EQ(data.gridpoints.size(), 51);
  ASSERT_TRUE(data.gridpoints.isApprox(toppra::Vector::LinSpaced(51, 0, 3)));

  toppra::Vector e_K_max(51);
  e_K_max << 0.06666667, 0.07624309, 0.08631706, 0.09690258, 0.1005511, 0.09982804,
      0.09979021, 0.1004364, 0.10178673, 0.10184412, 0.09655088, 0.09173679, 0.08734254,
      0.08331796, 0.07962037, 0.07621325, 0.07306521, 0.07014913, 0.0674415, 0.06492188,
      0.06257244, 0.06037764, 0.05832397, 0.05639984, 0.05459563, 0.05290407,
      0.05132158, 0.04985238, 0.04852317, 0.04745694, 0.04761905, 0.05457026,
      0.06044905, 0.06527948, 0.08479263, 0.10990991, 0.13252362, 0.15269631,
      0.15777077, 0.12111776, 0.09525987, 0.07641998, 0.06232537, 0.05154506,
      0.04314353, 0.03257513, 0.02268898, 0.01495548, 0.0088349, 0.00394283, 0.;

  ASSERT_EQ(ret_code, toppra::ReturnCode::OK)
      << "actual return code: " << (int)ret_code;
  for (int i = 0; i < 51; i++)
    EXPECT_NEAR(data.controllable_sets(i, 1), e_K_max(i), TEST_PRECISION)
        << "idx: " << i;
}

TYPED_TEST(ProblemInstance, OutputParmetrization) {
  toppra::algorithm::TOPPRA problem{this->v, this->path};
  problem.setN(50);
  problem.solver(std::make_shared<TypeParam>());
  auto ret_code = problem.computePathParametrization();
  const auto& data = problem.getParameterizationData();
  toppra::Vector expected_parametrization(51);
  expected_parametrization << 0., 0.00799999, 0.01559927, 0.02295854, 0.03021812,
      0.0375065, 0.04494723, 0.05266502, 0.06079176, 0.06947278, 0.07887417, 0.08890758,
      0.08734253, 0.08331795, 0.07962036, 0.07621324, 0.0730652, 0.07014912, 0.06744149,
      0.06492187, 0.06257243, 0.06037763, 0.05832396, 0.05639983, 0.05459562,
      0.05290406, 0.05132157, 0.04985237, 0.04852316, 0.04745693, 0.04761904, 0.0285715,
      0.05376003, 0.04275653, 0.04126188, 0.04013804, 0.03912958, 0.03818766,
      0.03729606, 0.0364472, 0.03563649, 0.03486069, 0.03411724, 0.03340395, 0.03271895,
      0.03206054, 0.02268897, 0.01495547, 0.00883489, 0.00394282, 0.;

  ASSERT_EQ(ret_code, toppra::ReturnCode::OK)
      << "actual return code: " << (int)ret_code;

  for (int i = 0; i < 51; i++)
    EXPECT_NEAR(data.parametrization(i), expected_parametrization(i), TEST_PRECISION)
        << "idx: " << i
        << ", abs diff=" << data.parametrization(i) - expected_parametrization(i);

  // First and last must be zero.
  EXPECT_DOUBLE_EQ(data.parametrization(0), 0);
  EXPECT_DOUBLE_EQ(data.parametrization(50), 0);
}

TYPED_TEST(ProblemInstance, FeasibleSets) {
  toppra::algorithm::TOPPRA problem{this->v, this->path};
  problem.setN(50);
  problem.solver(std::make_shared<TypeParam>());
  auto ret_code = problem.computeFeasibleSets();
  const auto& data = problem.getParameterizationData();
  toppra::Vector expected_feasible_max(51);
  expected_feasible_max << 0.06666667, 0.07624309, 0.08631706, 0.09690258, 0.1005511,
      0.09982804, 0.09979021, 0.1004364, 0.10178673, 0.10388394, 0.10679654, 0.11062383,
      0.11550389, 0.12162517, 0.12924407, 0.13871115, 0.15051124, 0.16532619,
      0.18413615, 0.20838854, 0.24029219, 0.27052997, 0.2601227, 0.2447933, 0.22462845,
      0.2, 0.17154989, 0.14013605, 0.10674847, 0.07241209, 0.04761905, 0.05457026,
      0.06044905, 0.06527948, 0.08479263, 0.10990991, 0.13252362, 0.15269631,
      0.15777077, 0.12111776, 0.09525987, 0.07641998, 0.06232537, 0.05154506,
      0.04314353, 0.03648939, 0.0311448, 0.02679888, 0.02322632, 0.02026086, 0.01777778;

  ASSERT_EQ(ret_code, toppra::ReturnCode::OK)
      << "actual return code: " << (int)ret_code;

  for (int i = 0; i < 51; i++)
    EXPECT_NEAR(data.feasible_sets(i, 1), expected_feasible_max(i), TEST_PRECISION)
        << "idx: " << i
        << ", abs diff=" << data.parametrization(i) - expected_feasible_max(i);
}

TYPED_TEST(ProblemInstance, ParametrizeOutputTrajectory) {
  toppra::algorithm::TOPPRA problem{this->v, this->path};
  problem.setN(50);
  problem.solver(std::make_shared<TypeParam>());
  auto ret_code = problem.computePathParametrization();

  TOPPRA_LOG_DEBUG("Pre constructed");
  toppra::parametrizer::ConstAccel output_traj{
      this->path, problem.getParameterizationData().gridpoints,
      problem.getParameterizationData().parametrization};

  // Qualitative assertion
  ASSERT_TRUE(output_traj.validate());
  ASSERT_EQ(output_traj.pathInterval()[0], 0);
  ASSERT_GE(output_traj.pathInterval()[1], 0);
  auto interval = output_traj.pathInterval();

  // Qualitative assertion
  for (int i = 0; i < this->path->dof(); i++) {
    ASSERT_EQ(output_traj.eval_single(0)[i], this->path->eval_single(0)[i]);
    ASSERT_EQ(output_traj.eval_single(output_traj.pathInterval()[1])[i],
              this->path->eval_single(this->path->pathInterval()[1])[i]);
  }
}
<|endoftext|>


<commit_before>#include "types.h"
#include "user.h"
#include "unet.h"

int
main(void)
{
  int s;
  int r;

  s = socket(AF_INET, SOCK_STREAM, 0);
  if (s < 0)
    die("telnetd socket: %d\n", s);

  struct sockaddr_in sin;
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = htonl(INADDR_ANY);
  sin.sin_port = htons(23);
  r = bind(s, (struct sockaddr *)&sin, sizeof(sin));
  if (r < 0)
    die("telnetd bind: %d\n", r);

  r = listen(s, 5);
  if (r < 0)
    die("telnetd listen: %d\n", r);

  fprintf(1, "telnetd: port 23\n");

  for (;;) {
    socklen_t socklen;
    int ss;
    int pid;

    socklen = sizeof(sin);
    ss = accept(s, (struct sockaddr *)&sin, &socklen);
    if (ss < 0) {
      fprintf(2, "telnetd accept: %d\n", ss);
      continue;
    }
    fprintf(1, "telnetd: connection %s\n", ipaddr(&sin));

    pid = fork(0);
    if (pid < 0) {
      fprintf(2, "telnetd fork: %d\n", pid);
      close(ss);
      continue;
    }
    if (pid == 0) {
      static const char *argv[] = { "/login", 0 };
      close(0);
      close(1);
      close(2);
      dup(ss);
      dup(ss);
      dup(ss);
      exec(argv[0], argv);
      exit();
    }
    close(ss);
    wait(-1);
    fprintf(1, "telnetd: connection closed\n");
  }
}
<commit_msg>telnet: Accept concurrent connections<commit_after>#include "types.h"
#include "user.h"
#include "unet.h"

int
dfork(void)
{
  // First fork
  int pid = fork(0);
  if (pid < 0) {
    fprintf(2, "telnetd fork 1: %d\n", pid);
    return pid;
  } else if (pid > 0) {
    // Wait for intermediate process
    wait(-1);
    return pid;
  }

  // Second fork
  pid = fork(0);
  if (pid == 0) {
    // Second child does the real work
    return 0;
  } else if (pid < 0) {
    fprintf(2, "telnetd fork 2: %d\n", pid);
  }
  exit();
}

int
main(void)
{
  int s;
  int r;

  s = socket(AF_INET, SOCK_STREAM, 0);
  if (s < 0)
    die("telnetd socket: %d\n", s);

  struct sockaddr_in sin;
  sin.sin_family = AF_INET;
  sin.sin_addr.s_addr = htonl(INADDR_ANY);
  sin.sin_port = htons(23);
  r = bind(s, (struct sockaddr *)&sin, sizeof(sin));
  if (r < 0)
    die("telnetd bind: %d\n", r);

  r = listen(s, 5);
  if (r < 0)
    die("telnetd listen: %d\n", r);

  fprintf(1, "telnetd: port 23\n");

  for (;;) {
    socklen_t socklen;
    int ss;

    socklen = sizeof(sin);
    ss = accept(s, (struct sockaddr *)&sin, &socklen);
    if (ss < 0) {
      fprintf(2, "telnetd accept: %d\n", ss);
      continue;
    }
    fprintf(1, "telnetd: connection %s\n", ipaddr(&sin));

    if (dfork() == 0) {
      static const char *argv[] = { "/login", 0 };
      close(0);
      close(1);
      close(2);
      dup(ss);
      dup(ss);
      dup(ss);
      exec(argv[0], argv);
      exit();
    }
    close(ss);
  }
}
<|endoftext|>


<commit_before>//============================================================================
// Name        : Message.cpp
// Author      : ITM13
// Version     : 1.0
// Description :
//============================================================================
#pragma once

#include <Poco\HashMap.h>
#include <Poco\Logger.h>
#include <Poco\Exception.h>
#include <Poco\JSON\Parser.h>
#include <Poco\Dynamic\Var.h>
#include <Poco\JSON\Object.h>

#include "Message.h"
#include "MessageParams.h"

using std::string;
using std::stringstream;
using std::vector;
using Poco::HashMap;
using Poco::Logger;
using Poco::Dynamic::Var;
using Poco::JSON::Parser;
using Poco::JSON::Object;
using infrastructure::websocket::MessageHeaders;
using infrastructure::websocket::MessageHeaderEnum;

namespace infrastructure {
	namespace websocket {
		Message::Message(const string& cmd, const string& to, StringMap *params, const string& data)
			: cmd(cmd), to(to), data(data) {

			this->params = params == nullptr ? new StringMap() : params;
		}

		Message::Message(const Message& msg) : to(msg.to), cmd(msg.cmd), params(msg.params), data(msg.data) { }

		Message::~Message() {
			delete params;
			params = nullptr;
		}

		void Message::AddParam(const string& key, const string& value) {
			params->insert(StringMap::ValueType(key, value));
		}

		string Message::ToString() {
			stringstream stream;
			string comma = ", ";
			bool addComma = false;

			stream << "{ ";

			if (!to.empty()) {
				stream << "\"to\":\"" << to << "\"";
				addComma = true;
			}

			if (cmd.empty()) {
				//TODO ERROR?
			}

			if (addComma) {
				stream << comma;
			}

			stream << "\"cmd\":\"" << cmd << "\"";
			addComma = true;

			if (!params->empty()) {
				if (addComma) {
					stream << comma;
				}

				stream << "\"params\": { ";

				StringMap::Iterator iter = params->begin();
				while (iter != params->end())
				{
					stream << "\"" << iter->first << "\":" << "\"" << iter->second << "\"";

					++iter;

					if (iter != params->end()) {
						stream << ",";
					}
				}

				stream << " }";

				addComma = true;
			}

			if (!data.empty()) {
				if (addComma) {
					stream << comma;
				}

				stream << "\"data\":\"" << data << "\"";
			}

			stream << " }";
			return stream.str();
		}

		Message* Message::Parse(const string& message) {
			Logger& logger = Logger::get("WebSocketMessage");
			static StringMsgHeadersMap& map = MessageHeaders().GetMap();

			try {
				/* Protocol (based on JSON object)
				* {
				* 	 to: 'test',
				* 	 cmd: 'echo',
				*   params: {
				*	     toUpper: true
				*	 },
				*	 data: 'testdata'
				* }
				*/
				Parser parser;

				std::istringstream istr(message);
				parser.parse(istr);

				Object::Ptr root = parser.result().extract<Object::Ptr>();
				Message* tempMessage = new Message();

				vector<string> names;
				root->getNames(names);

				Object::Ptr params;
				vector<string> paramsNames;

				for (vector<string>::size_type i = 0; i != names.size(); i++) {

					switch (map[names[i]])
					{
					case MessageHeaderEnum::to:
						tempMessage->to = root->getValue<string>(names[i]);
						break;
					case MessageHeaderEnum::cmd:
						tempMessage->cmd = root->getValue<string>(names[i]);
						break;
					case MessageHeaderEnum::params:
						params = root->getObject(names[i]);
						params->getNames(paramsNames);

						for (vector<string>::size_type j = 0; j != paramsNames.size(); j++) {
							tempMessage->AddParam(paramsNames[j], params->getValue<string>(paramsNames[j]));
						}
						break;
					case MessageHeaderEnum::data:
						tempMessage->data = root->getValue<string>(names[i]);
						break;
					default:
						break;
					}
				}

				return tempMessage;
			}
			catch (Poco::Exception& e)  {
				logger.warning(e.displayText());
			}

			return nullptr;
		}
	}
}<commit_msg>fixed include - error caused by renaming<commit_after>//============================================================================
// Name        : Message.cpp
// Author      : ITM13
// Version     : 1.0
// Description :
//============================================================================
#pragma once

#include <Poco\HashMap.h>
#include <Poco\Logger.h>
#include <Poco\Exception.h>
#include <Poco\JSON\Parser.h>
#include <Poco\Dynamic\Var.h>
#include <Poco\JSON\Object.h>

#include "Message.h"
#include "MessageHeaders.h"

using std::string;
using std::stringstream;
using std::vector;
using Poco::HashMap;
using Poco::Logger;
using Poco::Dynamic::Var;
using Poco::JSON::Parser;
using Poco::JSON::Object;
using infrastructure::websocket::MessageHeaders;
using infrastructure::websocket::MessageHeaderEnum;

namespace infrastructure {
	namespace websocket {
		Message::Message(const string& cmd, const string& to, StringMap *params, const string& data)
			: cmd(cmd), to(to), data(data) {

			this->params = params == nullptr ? new StringMap() : params;
		}

		Message::Message(const Message& msg) : to(msg.to), cmd(msg.cmd), params(msg.params), data(msg.data) { }

		Message::~Message() {
			delete params;
			params = nullptr;
		}

		void Message::AddParam(const string& key, const string& value) {
			params->insert(StringMap::ValueType(key, value));
		}

		string Message::ToString() {
			stringstream stream;
			string comma = ", ";
			bool addComma = false;

			stream << "{ ";

			if (!to.empty()) {
				stream << "\"to\":\"" << to << "\"";
				addComma = true;
			}

			if (cmd.empty()) {
				//TODO ERROR?
			}

			if (addComma) {
				stream << comma;
			}

			stream << "\"cmd\":\"" << cmd << "\"";
			addComma = true;

			if (!params->empty()) {
				if (addComma) {
					stream << comma;
				}

				stream << "\"params\": { ";

				StringMap::Iterator iter = params->begin();
				while (iter != params->end())
				{
					stream << "\"" << iter->first << "\":" << "\"" << iter->second << "\"";

					++iter;

					if (iter != params->end()) {
						stream << ",";
					}
				}

				stream << " }";

				addComma = true;
			}

			if (!data.empty()) {
				if (addComma) {
					stream << comma;
				}

				stream << "\"data\":\"" << data << "\"";
			}

			stream << " }";
			return stream.str();
		}

		Message* Message::Parse(const string& message) {
			Logger& logger = Logger::get("WebSocketMessage");
			static StringMsgHeadersMap& map = MessageHeaders().GetMap();

			try {
				/* Protocol (based on JSON object)
				* {
				* 	 to: 'test',
				* 	 cmd: 'echo',
				*   params: {
				*	     toUpper: true
				*	 },
				*	 data: 'testdata'
				* }
				*/
				Parser parser;

				std::istringstream istr(message);
				parser.parse(istr);

				Object::Ptr root = parser.result().extract<Object::Ptr>();
				Message* tempMessage = new Message();

				vector<string> names;
				root->getNames(names);

				Object::Ptr params;
				vector<string> paramsNames;

				for (vector<string>::size_type i = 0; i != names.size(); i++) {

					switch (map[names[i]])
					{
					case MessageHeaderEnum::to:
						tempMessage->to = root->getValue<string>(names[i]);
						break;
					case MessageHeaderEnum::cmd:
						tempMessage->cmd = root->getValue<string>(names[i]);
						break;
					case MessageHeaderEnum::params:
						params = root->getObject(names[i]);
						params->getNames(paramsNames);

						for (vector<string>::size_type j = 0; j != paramsNames.size(); j++) {
							tempMessage->AddParam(paramsNames[j], params->getValue<string>(paramsNames[j]));
						}
						break;
					case MessageHeaderEnum::data:
						tempMessage->data = root->getValue<string>(names[i]);
						break;
					default:
						break;
					}
				}

				return tempMessage;
			}
			catch (Poco::Exception& e)  {
				logger.warning(e.displayText());
			}

			return nullptr;
		}
	}
}<|endoftext|>


<commit_before>#include "lcxl_string.h"
// 需包含locale、string头文件、使用setlocale函数。
#include <locale>
#include <algorithm>
#include <functional>
#include <cctype>
#include <stdarg.h>
#ifdef WIN32
#include <windows.h>
#endif
std::wstring string_to_wstring(const std::string &str)
{
	// string转wstring
	size_t len = str.size() * 2;// 预留字节数
	setlocale(LC_CTYPE, "");     //必须调用此函数
	wchar_t *p = new wchar_t[len];// 申请一段内存存放转换后的字符串
	size_t newlen = mbstowcs(p, str.c_str(), len);// 转换
	std::wstring str1;
	if (newlen > 0) {
		str1 = p;
	}
	delete[] p;// 释放申请的内存
	return str1;
}

std::string wstring_to_string(const std::wstring &str)
{
	// wstring转string
	size_t len = str.size() * 4;
	setlocale(LC_CTYPE, "");
	char *p = new char[len];
	size_t newlen = wcstombs(p, str.c_str(), len);
	std::string str1;
	if (newlen > 0) {
		str1 = p;
	}
	delete[] p;
	return str1;
}

std::wstring utf8string_to_wstring(const std::string &str)
{
	wchar_t *result;
	int textlen;
	std::wstring str1;

	textlen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);

	result = (wchar_t *)malloc((textlen + 1)*sizeof(wchar_t));
	if (result != NULL) {
		memset(result, 0, sizeof(wchar_t)* (textlen + 1));
		MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, result, textlen);
		str1 = result;
		free(result);
	}
	return str1;
}

std::string wstring_to_utf8string(const std::wstring &str)
{
	char* result;
	int textlen;
	textlen = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL);

	result = (char *)malloc((textlen + 1)*sizeof(char));
	memset(result, 0, sizeof(char)* (textlen + 1));
	WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, result, textlen, NULL, NULL);

	std::string str1(result);
	free(result);
	return str1;
}

// trim from start
std::string &ltrim(std::string &_Str) {
	_Str.erase(_Str.begin(), std::find_if(_Str.begin(), _Str.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
	return _Str;
}

std::wstring & ltrim(std::wstring &_Str)
{
	_Str.erase(_Str.begin(), std::find_if(_Str.begin(), _Str.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
	return _Str;
}

// trim from end
std::string &rtrim(std::string &_Str) {
	_Str.erase(std::find_if(_Str.rbegin(), _Str.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _Str.end());
	return _Str;
}

std::wstring & rtrim(std::wstring &_Str)
{
	_Str.erase(std::find_if(_Str.rbegin(), _Str.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _Str.end());
	return _Str;
}

// trim from both ends
std::string &trim(std::string &_Str) {
	return ltrim(rtrim(_Str));
}

std::wstring & trim(std::wstring &_Str)
{
	return ltrim(rtrim(_Str));
}

std::string string_format(const std::string fmt, ...)
{
	int size = 100;
	std::string str;
	va_list ap;
	while (1) {
		str.resize(size);
		va_start(ap, fmt);
		int n = vsnprintf(const_cast<char*>(str.c_str()), size, fmt.c_str(), ap);
		va_end(ap);
		if (n > -1 && n < size) {
			str.resize(n);
			return str;
		}
		if (n > -1)
			size = n + 1;
		else
			size *= 2;
	}
	return str;
}

std::wstring wstring_format(const std::wstring fmt, ...)
{
	int size = 100;
	std::wstring str;
	va_list ap;
	while (1) {
		str.resize(size);
		va_start(ap, fmt);
		int n = _vsnwprintf(const_cast<wchar_t*>(str.c_str()), size, fmt.c_str(), ap);
		va_end(ap);
		if (n > -1 && n < size) {
			str.resize(n);
			return str;
		}
		if (n > -1)
			size = n + 1;
		else
			size *= 2;
	}
	return str;
}

int string_to_mac(const std::string str, unsigned char mac[], int mac_size)
{
	int len = (str.length() + 1) / 3;
	int i;

	if (len > mac_size) {
		return -1;
	}
	for (i = 0; i < len; i++) {
		str.substr(i*3, 2);
		mac[i] = (unsigned char)strtol(str.substr(i * 3, 2).c_str(), NULL, 16);
	}
	return len;
}
<commit_msg>完善字符串操作<commit_after>#include "lcxl_string.h"
// 需包含locale、string头文件、使用setlocale函数。
#include <locale>
#include <algorithm>
#include <functional>
#include <cctype>
#include <stdarg.h>
#ifdef WIN32
#include <windows.h>
#endif
std::wstring string_to_wstring(const std::string &str)
{
	// string转wstring
	size_t len = str.size() * 2;// 预留字节数
	setlocale(LC_CTYPE, "");     //必须调用此函数
	wchar_t *p = new wchar_t[len];// 申请一段内存存放转换后的字符串
	size_t newlen = mbstowcs(p, str.c_str(), len);// 转换
	std::wstring str1;
	if (newlen > 0) {
		str1 = p;
	}
	delete[] p;// 释放申请的内存
	return str1;
}

std::string wstring_to_string(const std::wstring &str)
{
	// wstring转string
	size_t len = str.size() * 4;
	setlocale(LC_CTYPE, "");
	char *p = new char[len];
	size_t newlen = wcstombs(p, str.c_str(), len);
	std::string str1;
	if (newlen > 0) {
		str1 = p;
	}
	delete[] p;
	return str1;
}

std::wstring utf8string_to_wstring(const std::string &str)
{
	wchar_t *result;
	int textlen;
	std::wstring str1;

	textlen = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, NULL, 0);
	if (textlen > 0) {
		result = (wchar_t *)malloc((textlen + 1)*sizeof(wchar_t));
		if (result != NULL) {
			memset(result, 0, sizeof(wchar_t)* (textlen + 1));
			MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, result, textlen);
			str1 = result;
			free(result);
		}
	}

	return str1;
}

std::string wstring_to_utf8string(const std::wstring &str)
{
	char* result;
	int textlen;
	std::string str1;
	textlen = WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, NULL, 0, NULL, NULL);
	if (textlen > 0) {
		result = (char *)malloc((textlen + 1)*sizeof(char));
		if (result != NULL) {
			memset(result, 0, sizeof(char)* (textlen + 1));
			WideCharToMultiByte(CP_UTF8, 0, str.c_str(), -1, result, textlen, NULL, NULL);

			str1 = result;
			free(result);
		}
	}

	return str1;
}

// trim from start
std::string &ltrim(std::string &_Str) {
	_Str.erase(_Str.begin(), std::find_if(_Str.begin(), _Str.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
	return _Str;
}

std::wstring & ltrim(std::wstring &_Str)
{
	_Str.erase(_Str.begin(), std::find_if(_Str.begin(), _Str.end(), std::not1(std::ptr_fun<int, int>(std::isspace))));
	return _Str;
}

// trim from end
std::string &rtrim(std::string &_Str) {
	_Str.erase(std::find_if(_Str.rbegin(), _Str.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _Str.end());
	return _Str;
}

std::wstring & rtrim(std::wstring &_Str)
{
	_Str.erase(std::find_if(_Str.rbegin(), _Str.rend(), std::not1(std::ptr_fun<int, int>(std::isspace))).base(), _Str.end());
	return _Str;
}

// trim from both ends
std::string &trim(std::string &_Str) {
	return ltrim(rtrim(_Str));
}

std::wstring & trim(std::wstring &_Str)
{
	return ltrim(rtrim(_Str));
}

std::string string_format(const std::string fmt, ...)
{
	int size = 100;
	std::string str;
	va_list ap;
	while (1) {
		str.resize(size);
		va_start(ap, fmt);
		int n = vsnprintf(const_cast<char*>(str.c_str()), size, fmt.c_str(), ap);
		va_end(ap);
		if (n > -1 && n < size) {
			str.resize(n);
			return str;
		}
		if (n > -1)
			size = n + 1;
		else
			size *= 2;
	}
	return str;
}

std::wstring wstring_format(const std::wstring fmt, ...)
{
	int size = 100;
	std::wstring str;
	va_list ap;
	while (1) {
		str.resize(size);
		va_start(ap, fmt);
		int n = _vsnwprintf(const_cast<wchar_t*>(str.c_str()), size, fmt.c_str(), ap);
		va_end(ap);
		if (n > -1 && n < size) {
			str.resize(n);
			return str;
		}
		if (n > -1)
			size = n + 1;
		else
			size *= 2;
	}
	return str;
}

int string_to_mac(const std::string str, unsigned char mac[], int mac_size)
{
	int len = (str.length() + 1) / 3;
	int i;

	if (len > mac_size) {
		return -1;
	}
	for (i = 0; i < len; i++) {
		str.substr(i*3, 2);
		mac[i] = (unsigned char)strtol(str.substr(i * 3, 2).c_str(), NULL, 16);
	}
	return len;
}
<|endoftext|>


<commit_before>/*
 * src/AtomSpace/utils.cc
 *
 * Copyright (C) 2002-2007 Novamente LLC
 * All Rights Reserved
 *
 * Written by Thiago Maia <thiago@vettatech.com>
 *            Andre Senna <senna@vettalabs.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdlib.h>
#include <string>
#include <time.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/time.h>
#endif

#include "utils.h"
#include <opencog/util/platform.h>

using namespace opencog;

namespace opencog {

/**
 * Time used as reference to set/get timestamps over the code
 * Used as a handy-dandy but crude profiling utility
 */
static timeval referenceTime;
static bool referenceTimeInitialized = false;

void initReferenceTime()
{
    gettimeofday(&referenceTime, NULL);
    referenceTimeInitialized = true;
}

unsigned long getElapsedMillis()
{
    cassert(TRACE_INFO, referenceTimeInitialized,
            "utils - refenceTimeInitialized should have been initialized.");
    timeval currentTime;
    gettimeofday(&currentTime, NULL);
    return (currentTime.tv_sec -referenceTime.tv_sec)*1000 + (currentTime.tv_usec - referenceTime.tv_usec) / 1000;
}

};

<commit_msg>change copyright, there is no original code left here, except some  timeing/trace-debugging routines that I wrote ... <commit_after>/*
 * src/AtomSpace/utils.cc
 *
 * Copyright (C) 2008 Linas Vepstas
 * All Rights Reserved
 *
 * Written by Linas Vepstas <linasvepstas@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * 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 Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <stdlib.h>
#include <string>
#include <time.h>
#ifdef WIN32
#include <winsock2.h>
#else
#include <sys/time.h>
#endif

#include "utils.h"
#include <opencog/util/platform.h>

using namespace opencog;

namespace opencog {

/**
 * Time used as reference to set/get timestamps over the code
 * Used as a handy-dandy but crude profiling utility
 */
static timeval referenceTime;
static bool referenceTimeInitialized = false;

void initReferenceTime()
{
    gettimeofday(&referenceTime, NULL);
    referenceTimeInitialized = true;
}

unsigned long getElapsedMillis()
{
    cassert(TRACE_INFO, referenceTimeInitialized,
            "utils - refenceTimeInitialized should have been initialized.");
    timeval currentTime;
    gettimeofday(&currentTime, NULL);
    return (currentTime.tv_sec -referenceTime.tv_sec)*1000 + (currentTime.tv_usec - referenceTime.tv_usec) / 1000;
}

};

<|endoftext|>


<commit_before>// @(#)root/meta:$Id$
// Author: Markus Frank 20/05/2005

/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/

#include "TClass.h"
#include "TError.h"
#include "TInterpreter.h"
#include "TIsAProxy.h"

#include <map>
#include <type_traits>

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TClass                                                               //
//                                                                      //
// TIsAProxy implementation class.                                      //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

namespace {
   struct DynamicType {
      // Helper class to enable typeid on any address
      // Used in code similar to:
      //    typeid( * (DynamicType*) void_ptr );
      virtual ~DynamicType() {}
   };

   typedef std::map<const void*, TClass*> ClassMap_t; // Internal type map
   inline ClassMap_t *GetMap(const void* p)
   {
      return (ClassMap_t*)p;
   }

   inline ClassMap_t::value_type* ToPair(void*p)
   {
      return (ClassMap_t::value_type*)p;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Standard initializing constructor

TIsAProxy::TIsAProxy(const std::type_info& typ)
   : fType(&typ), fClass(nullptr), fLast(nullptr),
     fSubTypesReaders(0), fSubTypesWriteLockTaken(kFALSE),
     fVirtual(kFALSE), fInit(kFALSE)
{
   static_assert(sizeof(ClassMap_t)<=sizeof(fSubTypes), "ClassMap size is to large for array");

   ::new(fSubTypes) ClassMap_t();
}

////////////////////////////////////////////////////////////////////////////////
/// Standard destructor

TIsAProxy::~TIsAProxy()
{
   ClassMap_t* m = GetMap(fSubTypes);
   m->clear();
   m->~ClassMap_t();
}

////////////////////////////////////////////////////////////////////////////////
/// Set class pointer
///   This method is not thread safe

void TIsAProxy::SetClass(TClass *cl)
{
   GetMap(fSubTypes)->clear();
   fClass = cl;
   fLast = nullptr;
}

////////////////////////////////////////////////////////////////////////////////
/// IsA callback

TClass* TIsAProxy::operator()(const void *obj)
{
   if ( !fInit )  {
      if ( !fClass.load() && fType ) {
         auto cls = TClass::GetClass(*fType);
         TClass* expected = nullptr;
         fClass.compare_exchange_strong(expected,cls);
      }
      if ( !fClass.load() ) return nullptr;
      fVirtual = (*fClass).ClassProperty() & kClassHasVirtual;
      fInit = kTRUE;
   }
   if ( !obj || !fVirtual )  {
      return fClass.load();
   }
   // Avoid the case that the first word is a virtual_base_offset_table instead of
   // a virtual_function_table
   Long_t offset = **(Long_t**)obj;
   if ( offset == 0 ) {
      return fClass.load();
   }

   DynamicType* ptr = (DynamicType*)obj;
   const std::type_info* typ = &typeid(*ptr);

   if ( typ == fType )  {
     return fClass.load();
   }
   auto last = ToPair(fLast.load());
   if ( last && typ == last->first )  {
      return last->second;
   }
   // Check if type is already in sub-class cache
   last = ToPair(FindSubType(typ));
   if ( last == nullptr || last->second == nullptr )  {
      // Last resort: lookup root class
      auto cls = TClass::GetClass(*typ);
      last = ToPair(CacheSubType(typ,cls));
   }
   fLast.store(last);

   return last == nullptr? nullptr: last->second;
}

////////////////////////////////////////////////////////////////////////////////
/// See if we have already cached the TClass that correspond to this type_info.

inline void* TIsAProxy::FindSubType(const type_info* type) const
{
   bool needToWait = kTRUE;
   do {
     ++fSubTypesReaders;

     //See if there is a writer, if there is we need to release
     // our reader count so that the writer can proceed
     if(fSubTypesWriteLockTaken) {
       --fSubTypesReaders;
       while(fSubTypesWriteLockTaken) {}
     } else {
       needToWait = kFALSE;
     }
   } while(needToWait);

   void* returnValue = nullptr;
   auto const map = GetMap(fSubTypes);

   auto found = map->find(type);
   if(found != map->end()) {
      returnValue = &(*found);
   }
   --fSubTypesReaders;
   return returnValue;
}

////////////////////////////////////////////////////////////////////////////////
/// Record the TClass found for a type_info, so that we can retrieved it faster.

void* TIsAProxy::CacheSubType(const type_info* type, TClass* cls)
{
   //See if another thread has the write lock, wait if it does
   Bool_t expected = kFALSE;
   while(! fSubTypesWriteLockTaken.compare_exchange_strong(expected,kTRUE) ) {
      expected = kFALSE;
   };

   //See if there are any readers
   while(fSubTypesReaders > 0);

   auto map = GetMap(fSubTypes);
   auto ret = map->emplace(type,cls);
   if (!ret.second) {
      // type is already in the map, let's update it.
      (*ret.first).second = cls;
   }

   fSubTypesWriteLockTaken = kFALSE;
   return &(*(ret.first));
}
<commit_msg>Doxygen<commit_after>// @(#)root/meta:$Id$
// Author: Markus Frank 20/05/2005

/*************************************************************************
* Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
* All rights reserved.                                                  *
*                                                                       *
* For the licensing terms see $ROOTSYS/LICENSE.                         *
* For the list of contributors see $ROOTSYS/README/CREDITS.             *
*************************************************************************/

#include "TClass.h"
#include "TError.h"
#include "TInterpreter.h"
#include "TIsAProxy.h"

#include <map>
#include <type_traits>

/** \class TIsAProxy
TIsAProxy implementation class.
*/

namespace {
   struct DynamicType {
      // Helper class to enable typeid on any address
      // Used in code similar to:
      //    typeid( * (DynamicType*) void_ptr );
      virtual ~DynamicType() {}
   };

   typedef std::map<const void*, TClass*> ClassMap_t; // Internal type map
   inline ClassMap_t *GetMap(const void* p)
   {
      return (ClassMap_t*)p;
   }

   inline ClassMap_t::value_type* ToPair(void*p)
   {
      return (ClassMap_t::value_type*)p;
   }
}

////////////////////////////////////////////////////////////////////////////////
/// Standard initializing constructor

TIsAProxy::TIsAProxy(const std::type_info& typ)
   : fType(&typ), fClass(nullptr), fLast(nullptr),
     fSubTypesReaders(0), fSubTypesWriteLockTaken(kFALSE),
     fVirtual(kFALSE), fInit(kFALSE)
{
   static_assert(sizeof(ClassMap_t)<=sizeof(fSubTypes), "ClassMap size is to large for array");

   ::new(fSubTypes) ClassMap_t();
}

////////////////////////////////////////////////////////////////////////////////
/// Standard destructor

TIsAProxy::~TIsAProxy()
{
   ClassMap_t* m = GetMap(fSubTypes);
   m->clear();
   m->~ClassMap_t();
}

////////////////////////////////////////////////////////////////////////////////
/// Set class pointer
///   This method is not thread safe

void TIsAProxy::SetClass(TClass *cl)
{
   GetMap(fSubTypes)->clear();
   fClass = cl;
   fLast = nullptr;
}

////////////////////////////////////////////////////////////////////////////////
/// IsA callback

TClass* TIsAProxy::operator()(const void *obj)
{
   if ( !fInit )  {
      if ( !fClass.load() && fType ) {
         auto cls = TClass::GetClass(*fType);
         TClass* expected = nullptr;
         fClass.compare_exchange_strong(expected,cls);
      }
      if ( !fClass.load() ) return nullptr;
      fVirtual = (*fClass).ClassProperty() & kClassHasVirtual;
      fInit = kTRUE;
   }
   if ( !obj || !fVirtual )  {
      return fClass.load();
   }
   // Avoid the case that the first word is a virtual_base_offset_table instead of
   // a virtual_function_table
   Long_t offset = **(Long_t**)obj;
   if ( offset == 0 ) {
      return fClass.load();
   }

   DynamicType* ptr = (DynamicType*)obj;
   const std::type_info* typ = &typeid(*ptr);

   if ( typ == fType )  {
     return fClass.load();
   }
   auto last = ToPair(fLast.load());
   if ( last && typ == last->first )  {
      return last->second;
   }
   // Check if type is already in sub-class cache
   last = ToPair(FindSubType(typ));
   if ( last == nullptr || last->second == nullptr )  {
      // Last resort: lookup root class
      auto cls = TClass::GetClass(*typ);
      last = ToPair(CacheSubType(typ,cls));
   }
   fLast.store(last);

   return last == nullptr? nullptr: last->second;
}

////////////////////////////////////////////////////////////////////////////////
/// See if we have already cached the TClass that correspond to this type_info.

inline void* TIsAProxy::FindSubType(const type_info* type) const
{
   bool needToWait = kTRUE;
   do {
     ++fSubTypesReaders;

     //See if there is a writer, if there is we need to release
     // our reader count so that the writer can proceed
     if(fSubTypesWriteLockTaken) {
       --fSubTypesReaders;
       while(fSubTypesWriteLockTaken) {}
     } else {
       needToWait = kFALSE;
     }
   } while(needToWait);

   void* returnValue = nullptr;
   auto const map = GetMap(fSubTypes);

   auto found = map->find(type);
   if(found != map->end()) {
      returnValue = &(*found);
   }
   --fSubTypesReaders;
   return returnValue;
}

////////////////////////////////////////////////////////////////////////////////
/// Record the TClass found for a type_info, so that we can retrieved it faster.

void* TIsAProxy::CacheSubType(const type_info* type, TClass* cls)
{
   //See if another thread has the write lock, wait if it does
   Bool_t expected = kFALSE;
   while(! fSubTypesWriteLockTaken.compare_exchange_strong(expected,kTRUE) ) {
      expected = kFALSE;
   };

   //See if there are any readers
   while(fSubTypesReaders > 0);

   auto map = GetMap(fSubTypes);
   auto ret = map->emplace(type,cls);
   if (!ret.second) {
      // type is already in the map, let's update it.
      (*ret.first).second = cls;
   }

   fSubTypesWriteLockTaken = kFALSE;
   return &(*(ret.first));
}
<|endoftext|>


<commit_before>//
// Copyright (c) 2018 The nanoFramework project contributors
// Portions Copyright (c) Microsoft Corporation.  All rights reserved.
// See LICENSE file in the project root for full license information.
//

#include "sys_net_native.h"

static const CLR_RT_MethodHandler method_lookup[] =
{
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::socket___STATIC__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::bind___STATIC__VOID__OBJECT__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::connect___STATIC__VOID__OBJECT__SZARRAY_U1__BOOLEAN,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::send___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::recv___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::close___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::listen___STATIC__VOID__OBJECT__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::accept___STATIC__I4__OBJECT,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getaddrinfo___STATIC__VOID__STRING__BYREF_STRING__BYREF_SZARRAY_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::shutdown___STATIC__VOID__OBJECT__I4__BYREF_I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::sendto___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::recvfrom___STATIC__I4__OBJECT__SZARRAY_U1__I4__I4__I4__I4__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getpeername___STATIC__VOID__OBJECT__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getsockname___STATIC__VOID__OBJECT__BYREF_SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::getsockopt___STATIC__VOID__OBJECT__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::setsockopt___STATIC__VOID__OBJECT__I4__I4__SZARRAY_U1,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::poll___STATIC__BOOLEAN__OBJECT__I4__I4,
    Library_sys_net_native_System_Net_Sockets_NativeSocket::ioctl___STATIC__VOID__OBJECT__U4__BYREF_U4,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
    NULL,
};

const CLR_RT_NativeAssemblyData g_CLR_AssemblyNative_System_Net =
{
    "System.Net",
    0xDE2F601A,
    method_lookup,
    { 1, 0, 0, 0 }
};
<commit_msg>Remove unused network code from targets/ChibiOS folder<commit_after><|endoftext|>


<commit_before>/*
 * Copyright 2011 Christoph Bumiller
 *
 * 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 "codegen/nv50_ir_util.h"

namespace nv50_ir {

void DLList::clear()
{
   for (Item *next, *item = head.next; item != &head; item = next) {
      next = item->next;
      delete item;
   }
   head.next = head.prev = &head;
}

void
DLList::Iterator::erase()
{
   Item *rem = pos;

   if (rem == term)
      return;
   pos = pos->next;

   DLLIST_DEL(rem);
   delete rem;
}

void DLList::Iterator::moveToList(DLList& dest)
{
   Item *item = pos;

   assert(term != &dest.head);
   assert(pos != term);

   pos = pos->next;

   DLLIST_DEL(item);
   DLLIST_ADDHEAD(&dest.head, item);
}

bool
DLList::Iterator::insert(void *data)
{
   Item *ins = new Item(data);

   ins->next = pos->next;
   ins->prev = pos;
   pos->next->prev = ins;
   pos->next = ins;

   if (pos == term)
      term = ins;

   return true;
}

void
Stack::moveTo(Stack& that)
{
   unsigned int newSize = this->size + that.size;

   while (newSize > that.limit)
      that.resize();
   memcpy(&that.array[that.size], &array[0], this->size * sizeof(Item));

   that.size = newSize;
   this->size = 0;
}

Interval::Interval(const Interval& that) : head(NULL), tail(NULL)
{
   this->insert(that);
}

Interval::~Interval()
{
   clear();
}

void
Interval::clear()
{
   for (Range *next, *r = head; r; r = next) {
      next = r->next;
      delete r;
   }
   head = tail = NULL;
}

bool
Interval::extend(int a, int b)
{
   Range *r, **nextp = &head;

   // NOTE: we need empty intervals for fixed registers
   // if (a == b)
   //   return false;
   assert(a <= b);

   for (r = head; r; r = r->next) {
      if (b < r->bgn)
         break; // insert before
      if (a > r->end) {
         // insert after
         nextp = &r->next;
         continue;
      }

      // overlap
      if (a < r->bgn) {
         r->bgn = a;
         if (b > r->end)
            r->end = b;
         r->coalesce(&tail);
         return true;
      }
      if (b > r->end) {
         r->end = b;
         r->coalesce(&tail);
         return true;
      }
      assert(a >= r->bgn);
      assert(b <= r->end);
      return true;
   }

   (*nextp) = new Range(a, b);
   (*nextp)->next = r;

   for (r = (*nextp); r->next; r = r->next);
   tail = r;
   return true;
}

bool Interval::contains(int pos) const
{
   for (Range *r = head; r && r->bgn <= pos; r = r->next)
      if (r->end > pos)
         return true;
   return false;
}

bool Interval::overlaps(const Interval &that) const
{
#if 1
   Range *a = this->head;
   Range *b = that.head;

   while (a && b) {
      if (b->bgn < a->end &&
          b->end > a->bgn)
         return true;
      if (a->end <= b->bgn)
         a = a->next;
      else
         b = b->next;
   }
#else
   for (Range *rA = this->head; rA; rA = rA->next)
      for (Range *rB = iv.head; rB; rB = rB->next)
         if (rB->bgn < rA->end &&
             rB->end > rA->bgn)
            return true;
#endif
   return false;
}

void Interval::insert(const Interval &that)
{
   for (Range *r = that.head; r; r = r->next)
      this->extend(r->bgn, r->end);
}

void Interval::unify(Interval &that)
{
   assert(this != &that);
   for (Range *next, *r = that.head; r; r = next) {
      next = r->next;
      this->extend(r->bgn, r->end);
      delete r;
   }
   that.head = NULL;
}

int Interval::length() const
{
   int len = 0;
   for (Range *r = head; r; r = r->next)
      len += r->bgn - r->end;
   return len;
}

void Interval::print() const
{
   if (!head)
      return;
   INFO("[%i %i)", head->bgn, head->end);
   for (const Range *r = head->next; r; r = r->next)
      INFO(" [%i %i)", r->bgn, r->end);
   INFO("\n");
}

void
BitSet::andNot(const BitSet &set)
{
   assert(data && set.data);
   assert(size >= set.size);
   for (unsigned int i = 0; i < (set.size + 31) / 32; ++i)
      data[i] &= ~set.data[i];
}

BitSet& BitSet::operator|=(const BitSet &set)
{
   assert(data && set.data);
   assert(size >= set.size);
   for (unsigned int i = 0; i < (set.size + 31) / 32; ++i)
      data[i] |= set.data[i];
   return *this;
}

bool BitSet::resize(unsigned int nBits)
{
   if (!data || !nBits)
      return allocate(nBits, true);
   const unsigned int p = (size + 31) / 32;
   const unsigned int n = (nBits + 31) / 32;
   if (n == p)
      return true;

   data = (uint32_t *)REALLOC(data, 4 * p, 4 * n);
   if (!data) {
      size = 0;
      return false;
   }
   if (n > p)
      memset(&data[p], 0, (n - p) * 4);
   if (nBits < size && (nBits % 32))
      data[(nBits + 31) / 32 - 1] &= (1 << (nBits % 32)) - 1;

   size = nBits;
   return true;
}

bool BitSet::allocate(unsigned int nBits, bool zero)
{
   if (data && size < nBits) {
      FREE(data);
      data = NULL;
   }
   size = nBits;

   if (!data)
      data = reinterpret_cast<uint32_t *>(CALLOC((size + 31) / 32, 4));

   if (zero)
      memset(data, 0, (size + 7) / 8);
   else
   if (size % 32) // clear unused bits (e.g. for popCount)
      data[(size + 31) / 32 - 1] &= (1 << (size % 32)) - 1;

   return data;
}

unsigned int BitSet::popCount() const
{
   unsigned int count = 0;

   for (unsigned int i = 0; i < (size + 31) / 32; ++i)
      if (data[i])
         count += util_bitcount(data[i]);
   return count;
}

void BitSet::fill(uint32_t val)
{
   unsigned int i;
   for (i = 0; i < (size + 31) / 32; ++i)
      data[i] = val;
   if (val)
      data[i] &= ~(0xffffffff << (size % 32)); // BE ?
}

void BitSet::setOr(BitSet *pA, BitSet *pB)
{
   if (!pB) {
      *this = *pA;
   } else {
      for (unsigned int i = 0; i < (size + 31) / 32; ++i)
         data[i] = pA->data[i] | pB->data[i];
   }
}

int BitSet::findFreeRange(unsigned int count) const
{
   const uint32_t m = (1 << count) - 1;
   int pos = size;
   unsigned int i;
   const unsigned int end = (size + 31) / 32;

   if (count == 1) {
      for (i = 0; i < end; ++i) {
         pos = ffs(~data[i]) - 1;
         if (pos >= 0)
            break;
      }
   } else
   if (count == 2) {
      for (i = 0; i < end; ++i) {
         if (data[i] != 0xffffffff) {
            uint32_t b = data[i] | (data[i] >> 1) | 0xaaaaaaaa;
            pos = ffs(~b) - 1;
            if (pos >= 0)
               break;
         }
      }
   } else
   if (count == 4 || count == 3) {
      for (i = 0; i < end; ++i) {
         if (data[i] != 0xffffffff) {
            uint32_t b =
               (data[i] >> 0) | (data[i] >> 1) |
               (data[i] >> 2) | (data[i] >> 3) | 0xeeeeeeee;
            pos = ffs(~b) - 1;
            if (pos >= 0)
               break;
         }
      }
   } else {
      if (count <= 8)
         count = 8;
      else
      if (count <= 16)
         count = 16;
      else
         count = 32;

      for (i = 0; i < end; ++i) {
         if (data[i] != 0xffffffff) {
            for (pos = 0; pos < 32; pos += count)
               if (!(data[i] & (m << pos)))
                  break;
            if (pos < 32)
               break;
         }
      }
   }
   pos += i * 32;

   return ((pos + count) <= size) ? pos : -1;
}

void BitSet::print() const
{
   unsigned int n = 0;
   INFO("BitSet of size %u:\n", size);
   for (unsigned int i = 0; i < (size + 31) / 32; ++i) {
      uint32_t bits = data[i];
      while (bits) {
         int pos = ffs(bits) - 1;
         bits &= ~(1 << pos);
         INFO(" %i", i * 32 + pos);
         ++n;
         if ((n % 16) == 0)
            INFO("\n");
      }
   }
   if (n % 16)
      INFO("\n");
}

} // namespace nv50_ir
<commit_msg>nv50/ir: fix error finding free element in bitset in some situations<commit_after>/*
 * Copyright 2011 Christoph Bumiller
 *
 * 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 "codegen/nv50_ir_util.h"

namespace nv50_ir {

void DLList::clear()
{
   for (Item *next, *item = head.next; item != &head; item = next) {
      next = item->next;
      delete item;
   }
   head.next = head.prev = &head;
}

void
DLList::Iterator::erase()
{
   Item *rem = pos;

   if (rem == term)
      return;
   pos = pos->next;

   DLLIST_DEL(rem);
   delete rem;
}

void DLList::Iterator::moveToList(DLList& dest)
{
   Item *item = pos;

   assert(term != &dest.head);
   assert(pos != term);

   pos = pos->next;

   DLLIST_DEL(item);
   DLLIST_ADDHEAD(&dest.head, item);
}

bool
DLList::Iterator::insert(void *data)
{
   Item *ins = new Item(data);

   ins->next = pos->next;
   ins->prev = pos;
   pos->next->prev = ins;
   pos->next = ins;

   if (pos == term)
      term = ins;

   return true;
}

void
Stack::moveTo(Stack& that)
{
   unsigned int newSize = this->size + that.size;

   while (newSize > that.limit)
      that.resize();
   memcpy(&that.array[that.size], &array[0], this->size * sizeof(Item));

   that.size = newSize;
   this->size = 0;
}

Interval::Interval(const Interval& that) : head(NULL), tail(NULL)
{
   this->insert(that);
}

Interval::~Interval()
{
   clear();
}

void
Interval::clear()
{
   for (Range *next, *r = head; r; r = next) {
      next = r->next;
      delete r;
   }
   head = tail = NULL;
}

bool
Interval::extend(int a, int b)
{
   Range *r, **nextp = &head;

   // NOTE: we need empty intervals for fixed registers
   // if (a == b)
   //   return false;
   assert(a <= b);

   for (r = head; r; r = r->next) {
      if (b < r->bgn)
         break; // insert before
      if (a > r->end) {
         // insert after
         nextp = &r->next;
         continue;
      }

      // overlap
      if (a < r->bgn) {
         r->bgn = a;
         if (b > r->end)
            r->end = b;
         r->coalesce(&tail);
         return true;
      }
      if (b > r->end) {
         r->end = b;
         r->coalesce(&tail);
         return true;
      }
      assert(a >= r->bgn);
      assert(b <= r->end);
      return true;
   }

   (*nextp) = new Range(a, b);
   (*nextp)->next = r;

   for (r = (*nextp); r->next; r = r->next);
   tail = r;
   return true;
}

bool Interval::contains(int pos) const
{
   for (Range *r = head; r && r->bgn <= pos; r = r->next)
      if (r->end > pos)
         return true;
   return false;
}

bool Interval::overlaps(const Interval &that) const
{
#if 1
   Range *a = this->head;
   Range *b = that.head;

   while (a && b) {
      if (b->bgn < a->end &&
          b->end > a->bgn)
         return true;
      if (a->end <= b->bgn)
         a = a->next;
      else
         b = b->next;
   }
#else
   for (Range *rA = this->head; rA; rA = rA->next)
      for (Range *rB = iv.head; rB; rB = rB->next)
         if (rB->bgn < rA->end &&
             rB->end > rA->bgn)
            return true;
#endif
   return false;
}

void Interval::insert(const Interval &that)
{
   for (Range *r = that.head; r; r = r->next)
      this->extend(r->bgn, r->end);
}

void Interval::unify(Interval &that)
{
   assert(this != &that);
   for (Range *next, *r = that.head; r; r = next) {
      next = r->next;
      this->extend(r->bgn, r->end);
      delete r;
   }
   that.head = NULL;
}

int Interval::length() const
{
   int len = 0;
   for (Range *r = head; r; r = r->next)
      len += r->bgn - r->end;
   return len;
}

void Interval::print() const
{
   if (!head)
      return;
   INFO("[%i %i)", head->bgn, head->end);
   for (const Range *r = head->next; r; r = r->next)
      INFO(" [%i %i)", r->bgn, r->end);
   INFO("\n");
}

void
BitSet::andNot(const BitSet &set)
{
   assert(data && set.data);
   assert(size >= set.size);
   for (unsigned int i = 0; i < (set.size + 31) / 32; ++i)
      data[i] &= ~set.data[i];
}

BitSet& BitSet::operator|=(const BitSet &set)
{
   assert(data && set.data);
   assert(size >= set.size);
   for (unsigned int i = 0; i < (set.size + 31) / 32; ++i)
      data[i] |= set.data[i];
   return *this;
}

bool BitSet::resize(unsigned int nBits)
{
   if (!data || !nBits)
      return allocate(nBits, true);
   const unsigned int p = (size + 31) / 32;
   const unsigned int n = (nBits + 31) / 32;
   if (n == p)
      return true;

   data = (uint32_t *)REALLOC(data, 4 * p, 4 * n);
   if (!data) {
      size = 0;
      return false;
   }
   if (n > p)
      memset(&data[p], 0, (n - p) * 4);
   if (nBits < size && (nBits % 32))
      data[(nBits + 31) / 32 - 1] &= (1 << (nBits % 32)) - 1;

   size = nBits;
   return true;
}

bool BitSet::allocate(unsigned int nBits, bool zero)
{
   if (data && size < nBits) {
      FREE(data);
      data = NULL;
   }
   size = nBits;

   if (!data)
      data = reinterpret_cast<uint32_t *>(CALLOC((size + 31) / 32, 4));

   if (zero)
      memset(data, 0, (size + 7) / 8);
   else
   if (size % 32) // clear unused bits (e.g. for popCount)
      data[(size + 31) / 32 - 1] &= (1 << (size % 32)) - 1;

   return data;
}

unsigned int BitSet::popCount() const
{
   unsigned int count = 0;

   for (unsigned int i = 0; i < (size + 31) / 32; ++i)
      if (data[i])
         count += util_bitcount(data[i]);
   return count;
}

void BitSet::fill(uint32_t val)
{
   unsigned int i;
   for (i = 0; i < (size + 31) / 32; ++i)
      data[i] = val;
   if (val)
      data[i] &= ~(0xffffffff << (size % 32)); // BE ?
}

void BitSet::setOr(BitSet *pA, BitSet *pB)
{
   if (!pB) {
      *this = *pA;
   } else {
      for (unsigned int i = 0; i < (size + 31) / 32; ++i)
         data[i] = pA->data[i] | pB->data[i];
   }
}

int BitSet::findFreeRange(unsigned int count) const
{
   const uint32_t m = (1 << count) - 1;
   int pos = size;
   unsigned int i;
   const unsigned int end = (size + 31) / 32;

   if (count == 1) {
      for (i = 0; i < end; ++i) {
         pos = ffs(~data[i]) - 1;
         if (pos >= 0)
            break;
      }
   } else
   if (count == 2) {
      for (i = 0; i < end; ++i) {
         if (data[i] != 0xffffffff) {
            uint32_t b = data[i] | (data[i] >> 1) | 0xaaaaaaaa;
            pos = ffs(~b) - 1;
            if (pos >= 0)
               break;
         }
      }
   } else
   if (count == 4 || count == 3) {
      for (i = 0; i < end; ++i) {
         if (data[i] != 0xffffffff) {
            uint32_t b =
               (data[i] >> 0) | (data[i] >> 1) |
               (data[i] >> 2) | (data[i] >> 3) | 0xeeeeeeee;
            pos = ffs(~b) - 1;
            if (pos >= 0)
               break;
         }
      }
   } else {
      if (count <= 8)
         count = 8;
      else
      if (count <= 16)
         count = 16;
      else
         count = 32;

      for (i = 0; i < end; ++i) {
         if (data[i] != 0xffffffff) {
            for (pos = 0; pos < 32; pos += count)
               if (!(data[i] & (m << pos)))
                  break;
            if (pos < 32)
               break;
         }
      }
   }

   // If we couldn't find a position, we can have a left-over -1 in pos. Make
   // sure to abort in such a case.
   if (pos < 0)
      return -1;

   pos += i * 32;

   return ((pos + count) <= size) ? pos : -1;
}

void BitSet::print() const
{
   unsigned int n = 0;
   INFO("BitSet of size %u:\n", size);
   for (unsigned int i = 0; i < (size + 31) / 32; ++i) {
      uint32_t bits = data[i];
      while (bits) {
         int pos = ffs(bits) - 1;
         bits &= ~(1 << pos);
         INFO(" %i", i * 32 + pos);
         ++n;
         if ((n % 16) == 0)
            INFO("\n");
      }
   }
   if (n % 16)
      INFO("\n");
}

} // namespace nv50_ir
<|endoftext|>


<commit_before>// Copyright (c) 2010 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 <algorithm>

#include <algorithm>

#include "app/resource_bundle.h"
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/values.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/dom_ui/login/login_ui_helpers.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/jstemplate_builder.h"
#include "grit/browser_resources.h"

namespace chromeos {

////////////////////////////////////////////////////////////////////////////////
//
// ProfileOperationsInterface
//
////////////////////////////////////////////////////////////////////////////////
Profile* ProfileOperationsInterface::GetDefaultProfile() {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  return profile_manager->GetDefaultProfile();
}

Profile* ProfileOperationsInterface::GetDefaultProfileByPath() {
  return GetDefaultProfile(GetUserDataPath());
}

Profile* ProfileOperationsInterface::GetDefaultProfile(FilePath user_data_dir) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  return profile_manager->GetDefaultProfile(user_data_dir);
}

FilePath ProfileOperationsInterface::GetUserDataPath() {
  FilePath user_data_dir;
  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
  return user_data_dir;
}

////////////////////////////////////////////////////////////////////////////////
//
// BrowserOperationsInterface
//
////////////////////////////////////////////////////////////////////////////////
Browser* BrowserOperationsInterface::CreateBrowser(Profile* profile) {
  return Browser::Create(profile);
}

Browser* BrowserOperationsInterface::GetLoginBrowser(Profile* profile) {
  return BrowserList::FindBrowserWithType(profile,
                                          Browser::TYPE_ANY,
                                          true);
}

////////////////////////////////////////////////////////////////////////////////
//
// HTMLOperationsInterface
//
////////////////////////////////////////////////////////////////////////////////
base::StringPiece HTMLOperationsInterface::GetLoginHTML() {
  base::StringPiece login_html(
      ResourceBundle::GetSharedInstance().GetRawDataResource(
          IDR_LOGIN_HTML));
  return login_html;
}

std::string HTMLOperationsInterface::GetFullHTML(
    base::StringPiece login_html,
    DictionaryValue* localized_strings) {
  return jstemplate_builder::GetI18nTemplateHtml(
      login_html,
      localized_strings);
}

RefCountedBytes* HTMLOperationsInterface::CreateHTMLBytes(
    std::string full_html) {
  RefCountedBytes* html_bytes = new RefCountedBytes();
  html_bytes->data.resize(full_html.size());
  std::copy(full_html.begin(),
            full_html.end(),
            html_bytes->data.begin());
  return html_bytes;
}

}  // namespace chromeos
<commit_msg>Fix includes in stubbed login that were broken by profile.h and profile_manager.h moving.<commit_after>// Copyright (c) 2010 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 <algorithm>

#include <algorithm>

#include "app/resource_bundle.h"
#include "base/file_path.h"
#include "base/path_service.h"
#include "base/values.h"
#include "chrome/browser/browser_list.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/chromeos/dom_ui/login/login_ui_helpers.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/profiles/profile_manager.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/common/jstemplate_builder.h"
#include "grit/browser_resources.h"

namespace chromeos {

////////////////////////////////////////////////////////////////////////////////
//
// ProfileOperationsInterface
//
////////////////////////////////////////////////////////////////////////////////
Profile* ProfileOperationsInterface::GetDefaultProfile() {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  return profile_manager->GetDefaultProfile();
}

Profile* ProfileOperationsInterface::GetDefaultProfileByPath() {
  return GetDefaultProfile(GetUserDataPath());
}

Profile* ProfileOperationsInterface::GetDefaultProfile(FilePath user_data_dir) {
  ProfileManager* profile_manager = g_browser_process->profile_manager();
  return profile_manager->GetDefaultProfile(user_data_dir);
}

FilePath ProfileOperationsInterface::GetUserDataPath() {
  FilePath user_data_dir;
  PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
  return user_data_dir;
}

////////////////////////////////////////////////////////////////////////////////
//
// BrowserOperationsInterface
//
////////////////////////////////////////////////////////////////////////////////
Browser* BrowserOperationsInterface::CreateBrowser(Profile* profile) {
  return Browser::Create(profile);
}

Browser* BrowserOperationsInterface::GetLoginBrowser(Profile* profile) {
  return BrowserList::FindBrowserWithType(profile,
                                          Browser::TYPE_ANY,
                                          true);
}

////////////////////////////////////////////////////////////////////////////////
//
// HTMLOperationsInterface
//
////////////////////////////////////////////////////////////////////////////////
base::StringPiece HTMLOperationsInterface::GetLoginHTML() {
  base::StringPiece login_html(
      ResourceBundle::GetSharedInstance().GetRawDataResource(
          IDR_LOGIN_HTML));
  return login_html;
}

std::string HTMLOperationsInterface::GetFullHTML(
    base::StringPiece login_html,
    DictionaryValue* localized_strings) {
  return jstemplate_builder::GetI18nTemplateHtml(
      login_html,
      localized_strings);
}

RefCountedBytes* HTMLOperationsInterface::CreateHTMLBytes(
    std::string full_html) {
  RefCountedBytes* html_bytes = new RefCountedBytes();
  html_bytes->data.resize(full_html.size());
  std::copy(full_html.begin(),
            full_html.end(),
            html_bytes->data.begin());
  return html_bytes;
}

}  // namespace chromeos
<|endoftext|>


<commit_before>/**
 * Copyright 2007-2018 IMP Inventors. All rights reserved.
 */

#include <exception>
#include <iostream>
#include <string>
#include <vector>

#include "RMF/FileConstHandle.h"
#include "RMF/FileHandle.h"
#include "RMF/ID.h"
#include "RMF/infrastructure_macros.h"
#include "RMF/utility.h"
#include "common.h"

namespace {
std::vector<std::string> inputs;
std::string description("Combine two or more rmf files.");
std::string output;
}
int main(int argc, char** argv) {
  try {
    positional_options.add_options()(
        "input-files,i",
        boost::program_options::value<std::vector<std::string> >(&inputs),
        "input rmf file");
    positional_names.push_back("input_1.rmf input_2.rmf ... output.rmf");
    positional_options_description.add("input-files", -1);
    process_options(argc, argv);
    if (inputs.size() < 3) {
      print_help_and_exit(argv);
    }

    output = inputs.back();
    inputs.pop_back();
    RMF::FileHandle orh = RMF::create_rmf_file(output);
    orh.set_producer("rmf_cat");
    for (unsigned int i = 0; i < inputs.size(); ++i) {
      RMF::FileConstHandle rh = RMF::open_rmf_file_read_only(inputs[i]);
      if (i == 0) {
        RMF::clone_hierarchy(rh, orh);
      }
      orh.set_description(orh.get_description() + "\n" + rh.get_description());
      RMF_FOREACH(RMF::FrameID ni, rh.get_frames()) {
        rh.set_current_frame(ni);
        orh.add_frame(rh.get_name(ni), rh.get_type(ni));
        RMF::clone_loaded_frame(rh, orh);
      }
    }
    return 0;
  }
  catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
}
<commit_msg>add missing file/static info<commit_after>/**
 * Copyright 2007-2018 IMP Inventors. All rights reserved.
 */

#include <exception>
#include <iostream>
#include <string>
#include <vector>

#include "RMF/FileConstHandle.h"
#include "RMF/FileHandle.h"
#include "RMF/ID.h"
#include "RMF/infrastructure_macros.h"
#include "RMF/utility.h"
#include "common.h"

namespace {
std::vector<std::string> inputs;
std::string description("Combine two or more rmf files.");
std::string output;
}
int main(int argc, char** argv) {
  try {
    positional_options.add_options()(
        "input-files,i",
        boost::program_options::value<std::vector<std::string> >(&inputs),
        "input rmf file");
    positional_names.push_back("input_1.rmf input_2.rmf ... output.rmf");
    positional_options_description.add("input-files", -1);
    process_options(argc, argv);
    if (inputs.size() < 3) {
      print_help_and_exit(argv);
    }

    output = inputs.back();
    inputs.pop_back();
    RMF::FileHandle orh = RMF::create_rmf_file(output);
    orh.set_producer("rmf_cat");
    for (unsigned int i = 0; i < inputs.size(); ++i) {
      RMF::FileConstHandle rh = RMF::open_rmf_file_read_only(inputs[i]);
      if (i == 0) {
        RMF::clone_file_info(rh, orh); // creator etc. (not essential)
        RMF::clone_hierarchy(rh, orh);
        RMF::clone_static_frame(rh, orh);
      }
      orh.set_description(orh.get_description() + "\n" + rh.get_description());
      RMF_FOREACH(RMF::FrameID ni, rh.get_frames()) {
        rh.set_current_frame(ni);
        orh.add_frame(rh.get_name(ni), rh.get_type(ni));
        RMF::clone_loaded_frame(rh, orh);
      }
    }
    return 0;
  }
  catch (const std::exception& e) {
    std::cerr << "Error: " << e.what() << std::endl;
  }
}
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// ----------------------------------------------------------------------------
/// @file  p9_mss_eff_grouping.H
///
/// @brief Perform Memory Controller grouping on each processor chip
///
/// The purpose of this procedure is to effectively group the memory on each
/// processor chip based on available memory behind its memory grouping ports.
/// Some placement policy/scheme and other info that are stored in the
/// attributes are used as part of the grouping process.
///
/// ----------------------------------------------------------------------------
/// *HWP HWP Owner   : Joe McGill <jmcgill@us.ibm.com>
/// *HWP FW Owner    : Thi Tran <thi@us.ibm.com>
/// *HWP Team        : Nest
/// *HWP Level       : 3
/// *HWP Consumed by : HB
/// ----------------------------------------------------------------------------

#ifndef _P9_MSS_EFF_GROUPING_H_
#define _P9_MSS_EFF_GROUPING_H_

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <fapi2.H>

///----------------------------------------------------------------------------
/// Constant definitions
///----------------------------------------------------------------------------

// Constants used for EffGroupingData struct
const uint8_t DATA_GROUPS   = 16;   // 8 regular groups, 8 mirrored groups
const uint8_t MIRR_OFFSET   = 8;    // Start of mirrored offset in DATA_GROUPS
const uint8_t DATA_ELEMENTS = 18;   // 18 items of data for each group

// Indexes used for EffGroupingData::iv_data DATA ELEMENTS
const uint8_t PORT_SIZE = 0;         // Memory size of each port in group (GB)
const uint8_t PORTS_IN_GROUP = 1;    // Number of ports in group
const uint8_t GROUP_SIZE = 2;        // Memory size of entire group (GB)
const uint8_t BASE_ADDR = 3;         // Base Address
#define MEMBER_IDX(X) ((X) + 4)      // List of MC ports in group
#define ALT_VALID(X) ((X) + 12)      // Alt Memory valid (2 alt memory regions)
#define ALT_SIZE(X) ((X) + 14)       // Alt Memory Size
#define ALT_BASE_ADDR(X) ((X) + 16)  // Alt Base Address

// Number of memory regions
const uint8_t NUM_NON_MIRROR_REGIONS = 8;
const uint8_t NUM_MIRROR_REGIONS = 4;
const uint8_t NUM_OF_CHTM_REGIONS = 24;   // 24 CHTM memory regions
const uint8_t NUM_OF_ALT_MEM_REGIONS = 2; // 2 memory holes

// ------------------------------------------------------
// MC ports
// Define the MC ports to be grouped.
// For Nimbus, MC port is an MCA (8 MCAs)
// For Cumulus, MC port is a DMI (8 DMIs)
// -------------------------------------------------------
const uint8_t NUM_MCS_PER_PROC = 4;
const uint8_t NUM_MC_PORTS_PER_PROC = 8;
const uint8_t NUM_DIMMS_PER_DRAM_PORT = 2; // 2 DIMMs per DRAM port

/// Function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_mss_eff_grouping_FP_t)(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);

//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------
///
/// @brief p9_mss_eff_grouping procedure
///
/// This HWP is to group the MCs of the input target processor chip based
/// on the amount of memory behind its ports and some policy attribute settings.
///
/// @param[in]    i_target   Reference to TARGET_TYPE_PROC_CHIP target
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
///
extern "C"
{

    fapi2::ReturnCode p9_mss_eff_grouping(
        const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

} // extern "C"

#endif  // _P9_MSS_EFF_GROUPING_H_
<commit_msg>Secure memory allocation and setup<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/nest/p9_mss_eff_grouping.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2015,2019                        */
/* [+] International Business Machines Corp.                              */
/*                                                                        */
/*                                                                        */
/* 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.                         */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */
/// ----------------------------------------------------------------------------
/// @file  p9_mss_eff_grouping.H
///
/// @brief Perform Memory Controller grouping on each processor chip
///
/// The purpose of this procedure is to effectively group the memory on each
/// processor chip based on available memory behind its memory grouping ports.
/// Some placement policy/scheme and other info that are stored in the
/// attributes are used as part of the grouping process.
///
/// ----------------------------------------------------------------------------
/// *HWP HWP Owner   : Joe McGill <jmcgill@us.ibm.com>
/// *HWP FW Owner    : Thi Tran <thi@us.ibm.com>
/// *HWP Team        : Nest
/// *HWP Level       : 3
/// *HWP Consumed by : HB
/// ----------------------------------------------------------------------------

#ifndef _P9_MSS_EFF_GROUPING_H_
#define _P9_MSS_EFF_GROUPING_H_

//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include <fapi2.H>

///----------------------------------------------------------------------------
/// Constant definitions
///----------------------------------------------------------------------------

// Constants used for EffGroupingData struct
const uint8_t DATA_GROUPS   = 16;   // 8 regular groups, 8 mirrored groups
const uint8_t MIRR_OFFSET   = 8;    // Start of mirrored offset in DATA_GROUPS
const uint8_t DATA_ELEMENTS = 21;   // 21 items of data for each group

// Indexes used for EffGroupingData::iv_data DATA ELEMENTS
const uint8_t PORT_SIZE = 0;         // Memory size of each port in group (GB)
const uint8_t PORTS_IN_GROUP = 1;    // Number of ports in group
const uint8_t GROUP_SIZE = 2;        // Memory size of entire group (GB)
const uint8_t BASE_ADDR = 3;         // Base Address
#define MEMBER_IDX(X) ((X) + 4)      // List of MC ports in group
#define ALT_VALID(X) ((X) + 12)      // Alt Memory Valid (2 alt memory regions)
#define ALT_SIZE(X) ((X) + 14)       // Alt Memory Size
#define ALT_BASE_ADDR(X) ((X) + 16)  // Alt Base Address
const uint8_t SMF_VALID = 18;        // SMF Memory Valid
const uint8_t SMF_SIZE = 19;         // SMF Memory Size
const uint8_t SMF_BASE_ADDR = 20;    // SMF Base Address

// Number of memory regions
const uint8_t NUM_NON_MIRROR_REGIONS = 8;
const uint8_t NUM_MIRROR_REGIONS = 4;
const uint8_t NUM_OF_CHTM_REGIONS = 24;   // 24 CHTM memory regions
const uint8_t NUM_OF_ALT_MEM_REGIONS = 2; // 2 memory holes

// ------------------------------------------------------
// MC ports
// Define the MC ports to be grouped.
// For Nimbus, MC port is an MCA (8 MCAs)
// For Cumulus, MC port is a DMI (8 DMIs)
// -------------------------------------------------------
const uint8_t NUM_MCS_PER_PROC = 4;
const uint8_t NUM_MC_PORTS_PER_PROC = 8;
const uint8_t NUM_DIMMS_PER_DRAM_PORT = 2; // 2 DIMMs per DRAM port

/// Function pointer typedef definition for HWP call support
typedef fapi2::ReturnCode (*p9_mss_eff_grouping_FP_t)(
    const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>&);

//------------------------------------------------------------------------------
// Function prototypes
//------------------------------------------------------------------------------
///
/// @brief p9_mss_eff_grouping procedure
///
/// This HWP is to group the MCs of the input target processor chip based
/// on the amount of memory behind its ports and some policy attribute settings.
///
/// @param[in]    i_target   Reference to TARGET_TYPE_PROC_CHIP target
///
/// @return FAPI2_RC_SUCCESS if success, else error code.
///
extern "C"
{

    fapi2::ReturnCode p9_mss_eff_grouping(
        const fapi2::Target<fapi2::TARGET_TYPE_PROC_CHIP>& i_target);

} // extern "C"

#endif  // _P9_MSS_EFF_GROUPING_H_
<|endoftext|>