<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Justin Madsen, Daniel Melanz
// =============================================================================
//
// Base class for a double-A arm suspension modeled with bodies and constraints.
//
// The suspension subsystem is modeled with respect to a right-handed frame,
// with X pointing towards the rear, Y to the right, and Z up. By default, a
// right suspension is constructed.  This can be mirrored to obtain a left
// suspension. Note that this is done by reflecting the y coordinates of the
// hardpoints. As such, the orientation of the suspension reference frame must
// be as specified above. However, its location relative to the chassis is
// arbitrary (and left up to a derived class).
//
// If marked as 'driven', the suspension subsystem also creates the ChShaft axle
// element and its connection to the spindle body (which provides the interface
// to the powertrain subsystem).
//
// =============================================================================

#include "assets/ChCylinderShape.h"
#include "assets/ChColorAsset.h"

#include "subsys/suspension/ChDoubleWishbone.h"

namespace chrono {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChDoubleWishbone::ChDoubleWishbone(const std::string& name,
                                                 ChSuspension::Side side,
                                                 bool               driven)
: ChSuspension(name, side, driven)
{
  // Create the upright and spindle bodies
  m_spindle = ChSharedBodyPtr(new ChBody);
  m_spindle->SetNameString(name + "_spindle");

  m_upright = ChSharedBodyPtr(new ChBody);
  m_upright->SetNameString(name + "_upright");

  // Revolute joint between spindle and upright
  m_revolute = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute);
  m_revolute->SetNameString(name + "_revolute");

  // Bodies and constraints to model upper control arm
  m_UCA = ChSharedBodyPtr(new ChBody);
  m_UCA->SetNameString(name + "_UCA");
  m_revoluteUCA = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute);
  m_revoluteUCA->SetNameString(name + "_revoluteUCA");
  m_sphericalUCA = ChSharedPtr<ChLinkLockSpherical>(new ChLinkLockSpherical);
  m_sphericalUCA->SetNameString(name + "_sphericalUCA");

  // Bodies and constraints to model lower control arm
  m_LCA = ChSharedBodyPtr(new ChBody);
  m_LCA->SetNameString(name + "_LCA");
  m_revoluteLCA = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute);
  m_revoluteLCA->SetNameString(name + "_revoluteLCA");
  m_sphericalLCA = ChSharedPtr<ChLinkLockSpherical>(new ChLinkLockSpherical);
  m_sphericalLCA->SetNameString(name + "_sphericalLCA");

  // Distance constraint to model the tierod
  m_distTierod = ChSharedPtr<ChLinkDistance>(new ChLinkDistance);
  m_distTierod->SetNameString(name + "_distTierod");

  // Spring-damper
  m_shock = ChSharedPtr<ChLinkSpring>(new ChLinkSpring);
  m_shock->SetNameString(name + "_shock");

  // If driven, create the axle shaft and its connection to the spindle.
  if (m_driven) {
    m_axle = ChSharedPtr<ChShaft>(new ChShaft);
    m_axle->SetNameString(name + "_axle");

    m_axle_to_spindle = ChSharedPtr<ChShaftsBody>(new ChShaftsBody);
    m_axle_to_spindle->SetNameString(name + "_axle_to_spindle");
  }
}

// -----------------------------------------------------------------------------
// TODO: does it make sense to ask for a complete Coordsys (i.e. allow for a
// non-identity rotation) when attaching a suspension subsystem to the chassis?
// -----------------------------------------------------------------------------
void
ChDoubleWishbone::Initialize(ChSharedBodyPtr   chassis,
                                    const ChVector<>& location)
{
  // Transform all points to absolute frame
  for (int i = 0; i < NUM_POINTS; i++) {
    ChVector<> rel_pos = getLocation(static_cast<PointId>(i));
    if (m_side == LEFT)
      rel_pos.y = -rel_pos.y;
    m_points[i] = chassis->GetCoord().TransformLocalToParent(location + rel_pos);
  }

  // Set body positions and rotations, mass properties, etc.
  m_spindle->SetPos(m_points[SPINDLE]);
  m_spindle->SetRot(chassis->GetCoord().rot);
  m_spindle->SetMass(getSpindleMass());
  m_spindle->SetInertiaXX(getSpindleInertia());
  OnInitializeSpindle();
  chassis->GetSystem()->AddBody(m_spindle);

  m_UCA->SetPos(m_points[UCA_CM]);
  // Determine the rotation matrix of the UCA based on the plane of the hard points
  ChVector<> wRot;
  wRot.Cross(m_points[UCA_F]-m_points[UCA_U], m_points[UCA_B]-m_points[UCA_U]);
  wRot.Normalize();
  ChVector<> uRot = m_points[UCA_B]-m_points[UCA_F];
  uRot.Normalize();
  ChVector<> vRot;
  vRot.Cross(wRot,uRot);
  ChMatrix33<> rotationMatrix;
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_UCA->SetRot(rotationMatrix); // Set the rotation of the UCA
  m_UCA->SetMass(getUCAMass());
  m_UCA->SetInertiaXX(getUCAInertia());
  AddVisualizationUCA();
  OnInitializeUCA();
  chassis->GetSystem()->AddBody(m_UCA);

  m_LCA->SetPos(m_points[LCA_CM]);
  // Determine the rotation matrix of the LCA based on the plane of the hard points
  wRot.Cross(m_points[LCA_F]-m_points[LCA_U], m_points[LCA_B]-m_points[LCA_U]);
  wRot.Normalize();
  uRot = m_points[LCA_B]-m_points[LCA_F];
  uRot.Normalize();
  vRot.Cross(wRot,uRot);
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_LCA->SetRot(rotationMatrix); // Set the rotation of the LCA
  m_LCA->SetMass(getLCAMass());
  m_LCA->SetInertiaXX(getLCAInertia());
  AddVisualizationLCA();
  OnInitializeLCA();
  chassis->GetSystem()->AddBody(m_LCA);

  m_upright->SetPos(m_points[UPRIGHT]);
  m_upright->SetRot(chassis->GetCoord().rot);
  m_upright->SetMass(getUprightMass());
  m_upright->SetInertiaXX(getUprightInertia());
  AddVisualizationUpright();
  OnInitializeUpright();
  chassis->GetSystem()->AddBody(m_upright);

  // Initialize joints
  ChCoordsys<> rev_csys(m_points[UPRIGHT], Q_from_AngAxis(CH_C_PI / 2.0, VECT_X));
  m_revolute->Initialize(m_spindle, m_upright, rev_csys);
  chassis->GetSystem()->AddLink(m_revolute);

  // Determine the rotation matrix of the UCA based on the plane of the hard points
  wRot = m_points[UCA_B]-m_points[UCA_F];
  wRot.Normalize();
  uRot = ChVector<>(0,0,1);
  uRot.Normalize();
  vRot.Cross(wRot,uRot);
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_revoluteUCA->Initialize(chassis, m_UCA, ChCoordsys<>((m_points[UCA_F]+m_points[UCA_B])/2, rotationMatrix.Get_A_quaternion()));
  chassis->GetSystem()->AddLink(m_revoluteUCA);
  m_sphericalUCA->Initialize(m_UCA, m_upright, ChCoordsys<>(m_points[UCA_U], QUNIT));
  chassis->GetSystem()->AddLink(m_sphericalUCA);

  // Determine the rotation matrix of the LCA based on the plane of the hard points
  wRot = m_points[LCA_B]-m_points[LCA_F];
  wRot.Normalize();
  uRot = ChVector<>(0,0,1);
  uRot.Normalize();
  vRot.Cross(wRot,uRot);
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_revoluteLCA->Initialize(chassis, m_LCA, ChCoordsys<>((m_points[LCA_F]+m_points[LCA_B])/2, rotationMatrix.Get_A_quaternion()));
  chassis->GetSystem()->AddLink(m_revoluteLCA);
  m_sphericalLCA->Initialize(m_LCA, m_upright, ChCoordsys<>(m_points[LCA_U], QUNIT));
  chassis->GetSystem()->AddLink(m_sphericalLCA);

  m_distTierod->Initialize(chassis, m_upright, false, m_points[TIEROD_C], m_points[TIEROD_U]);
  chassis->GetSystem()->AddLink(m_distTierod);

  // Initialize the spring/damper
  m_shock->Initialize(chassis, m_upright, false, m_points[SHOCK_C], m_points[SHOCK_U]);
  m_shock->Set_SpringK(getSpringCoefficient());
  m_shock->Set_SpringR(getDampingCoefficient());
  m_shock->Set_SpringRestLength(getSpringRestLength());
  chassis->GetSystem()->AddLink(m_shock);

  // Save initial relative position of marker 1 of the tierod distance link,
  // to be used in steering.
  m_tierod_marker = m_distTierod->GetEndPoint1Rel();

  // Initialize the axle shaft and its connection to the spindle. Note that the
  // spindle rotates about the Y axis.
  if (m_driven) {
    m_axle->SetInertia(getAxleInertia());
    chassis->GetSystem()->Add(m_axle);
    m_axle_to_spindle->Initialize(m_axle, m_spindle, ChVector<>(0, 1, 0));
    chassis->GetSystem()->Add(m_axle_to_spindle);
  }

}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChDoubleWishbone::AddVisualizationLCA()
{
  // Express hardpoint locations in body frame.
  ChVector<> p_F = m_LCA->TransformPointParentToLocal(m_points[LCA_F]);
  ChVector<> p_B = m_LCA->TransformPointParentToLocal(m_points[LCA_B]);
  ChVector<> p_U = m_LCA->TransformPointParentToLocal(m_points[LCA_U]);

  ChSharedPtr<ChCylinderShape> cyl_F(new ChCylinderShape);
  cyl_F->GetCylinderGeometry().p1 = p_F;
  cyl_F->GetCylinderGeometry().p2 = p_U;
  cyl_F->GetCylinderGeometry().rad = getLCARadius();
  m_LCA->AddAsset(cyl_F);

  ChSharedPtr<ChCylinderShape> cyl_B(new ChCylinderShape);
  cyl_B->GetCylinderGeometry().p1 = p_B;
  cyl_B->GetCylinderGeometry().p2 = p_U;
  cyl_B->GetCylinderGeometry().rad = getLCARadius();
  m_LCA->AddAsset(cyl_B);

  ChSharedPtr<ChColorAsset> col(new ChColorAsset);
  switch (m_side) {
  case RIGHT: col->SetColor(ChColor(0.6f, 0.4f, 0.4f)); break;
  case LEFT:  col->SetColor(ChColor(0.4f, 0.4f, 0.6f)); break;
  }
  m_LCA->AddAsset(col);
}

void ChDoubleWishbone::AddVisualizationUCA()
{
  // Express hardpoint locations in body frame.
  ChVector<> p_F = m_UCA->TransformPointParentToLocal(m_points[UCA_F]);
  ChVector<> p_B = m_UCA->TransformPointParentToLocal(m_points[UCA_B]);
  ChVector<> p_U = m_UCA->TransformPointParentToLocal(m_points[UCA_U]);

  ChSharedPtr<ChCylinderShape> cyl_F(new ChCylinderShape);
  cyl_F->GetCylinderGeometry().p1 = p_F;
  cyl_F->GetCylinderGeometry().p2 = p_U;
  cyl_F->GetCylinderGeometry().rad = getUCARadius();
  m_UCA->AddAsset(cyl_F);

  ChSharedPtr<ChCylinderShape> cyl_B(new ChCylinderShape);
  cyl_B->GetCylinderGeometry().p1 = p_B;
  cyl_B->GetCylinderGeometry().p2 = p_U;
  cyl_B->GetCylinderGeometry().rad = getUCARadius();
  m_UCA->AddAsset(cyl_B);

  ChSharedPtr<ChColorAsset> col(new ChColorAsset);
  switch (m_side) {
  case RIGHT: col->SetColor(ChColor(0.6f, 0.4f, 0.4f)); break;
  case LEFT:  col->SetColor(ChColor(0.4f, 0.4f, 0.6f)); break;
  }
  m_UCA->AddAsset(col);
}

void ChDoubleWishbone::AddVisualizationUpright()
{
  // Express hardpoint locations in body frame.
  ChVector<> p_U = m_upright->TransformPointParentToLocal(m_points[UCA_U]);
  ChVector<> p_L = m_upright->TransformPointParentToLocal(m_points[LCA_U]);

  ChSharedPtr<ChCylinderShape> cyl(new ChCylinderShape);
  cyl->GetCylinderGeometry().p1 = p_U;
  cyl->GetCylinderGeometry().p2 = p_L;
  cyl->GetCylinderGeometry().rad = getUprightRadius();
  m_upright->AddAsset(cyl);

  ChSharedPtr<ChColorAsset> col(new ChColorAsset);
  switch (m_side) {
  case RIGHT: col->SetColor(ChColor(0.6f, 0.1f, 0.1f)); break;
  case LEFT:  col->SetColor(ChColor(0.1f, 0.1f, 0.6f)); break;
  }
  m_upright->AddAsset(col);
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void ChDoubleWishbone::ApplySteering(double displ)
{
  ChVector<> r_bar = m_tierod_marker;
  r_bar.y += displ;
  m_distTierod->SetEndPoint1Rel(r_bar);
}

} // end namespace chrono
<commit_msg>Changed the connection of the shock spring/damper from the upright to the LCA.<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right reserved.
//
// Use of this source code is governed by a BSD-style license that can be found
// in the LICENSE file at the top level of the distribution and at
// http://projectchrono.org/license-chrono.txt.
//
// =============================================================================
// Authors: Radu Serban, Justin Madsen, Daniel Melanz
// =============================================================================
//
// Base class for a double-A arm suspension modeled with bodies and constraints.
//
// The suspension subsystem is modeled with respect to a right-handed frame,
// with X pointing towards the rear, Y to the right, and Z up. By default, a
// right suspension is constructed.  This can be mirrored to obtain a left
// suspension. Note that this is done by reflecting the y coordinates of the
// hardpoints. As such, the orientation of the suspension reference frame must
// be as specified above. However, its location relative to the chassis is
// arbitrary (and left up to a derived class).
//
// If marked as 'driven', the suspension subsystem also creates the ChShaft axle
// element and its connection to the spindle body (which provides the interface
// to the powertrain subsystem).
//
// =============================================================================

#include "assets/ChCylinderShape.h"
#include "assets/ChColorAsset.h"

#include "subsys/suspension/ChDoubleWishbone.h"

namespace chrono {

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
ChDoubleWishbone::ChDoubleWishbone(const std::string& name,
                                                 ChSuspension::Side side,
                                                 bool               driven)
: ChSuspension(name, side, driven)
{
  // Create the upright and spindle bodies
  m_spindle = ChSharedBodyPtr(new ChBody);
  m_spindle->SetNameString(name + "_spindle");

  m_upright = ChSharedBodyPtr(new ChBody);
  m_upright->SetNameString(name + "_upright");

  // Revolute joint between spindle and upright
  m_revolute = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute);
  m_revolute->SetNameString(name + "_revolute");

  // Bodies and constraints to model upper control arm
  m_UCA = ChSharedBodyPtr(new ChBody);
  m_UCA->SetNameString(name + "_UCA");
  m_revoluteUCA = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute);
  m_revoluteUCA->SetNameString(name + "_revoluteUCA");
  m_sphericalUCA = ChSharedPtr<ChLinkLockSpherical>(new ChLinkLockSpherical);
  m_sphericalUCA->SetNameString(name + "_sphericalUCA");

  // Bodies and constraints to model lower control arm
  m_LCA = ChSharedBodyPtr(new ChBody);
  m_LCA->SetNameString(name + "_LCA");
  m_revoluteLCA = ChSharedPtr<ChLinkLockRevolute>(new ChLinkLockRevolute);
  m_revoluteLCA->SetNameString(name + "_revoluteLCA");
  m_sphericalLCA = ChSharedPtr<ChLinkLockSpherical>(new ChLinkLockSpherical);
  m_sphericalLCA->SetNameString(name + "_sphericalLCA");

  // Distance constraint to model the tierod
  m_distTierod = ChSharedPtr<ChLinkDistance>(new ChLinkDistance);
  m_distTierod->SetNameString(name + "_distTierod");

  // Spring-damper
  m_shock = ChSharedPtr<ChLinkSpring>(new ChLinkSpring);
  m_shock->SetNameString(name + "_shock");

  // If driven, create the axle shaft and its connection to the spindle.
  if (m_driven) {
    m_axle = ChSharedPtr<ChShaft>(new ChShaft);
    m_axle->SetNameString(name + "_axle");

    m_axle_to_spindle = ChSharedPtr<ChShaftsBody>(new ChShaftsBody);
    m_axle_to_spindle->SetNameString(name + "_axle_to_spindle");
  }
}

// -----------------------------------------------------------------------------
// TODO: does it make sense to ask for a complete Coordsys (i.e. allow for a
// non-identity rotation) when attaching a suspension subsystem to the chassis?
// -----------------------------------------------------------------------------
void
ChDoubleWishbone::Initialize(ChSharedBodyPtr   chassis,
                                    const ChVector<>& location)
{
  // Transform all points to absolute frame
  for (int i = 0; i < NUM_POINTS; i++) {
    ChVector<> rel_pos = getLocation(static_cast<PointId>(i));
    if (m_side == LEFT)
      rel_pos.y = -rel_pos.y;
    m_points[i] = chassis->GetCoord().TransformLocalToParent(location + rel_pos);
  }

  // Set body positions and rotations, mass properties, etc.
  m_spindle->SetPos(m_points[SPINDLE]);
  m_spindle->SetRot(chassis->GetCoord().rot);
  m_spindle->SetMass(getSpindleMass());
  m_spindle->SetInertiaXX(getSpindleInertia());
  OnInitializeSpindle();
  chassis->GetSystem()->AddBody(m_spindle);

  m_UCA->SetPos(m_points[UCA_CM]);
  // Determine the rotation matrix of the UCA based on the plane of the hard points
  ChVector<> wRot;
  wRot.Cross(m_points[UCA_F]-m_points[UCA_U], m_points[UCA_B]-m_points[UCA_U]);
  wRot.Normalize();
  ChVector<> uRot = m_points[UCA_B]-m_points[UCA_F];
  uRot.Normalize();
  ChVector<> vRot;
  vRot.Cross(wRot,uRot);
  ChMatrix33<> rotationMatrix;
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_UCA->SetRot(rotationMatrix); // Set the rotation of the UCA
  m_UCA->SetMass(getUCAMass());
  m_UCA->SetInertiaXX(getUCAInertia());
  AddVisualizationUCA();
  OnInitializeUCA();
  chassis->GetSystem()->AddBody(m_UCA);

  m_LCA->SetPos(m_points[LCA_CM]);
  // Determine the rotation matrix of the LCA based on the plane of the hard points
  wRot.Cross(m_points[LCA_F]-m_points[LCA_U], m_points[LCA_B]-m_points[LCA_U]);
  wRot.Normalize();
  uRot = m_points[LCA_B]-m_points[LCA_F];
  uRot.Normalize();
  vRot.Cross(wRot,uRot);
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_LCA->SetRot(rotationMatrix); // Set the rotation of the LCA
  m_LCA->SetMass(getLCAMass());
  m_LCA->SetInertiaXX(getLCAInertia());
  AddVisualizationLCA();
  OnInitializeLCA();
  chassis->GetSystem()->AddBody(m_LCA);

  m_upright->SetPos(m_points[UPRIGHT]);
  m_upright->SetRot(chassis->GetCoord().rot);
  m_upright->SetMass(getUprightMass());
  m_upright->SetInertiaXX(getUprightInertia());
  AddVisualizationUpright();
  OnInitializeUpright();
  chassis->GetSystem()->AddBody(m_upright);

  // Initialize joints
  ChCoordsys<> rev_csys(m_points[UPRIGHT], Q_from_AngAxis(CH_C_PI / 2.0, VECT_X));
  m_revolute->Initialize(m_spindle, m_upright, rev_csys);
  chassis->GetSystem()->AddLink(m_revolute);

  // Determine the rotation matrix of the UCA based on the plane of the hard points
  wRot = m_points[UCA_B]-m_points[UCA_F];
  wRot.Normalize();
  uRot = ChVector<>(0,0,1);
  uRot.Normalize();
  vRot.Cross(wRot,uRot);
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_revoluteUCA->Initialize(chassis, m_UCA, ChCoordsys<>((m_points[UCA_F]+m_points[UCA_B])/2, rotationMatrix.Get_A_quaternion()));
  chassis->GetSystem()->AddLink(m_revoluteUCA);
  m_sphericalUCA->Initialize(m_UCA, m_upright, ChCoordsys<>(m_points[UCA_U], QUNIT));
  chassis->GetSystem()->AddLink(m_sphericalUCA);

  // Determine the rotation matrix of the LCA based on the plane of the hard points
  wRot = m_points[LCA_B]-m_points[LCA_F];
  wRot.Normalize();
  uRot = ChVector<>(0,0,1);
  uRot.Normalize();
  vRot.Cross(wRot,uRot);
  rotationMatrix.Set_A_axis(uRot,vRot,wRot);
  m_revoluteLCA->Initialize(chassis, m_LCA, ChCoordsys<>((m_points[LCA_F]+m_points[LCA_B])/2, rotationMatrix.Get_A_quaternion()));
  chassis->GetSystem()->AddLink(m_revoluteLCA);
  m_sphericalLCA->Initialize(m_LCA, m_upright, ChCoordsys<>(m_points[LCA_U], QUNIT));
  chassis->GetSystem()->AddLink(m_sphericalLCA);

  m_distTierod->Initialize(chassis, m_upright, false, m_points[TIEROD_C], m_points[TIEROD_U]);
  chassis->GetSystem()->AddLink(m_distTierod);

  // Initialize the spring/damper
  m_shock->Initialize(chassis, m_LCA, false, m_points[SHOCK_C], m_points[SHOCK_U]);
  m_shock->Set_SpringK(getSpringCoefficient());
  m_shock->Set_SpringR(getDampingCoefficient());
  m_shock->Set_SpringRestLength(getSpringRestLength());
  chassis->GetSystem()->AddLink(m_shock);

  // Save initial relative position of marker 1 of the tierod distance link,
  // to be used in steering.
  m_tierod_marker = m_distTierod->GetEndPoint1Rel();

  // Initialize the axle shaft and its connection to the spindle. Note that the
  // spindle rotates about the Y axis.
  if (m_driven) {
    m_axle->SetInertia(getAxleInertia());
    chassis->GetSystem()->Add(m_axle);
    m_axle_to_spindle->Initialize(m_axle, m_spindle, ChVector<>(0, 1, 0));
    chassis->GetSystem()->Add(m_axle_to_spindle);
  }

}

// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void ChDoubleWishbone::AddVisualizationLCA()
{
  // Express hardpoint locations in body frame.
  ChVector<> p_F = m_LCA->TransformPointParentToLocal(m_points[LCA_F]);
  ChVector<> p_B = m_LCA->TransformPointParentToLocal(m_points[LCA_B]);
  ChVector<> p_U = m_LCA->TransformPointParentToLocal(m_points[LCA_U]);

  ChSharedPtr<ChCylinderShape> cyl_F(new ChCylinderShape);
  cyl_F->GetCylinderGeometry().p1 = p_F;
  cyl_F->GetCylinderGeometry().p2 = p_U;
  cyl_F->GetCylinderGeometry().rad = getLCARadius();
  m_LCA->AddAsset(cyl_F);

  ChSharedPtr<ChCylinderShape> cyl_B(new ChCylinderShape);
  cyl_B->GetCylinderGeometry().p1 = p_B;
  cyl_B->GetCylinderGeometry().p2 = p_U;
  cyl_B->GetCylinderGeometry().rad = getLCARadius();
  m_LCA->AddAsset(cyl_B);

  ChSharedPtr<ChColorAsset> col(new ChColorAsset);
  switch (m_side) {
  case RIGHT: col->SetColor(ChColor(0.6f, 0.4f, 0.4f)); break;
  case LEFT:  col->SetColor(ChColor(0.4f, 0.4f, 0.6f)); break;
  }
  m_LCA->AddAsset(col);
}

void ChDoubleWishbone::AddVisualizationUCA()
{
  // Express hardpoint locations in body frame.
  ChVector<> p_F = m_UCA->TransformPointParentToLocal(m_points[UCA_F]);
  ChVector<> p_B = m_UCA->TransformPointParentToLocal(m_points[UCA_B]);
  ChVector<> p_U = m_UCA->TransformPointParentToLocal(m_points[UCA_U]);

  ChSharedPtr<ChCylinderShape> cyl_F(new ChCylinderShape);
  cyl_F->GetCylinderGeometry().p1 = p_F;
  cyl_F->GetCylinderGeometry().p2 = p_U;
  cyl_F->GetCylinderGeometry().rad = getUCARadius();
  m_UCA->AddAsset(cyl_F);

  ChSharedPtr<ChCylinderShape> cyl_B(new ChCylinderShape);
  cyl_B->GetCylinderGeometry().p1 = p_B;
  cyl_B->GetCylinderGeometry().p2 = p_U;
  cyl_B->GetCylinderGeometry().rad = getUCARadius();
  m_UCA->AddAsset(cyl_B);

  ChSharedPtr<ChColorAsset> col(new ChColorAsset);
  switch (m_side) {
  case RIGHT: col->SetColor(ChColor(0.6f, 0.4f, 0.4f)); break;
  case LEFT:  col->SetColor(ChColor(0.4f, 0.4f, 0.6f)); break;
  }
  m_UCA->AddAsset(col);
}

void ChDoubleWishbone::AddVisualizationUpright()
{
  // Express hardpoint locations in body frame.
  ChVector<> p_U = m_upright->TransformPointParentToLocal(m_points[UCA_U]);
  ChVector<> p_L = m_upright->TransformPointParentToLocal(m_points[LCA_U]);

  ChSharedPtr<ChCylinderShape> cyl(new ChCylinderShape);
  cyl->GetCylinderGeometry().p1 = p_U;
  cyl->GetCylinderGeometry().p2 = p_L;
  cyl->GetCylinderGeometry().rad = getUprightRadius();
  m_upright->AddAsset(cyl);

  ChSharedPtr<ChColorAsset> col(new ChColorAsset);
  switch (m_side) {
  case RIGHT: col->SetColor(ChColor(0.6f, 0.1f, 0.1f)); break;
  case LEFT:  col->SetColor(ChColor(0.1f, 0.1f, 0.6f)); break;
  }
  m_upright->AddAsset(col);
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
void ChDoubleWishbone::ApplySteering(double displ)
{
  ChVector<> r_bar = m_tierod_marker;
  r_bar.y += displ;
  m_distTierod->SetEndPoint1Rel(r_bar);
}

} // end namespace chrono
<|endoftext|>


<commit_before>/*
 * File:   AlarmClockSpeedTest.cpp
 * Author: Amanda Carbonari
 * Created: January 6, 2015 9:00am
 *
 * WARNING: This only measures CPU time
 */

#include <ctime>
#include <iostream>
#include <AlarmClock.h>
using namespace std;
typedef std::chrono::microseconds microseconds;
typedef std::chrono::milliseconds milliseconds;
typedef std::chrono::seconds seconds;

template<typename T> void WaitForAlarmClockToExpire(AlarmClock<T>& alerter) {
	while(!alerter.Expired());
}

int main(int, const char**) {
 	clock_t start;
 	unsigned int us = 389;

 	cout << "Creating Alarm Clock" << endl;
 	boost::thread(AlarmClock<microseconds> alerter(us)).join();

 	cout << "Starting clock and resetting" << endl;
 	start = clock();
 	alerter.Reset();
 	clock_t reset_time = (clock() - start) / (double) (CLOCKS_PER_SEC/1000);

 	cout << "Waiting for the clock to expire" << endl;
 	WaitForAlarmClockToExpire(alerter);

 	cout << "Time: " << reset_time << " ms" << endl;
}<commit_msg>Debugging performance test<commit_after>/*
 * File:   AlarmClockSpeedTest.cpp
 * Author: Amanda Carbonari
 * Created: January 6, 2015 9:00am
 *
 * WARNING: This only measures CPU time
 */

#include <ctime>
#include <iostream>
#include <AlarmClock.h>
using namespace std;
typedef std::chrono::microseconds microseconds;
typedef std::chrono::milliseconds milliseconds;
typedef std::chrono::seconds seconds;

template<typename T> void WaitForAlarmClockToExpire(AlarmClock<T>& alerter) {
	while(!alerter.Expired());
}

int main(int, const char**) {
 	clock_t start;
 	unsigned int us = 389;

 	cout << "Creating Alarm Clock" << endl;
 	AlarmClock<microseconds> alerter(us);
 	boost::this_thread::sleep_for(boost::chrono::microseconds(20));
 	cout << "Starting clock and resetting" << endl;
 	start = clock();
 	alerter.Reset();
 	clock_t reset_time = (clock() - start) / (double) (CLOCKS_PER_SEC/1000);

 	cout << "Waiting for the clock to expire" << endl;
 	WaitForAlarmClockToExpire(alerter);

 	cout << "Time: " << reset_time << " ms" << endl;
}<|endoftext|>


<commit_before><commit_msg>cppcheck: variableScope<commit_after><|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef KVSTORE_HH
#define KVSTORE_HH 1

#include <map>
#include <string>
#include <utility>

#include <cstring>

#include "stats.hh"
#include "item.hh"
#include "queueditem.hh"

/**
 * Result of database mutation operations.
 *
 * This is a pair where .first is the number of rows affected, and
 * .second is the ID that was generated (if any).  .second will be 0
 * on updates (not generating an ID).
 *
 * .first will be -1 if there was an error performing the update.
 *
 * .first will be 0 if the update did not error, but did not occur.
 * This would generally be considered a fatal condition (in practice,
 * it requires you to be firing an update at a missing rowid).
 */
typedef std::pair<int, int64_t> mutation_result;

struct vbucket_state {
    vbucket_state_t state;
    uint64_t checkpointId;
};

/**
 * Type of vbucket map.
 *
 * key.first is the vbucket identifier.
 * key.second is the vbucket version
 * value is a pair of string representation of the vbucket state and
 * its latest checkpoint Id persisted.
 */
typedef std::map<std::pair<uint16_t, uint16_t>, vbucket_state> vbucket_map_t;

/**
 * Properites of the storage layer.
 *
 * If concurrent filesystem access is possible, maxConcurrency() will
 * be greater than one.  One will need to determine whether more than
 * one writer is possible as well as whether more than one reader is
 * possible.
 */
class StorageProperties {
public:

    StorageProperties(size_t c, size_t r, size_t w, bool evb, bool evd)
        : maxc(c), maxr(r), maxw(w), efficientVBDump(evb),
          efficientVBDeletion(evd) {}

    //! The maximum number of active queries.
    size_t maxConcurrency()   const { return maxc; }
    //! Maximum number of active read-only connections.
    size_t maxReaders()       const { return maxr; }
    //! Maximum number of active connections for read and write.
    size_t maxWriters()       const { return maxw; }
    //! True if we can efficiently dump a single vbucket.
    bool hasEfficientVBDump() const { return efficientVBDump; }
    //! True if we can efficiently delete a vbucket all at once.
    bool hasEfficientVBDeletion() const { return efficientVBDeletion; }

private:
    size_t maxc;
    size_t maxr;
    size_t maxw;
    bool efficientVBDump;
    bool efficientVBDeletion;
};

/**
 * Database strategy
 */
enum db_type {
    single_db,           //!< single database strategy
    multi_db,            //!< multi-database strategy
    single_mt_db,        //!< single database, multi-table strategy
    multi_mt_db,         //!< multi-database, multi-table strategy
    multi_mt_vb_db       //!< multi-db, multi-table strategy sharded by vbucket
};

/**
 * Base class representing kvstore operations.
 */
class KVStore {
public:
    virtual ~KVStore() {}

    /**
     * Allow the kvstore to add extra statistics information
     * back to the client
     * @param prefix prefix to use for the stats
     * @param add_stat the callback function to add statistics
     * @param c the cookie to pass to the callback function
     */
    virtual void addStats(const std::string &prefix, ADD_STAT add_stat, const void *c) {
        (void)prefix;
        (void)add_stat;
        (void)c;
    }

    /**
     * Show kvstore specific timing stats.
     *
     * @param prefix prefix to use for the stats
     * @param add_stat the callback function to add statistics
     * @param c the cookie to pass to the callback function
     */
    virtual void addTimingStats(const std::string &, ADD_STAT, const void *) {
    }

    /**
     * Reset the store to a clean state.
     */
    virtual void reset() = 0;

    /**
     * Begin a transaction (if not already in one).
     *
     * @return false if we cannot begin a transaction
     */
    virtual bool begin() = 0;

    /**
     * Commit a transaction (unless not currently in one).
     *
     * @return false if the commit fails
     */
    virtual bool commit() = 0;

    /**
     * Rollback the current transaction.
     */
    virtual void rollback() = 0;

    /**
     * Get the properties of the underlying storage.
     */
    virtual StorageProperties getStorageProperties() = 0;

    /**
     * Set an item into the kv store.
     */
    virtual void set(const Item &item, uint16_t vb_version,
                     Callback<mutation_result> &cb) = 0;

    /**
     * Get an item from the kv store.
     */
    virtual void get(const std::string &key, uint64_t rowid,
                     uint16_t vb, uint16_t vbver,
                     Callback<GetValue> &cb) = 0;

    /**
     * Delete an item from the kv store.
     */
    virtual void del(const Item &itm, uint64_t rowid,
                     uint16_t vbver, Callback<int> &cb) = 0;

    /**
     * Bulk delete some versioned records from a vbucket.
     */
    virtual bool delVBucket(uint16_t vbucket, uint16_t vb_version) = 0;

    /**
     * Bulk delete some versioned records from a vbucket.
     */
    virtual bool delVBucket(uint16_t vbucket, uint16_t vb_version,
                            std::pair<int64_t, int64_t> row_range) = 0;

    /**
     * Invoked whenever vbucket states change.
     *
     * @param vbucket the vbucket that was updated
     * @param newState the new state of this vbucket
     */
    virtual void vbStateChanged(uint16_t vbucket, vbucket_state_t newState) {
        (void)vbucket; (void)newState;
    }

    /**
     * Get a list of all persisted vbuckets (with their versions and states).
     */
    virtual vbucket_map_t listPersistedVbuckets(void) = 0;

    /**
     * Persist a snapshot of a collection of stats.
     */
    virtual bool snapshotStats(const std::map<std::string, std::string> &m) = 0;

    /**
     * Snapshot vbucket states.
     */
    virtual bool snapshotVBuckets(const vbucket_map_t &m) = 0;

    /**
     * Pass all stored data through the given callback.
     */
    virtual void dump(shared_ptr<Callback<GetValue> > cb) = 0;

    /**
     * Pass all stored data for the given vbucket through the given
     * callback.
     */
    virtual void dump(uint16_t vbid, shared_ptr<Callback<GetValue> > cb) = 0;

    /**
     * Check if the kv-store supports a dumping all of the keys
     * @return true you may call dumpKeys() to do a prefetch
     *              of the keys
     */
    virtual bool isKeyDumpSupported() {
        return false;
    }

    /**
     * Dump the keys from a given set of vbuckets
     * @param vbids the vbuckets to dump
     * @param cb the callback to fire for each document
     */
    virtual void dumpKeys(const std::vector<uint16_t> &vbids, shared_ptr<Callback<GetValue> > cb) {
        (void)vbids; (void)cb;
        throw std::runtime_error("Unsupported operation");
    }

    /**
     * Get the number of data shards in this kvstore.
     */
    virtual size_t getNumShards() {
        return 1;
    }

    /**
     * get the shard ID for the given queued item.
     */
    virtual size_t getShardId(const QueuedItem &i) {
        (void)i;
        return 0;
    }

    /**
     * This method is called before persisting a batch of data if you'd like to
     * do stuff to them that might improve performance at the IO layer.
     */
    virtual void optimizeWrites(std::vector<queued_item> &items) {
        (void)items;
        // EMPTY
    }

    virtual void processTxnSizeChange(size_t txn_size) {
        (void)txn_size;
    }

    virtual void setVBBatchCount(size_t batch_count) {
        (void)batch_count;
    }

    /**
     * Remove invalid vbuckets from the underlying storage engine.
     * @param destroyOnlyOne True if this run should remove only one invalid vbucket.
     * This can be set to true if we want to delete all invalid vbuckets over the time.
     */
    virtual void destroyInvalidVBuckets(bool destroyOnlyOne = false) = 0;

};

/**
 * The KVStoreFactory creates the correct KVStore instance(s) when
 * needed by EPStore.
 */
class KVStoreFactory {
public:

    /**
     * Create a KVStore with the given properties.
     *
     * @param type the type of DB to set up
     * @param stats the server stats
     * @param conf type-specific parameters
     */
    static KVStore *create(EventuallyPersistentEngine &theEngine);
};

#endif // KVSTORE_HH
<commit_msg>Improve error message in exception<commit_after>/* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
#ifndef KVSTORE_HH
#define KVSTORE_HH 1

#include <map>
#include <string>
#include <utility>

#include <cstring>

#include "stats.hh"
#include "item.hh"
#include "queueditem.hh"

/**
 * Result of database mutation operations.
 *
 * This is a pair where .first is the number of rows affected, and
 * .second is the ID that was generated (if any).  .second will be 0
 * on updates (not generating an ID).
 *
 * .first will be -1 if there was an error performing the update.
 *
 * .first will be 0 if the update did not error, but did not occur.
 * This would generally be considered a fatal condition (in practice,
 * it requires you to be firing an update at a missing rowid).
 */
typedef std::pair<int, int64_t> mutation_result;

struct vbucket_state {
    vbucket_state_t state;
    uint64_t checkpointId;
};

/**
 * Type of vbucket map.
 *
 * key.first is the vbucket identifier.
 * key.second is the vbucket version
 * value is a pair of string representation of the vbucket state and
 * its latest checkpoint Id persisted.
 */
typedef std::map<std::pair<uint16_t, uint16_t>, vbucket_state> vbucket_map_t;

/**
 * Properites of the storage layer.
 *
 * If concurrent filesystem access is possible, maxConcurrency() will
 * be greater than one.  One will need to determine whether more than
 * one writer is possible as well as whether more than one reader is
 * possible.
 */
class StorageProperties {
public:

    StorageProperties(size_t c, size_t r, size_t w, bool evb, bool evd)
        : maxc(c), maxr(r), maxw(w), efficientVBDump(evb),
          efficientVBDeletion(evd) {}

    //! The maximum number of active queries.
    size_t maxConcurrency()   const { return maxc; }
    //! Maximum number of active read-only connections.
    size_t maxReaders()       const { return maxr; }
    //! Maximum number of active connections for read and write.
    size_t maxWriters()       const { return maxw; }
    //! True if we can efficiently dump a single vbucket.
    bool hasEfficientVBDump() const { return efficientVBDump; }
    //! True if we can efficiently delete a vbucket all at once.
    bool hasEfficientVBDeletion() const { return efficientVBDeletion; }

private:
    size_t maxc;
    size_t maxr;
    size_t maxw;
    bool efficientVBDump;
    bool efficientVBDeletion;
};

/**
 * Database strategy
 */
enum db_type {
    single_db,           //!< single database strategy
    multi_db,            //!< multi-database strategy
    single_mt_db,        //!< single database, multi-table strategy
    multi_mt_db,         //!< multi-database, multi-table strategy
    multi_mt_vb_db       //!< multi-db, multi-table strategy sharded by vbucket
};

/**
 * Base class representing kvstore operations.
 */
class KVStore {
public:
    virtual ~KVStore() {}

    /**
     * Allow the kvstore to add extra statistics information
     * back to the client
     * @param prefix prefix to use for the stats
     * @param add_stat the callback function to add statistics
     * @param c the cookie to pass to the callback function
     */
    virtual void addStats(const std::string &prefix, ADD_STAT add_stat, const void *c) {
        (void)prefix;
        (void)add_stat;
        (void)c;
    }

    /**
     * Show kvstore specific timing stats.
     *
     * @param prefix prefix to use for the stats
     * @param add_stat the callback function to add statistics
     * @param c the cookie to pass to the callback function
     */
    virtual void addTimingStats(const std::string &, ADD_STAT, const void *) {
    }

    /**
     * Reset the store to a clean state.
     */
    virtual void reset() = 0;

    /**
     * Begin a transaction (if not already in one).
     *
     * @return false if we cannot begin a transaction
     */
    virtual bool begin() = 0;

    /**
     * Commit a transaction (unless not currently in one).
     *
     * @return false if the commit fails
     */
    virtual bool commit() = 0;

    /**
     * Rollback the current transaction.
     */
    virtual void rollback() = 0;

    /**
     * Get the properties of the underlying storage.
     */
    virtual StorageProperties getStorageProperties() = 0;

    /**
     * Set an item into the kv store.
     */
    virtual void set(const Item &item, uint16_t vb_version,
                     Callback<mutation_result> &cb) = 0;

    /**
     * Get an item from the kv store.
     */
    virtual void get(const std::string &key, uint64_t rowid,
                     uint16_t vb, uint16_t vbver,
                     Callback<GetValue> &cb) = 0;

    /**
     * Delete an item from the kv store.
     */
    virtual void del(const Item &itm, uint64_t rowid,
                     uint16_t vbver, Callback<int> &cb) = 0;

    /**
     * Bulk delete some versioned records from a vbucket.
     */
    virtual bool delVBucket(uint16_t vbucket, uint16_t vb_version) = 0;

    /**
     * Bulk delete some versioned records from a vbucket.
     */
    virtual bool delVBucket(uint16_t vbucket, uint16_t vb_version,
                            std::pair<int64_t, int64_t> row_range) = 0;

    /**
     * Invoked whenever vbucket states change.
     *
     * @param vbucket the vbucket that was updated
     * @param newState the new state of this vbucket
     */
    virtual void vbStateChanged(uint16_t vbucket, vbucket_state_t newState) {
        (void)vbucket; (void)newState;
    }

    /**
     * Get a list of all persisted vbuckets (with their versions and states).
     */
    virtual vbucket_map_t listPersistedVbuckets(void) = 0;

    /**
     * Persist a snapshot of a collection of stats.
     */
    virtual bool snapshotStats(const std::map<std::string, std::string> &m) = 0;

    /**
     * Snapshot vbucket states.
     */
    virtual bool snapshotVBuckets(const vbucket_map_t &m) = 0;

    /**
     * Pass all stored data through the given callback.
     */
    virtual void dump(shared_ptr<Callback<GetValue> > cb) = 0;

    /**
     * Pass all stored data for the given vbucket through the given
     * callback.
     */
    virtual void dump(uint16_t vbid, shared_ptr<Callback<GetValue> > cb) = 0;

    /**
     * Check if the kv-store supports a dumping all of the keys
     * @return true you may call dumpKeys() to do a prefetch
     *              of the keys
     */
    virtual bool isKeyDumpSupported() {
        return false;
    }

    /**
     * Dump the keys from a given set of vbuckets
     * @param vbids the vbuckets to dump
     * @param cb the callback to fire for each document
     */
    virtual void dumpKeys(const std::vector<uint16_t> &vbids, shared_ptr<Callback<GetValue> > cb) {
        (void)vbids; (void)cb;
        throw std::runtime_error("Backed does not support dumpKeys()");
    }

    /**
     * Get the number of data shards in this kvstore.
     */
    virtual size_t getNumShards() {
        return 1;
    }

    /**
     * get the shard ID for the given queued item.
     */
    virtual size_t getShardId(const QueuedItem &i) {
        (void)i;
        return 0;
    }

    /**
     * This method is called before persisting a batch of data if you'd like to
     * do stuff to them that might improve performance at the IO layer.
     */
    virtual void optimizeWrites(std::vector<queued_item> &items) {
        (void)items;
        // EMPTY
    }

    virtual void processTxnSizeChange(size_t txn_size) {
        (void)txn_size;
    }

    virtual void setVBBatchCount(size_t batch_count) {
        (void)batch_count;
    }

    /**
     * Remove invalid vbuckets from the underlying storage engine.
     * @param destroyOnlyOne True if this run should remove only one invalid vbucket.
     * This can be set to true if we want to delete all invalid vbuckets over the time.
     */
    virtual void destroyInvalidVBuckets(bool destroyOnlyOne = false) = 0;

};

/**
 * The KVStoreFactory creates the correct KVStore instance(s) when
 * needed by EPStore.
 */
class KVStoreFactory {
public:

    /**
     * Create a KVStore with the given properties.
     *
     * @param type the type of DB to set up
     * @param stats the server stats
     * @param conf type-specific parameters
     */
    static KVStore *create(EventuallyPersistentEngine &theEngine);
};

#endif // KVSTORE_HH
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2003-2007 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/faults.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#if !FULL_SYSTEM
#include "arch/x86/isa_traits.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#endif

namespace X86ISA
{
#if FULL_SYSTEM
    void X86Trap::invoke(TheeadContext * tc)
    {
        panic("X86 faults are not implemented!");
    }

    void X86Abort::invoke(TheeadContext * tc)
    {
        panic("X86 faults are not implemented!");
    }

    void X86Interrupt::invoke(TheeadContext * tc)
    {
        panic("X86 faults are not implemented!");
    }
#else // !FULL_SYSTEM
    void FakeITLBFault::invoke(ThreadContext * tc)
    {
        DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n",
                vaddr, tc->readPC());
        Process *p = tc->getProcessPtr();
        Addr paddr;
        bool success = p->pTable->translate(vaddr, paddr);
        if(!success) {
            panic("Tried to execute unmapped address %#x.\n", vaddr);
        } else {
            TlbEntry entry;
            entry.pageStart = p->pTable->pageAlign(paddr);
            entry.writeable = false;
            entry.user = true;
            entry.uncacheable = false;
            entry.global = false;
            entry.patBit = 0;
            entry.noExec = false;
            entry.size = PageBytes;
            Addr alignedVaddr = p->pTable->pageAlign(vaddr);
            DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
            tc->getITBPtr()->insert(alignedVaddr, entry);
        }
    }

    void FakeDTLBFault::invoke(ThreadContext * tc)
    {
        DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n",
                vaddr, tc->readPC());
        Process *p = tc->getProcessPtr();
        Addr paddr;
        bool success = p->pTable->translate(vaddr, paddr);
        if(!success) {
            p->checkAndAllocNextPage(vaddr);
            success = p->pTable->translate(vaddr, paddr);
        }
        if(!success) {
            panic("Tried to access unmapped address %#x.\n", vaddr);
        } else {
            TlbEntry entry;
            entry.pageStart = p->pTable->pageAlign(paddr);
            entry.writeable = true;
            entry.user = true;
            entry.uncacheable = false;
            entry.global = false;
            entry.patBit = 0;
            entry.noExec = true;
            entry.size = PageBytes;
            Addr alignedVaddr = p->pTable->pageAlign(vaddr);
            DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
            tc->getDTBPtr()->insert(alignedVaddr, entry);
        }
    }
#endif
} // namespace X86ISA

<commit_msg>X86: X86 FS compile fix.<commit_after>/*
 * Copyright (c) 2003-2007 The Regents of The University of Michigan
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met: redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer;
 * redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution;
 * neither the name of the copyright holders nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

/*
 * Copyright (c) 2007 The Hewlett-Packard Development Company
 * All rights reserved.
 *
 * Redistribution and use of this software in source and binary forms,
 * with or without modification, are permitted provided that the
 * following conditions are met:
 *
 * The software must be used only for Non-Commercial Use which means any
 * use which is NOT directed to receiving any direct monetary
 * compensation for, or commercial advantage from such use.  Illustrative
 * examples of non-commercial use are academic research, personal study,
 * teaching, education and corporate research & development.
 * Illustrative examples of commercial use are distributing products for
 * commercial advantage and providing services using the software for
 * commercial advantage.
 *
 * If you wish to use this software or functionality therein that may be
 * covered by patents for commercial use, please contact:
 *     Director of Intellectual Property Licensing
 *     Office of Strategy and Technology
 *     Hewlett-Packard Company
 *     1501 Page Mill Road
 *     Palo Alto, California  94304
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.  Redistributions
 * in binary form must reproduce the above copyright notice, this list of
 * conditions and the following disclaimer in the documentation and/or
 * other materials provided with the distribution.  Neither the name of
 * the COPYRIGHT HOLDER(s), HEWLETT-PACKARD COMPANY, nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.  No right of
 * sublicense is granted herewith.  Derivatives of the software and
 * output created using the software may be prepared, but only for
 * Non-Commercial Uses.  Derivatives of the software may be shared with
 * others provided: (i) the others agree to abide by the list of
 * conditions herein which includes the Non-Commercial Use restrictions;
 * and (ii) such Derivatives of the software include the above copyright
 * notice to acknowledge the contribution from this software where
 * applicable, this list of conditions and the disclaimer below.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Authors: Gabe Black
 */

#include "arch/x86/faults.hh"
#include "base/trace.hh"
#include "config/full_system.hh"
#include "cpu/thread_context.hh"
#if !FULL_SYSTEM
#include "arch/x86/isa_traits.hh"
#include "mem/page_table.hh"
#include "sim/process.hh"
#endif

namespace X86ISA
{
#if FULL_SYSTEM
    void X86Trap::invoke(ThreadContext * tc)
    {
        panic("X86 faults are not implemented!");
    }

    void X86Abort::invoke(ThreadContext * tc)
    {
        panic("X86 faults are not implemented!");
    }

    void X86Interrupt::invoke(ThreadContext * tc)
    {
        panic("X86 faults are not implemented!");
    }
#else // !FULL_SYSTEM
    void FakeITLBFault::invoke(ThreadContext * tc)
    {
        DPRINTF(TLB, "Invoking an ITLB fault for address %#x at pc %#x.\n",
                vaddr, tc->readPC());
        Process *p = tc->getProcessPtr();
        Addr paddr;
        bool success = p->pTable->translate(vaddr, paddr);
        if(!success) {
            panic("Tried to execute unmapped address %#x.\n", vaddr);
        } else {
            TlbEntry entry;
            entry.pageStart = p->pTable->pageAlign(paddr);
            entry.writeable = false;
            entry.user = true;
            entry.uncacheable = false;
            entry.global = false;
            entry.patBit = 0;
            entry.noExec = false;
            entry.size = PageBytes;
            Addr alignedVaddr = p->pTable->pageAlign(vaddr);
            DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
            tc->getITBPtr()->insert(alignedVaddr, entry);
        }
    }

    void FakeDTLBFault::invoke(ThreadContext * tc)
    {
        DPRINTF(TLB, "Invoking an DTLB fault for address %#x at pc %#x.\n",
                vaddr, tc->readPC());
        Process *p = tc->getProcessPtr();
        Addr paddr;
        bool success = p->pTable->translate(vaddr, paddr);
        if(!success) {
            p->checkAndAllocNextPage(vaddr);
            success = p->pTable->translate(vaddr, paddr);
        }
        if(!success) {
            panic("Tried to access unmapped address %#x.\n", vaddr);
        } else {
            TlbEntry entry;
            entry.pageStart = p->pTable->pageAlign(paddr);
            entry.writeable = true;
            entry.user = true;
            entry.uncacheable = false;
            entry.global = false;
            entry.patBit = 0;
            entry.noExec = true;
            entry.size = PageBytes;
            Addr alignedVaddr = p->pTable->pageAlign(vaddr);
            DPRINTF(TLB, "Mapping %#x to %#x\n", alignedVaddr, entry.pageStart);
            tc->getDTBPtr()->insert(alignedVaddr, entry);
        }
    }
#endif
} // namespace X86ISA

<|endoftext|>


<commit_before>/*
 * Copyright 2013-2014 Jose Fonseca
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "tap.h"

#include <stdlib.h>

#include <windows.h>
#include <dbghelp.h>

static bool
comparePath(const char *s1, const char *s2)
{
    while (true) {
        char c1 = *s1++;
        char c2 = *s2++;
        if (c1 == '/') {
            c1 = '\\';
        }
        if (c2 == '/') {
            c2 = '\\';
        }
        if (c2 != c1) {
            return false;
        }
        if (c1 == 0) {
            return true;
        }
    }
}

static void
checkSym(HANDLE hProcess,
         PVOID pvSymbol,
         const char *szSymbolName)
{
    bool ok;

    DWORD64 dwAddr = (DWORD64)(UINT_PTR)pvSymbol;

    // Test SymFromAddr
    DWORD64 Displacement = 0;
    struct {
        SYMBOL_INFO Symbol;
        CHAR Name[256];
    } s;
    memset(&s, 0, sizeof s);
    s.Symbol.SizeOfStruct = sizeof s.Symbol;
    s.Symbol.MaxNameLen = sizeof s.Symbol.Name + sizeof s.Name;
    ok = SymFromAddr(hProcess, dwAddr, &Displacement, &s.Symbol);
    test_line(ok, "SymFromAddr(&%s)", szSymbolName);
    if (!ok) {
        test_diagnostic_last_error();
    } else {
        ok = strcmp(s.Symbol.Name, szSymbolName) == 0;
        test_line(ok, "SymFromAddr(&%s).Name", szSymbolName);
        if (!ok) {
            test_diagnostic("Name = \"%s\" != \"%s\"",
                            s.Symbol.Name, szSymbolName);
        }
    }
}

static void
checkSymLine(HANDLE hProcess,
             PVOID pvSymbol,
             const char *szSymbolName,
             const char *szFileName,
             DWORD dwLineNumber)
{
    bool ok;

    DWORD64 dwAddr = (DWORD64)(UINT_PTR)pvSymbol;

    checkSym(hProcess, pvSymbol, szSymbolName);

    // Test SymGetLineFromAddr64
    DWORD dwDisplacement;
    IMAGEHLP_LINE64 Line;
    ZeroMemory(&Line, sizeof Line);
    Line.SizeOfStruct = sizeof Line;
    ok = SymGetLineFromAddr64(hProcess, dwAddr, &dwDisplacement, &Line);
    test_line(ok, "SymGetLineFromAddr64(&%s)", szSymbolName);
    if (!ok) {
        test_diagnostic_last_error();
    } else {
        ok = comparePath(Line.FileName, szFileName);
        test_line(ok, "SymGetLineFromAddr64(&%s).FileName", szSymbolName);
        if (!ok) {
            test_diagnostic("FileName = \"%s\" != \"%s\"",
                            Line.FileName, szFileName);
        }
        ok = Line.LineNumber == dwLineNumber;
        test_line(ok, "SymGetLineFromAddr64(&%s).LineNumber", szSymbolName);
        if (Line.LineNumber != dwLineNumber) {
            test_diagnostic("LineNumber = %lu != %lu",
                            Line.LineNumber, dwLineNumber);
        }
    }
}

static void
    __attribute__ ((noinline))
checkCaller(HANDLE hProcess,
            const char *szSymbolName,
            const char *szFileName,
            DWORD dwLineNumber)
{
    void *addr = __builtin_return_address(0);
    checkSymLine(hProcess, addr, szSymbolName, szFileName, dwLineNumber);
}

static void
checkExport(HANDLE hProcess,
            const char *szModuleName,
            const char *szSymbolName)
{
    HMODULE hModule = GetModuleHandleA(szModuleName);
    const PVOID pvSymbol = (PVOID)GetProcAddress(hModule, szSymbolName);
    checkSym(hProcess, pvSymbol, szSymbolName);
}

static const DWORD foo_line = __LINE__; static int foo(int a, int b) {
    return a * b;
}

#define LINE_BARRIER rand();

int
main()
{
    HANDLE hProcess = GetCurrentProcess();
    bool ok;

    ok = SymInitialize(hProcess, "", TRUE);
    test_line(ok, "SymInitialize()");
    if (!ok) {
        test_diagnostic_last_error();
    } {
        checkSymLine(hProcess, (PVOID)&foo, "foo", __FILE__, foo_line);

        checkCaller(hProcess, "main", __FILE__, __LINE__); LINE_BARRIER

        // Test DbgHelp fallback
        checkExport(hProcess, "kernel32", "Sleep");

        ok = SymCleanup(hProcess);
        test_line(ok, "SymCleanup()");
        if (!ok) {
            test_diagnostic_last_error();
        }
    }

    test_exit();
}
<commit_msg>tests: Check MgwHelp.dll exports.<commit_after>/*
 * Copyright 2013-2014 Jose Fonseca
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include "tap.h"

#include <assert.h>
#include <stdlib.h>

#include <windows.h>
#include <dbghelp.h>

static bool
comparePath(const char *s1, const char *s2)
{
    while (true) {
        char c1 = *s1++;
        char c2 = *s2++;
        if (c1 == '/') {
            c1 = '\\';
        }
        if (c2 == '/') {
            c2 = '\\';
        }
        if (c2 != c1) {
            return false;
        }
        if (c1 == 0) {
            return true;
        }
    }
}

static void
checkSym(HANDLE hProcess,
         PVOID pvSymbol,
         const char *szSymbolName)
{
    bool ok;

    DWORD64 dwAddr = (DWORD64)(UINT_PTR)pvSymbol;

    // Test SymFromAddr
    DWORD64 Displacement = 0;
    struct {
        SYMBOL_INFO Symbol;
        CHAR Name[256];
    } s;
    memset(&s, 0, sizeof s);
    s.Symbol.SizeOfStruct = sizeof s.Symbol;
    s.Symbol.MaxNameLen = sizeof s.Symbol.Name + sizeof s.Name;
    ok = SymFromAddr(hProcess, dwAddr, &Displacement, &s.Symbol);
    test_line(ok, "SymFromAddr(&%s)", szSymbolName);
    if (!ok) {
        test_diagnostic_last_error();
    } else {
        ok = strcmp(s.Symbol.Name, szSymbolName) == 0;
        test_line(ok, "SymFromAddr(&%s).Name", szSymbolName);
        if (!ok) {
            test_diagnostic("Name = \"%s\" != \"%s\"",
                            s.Symbol.Name, szSymbolName);
        }
    }
}

static void
checkSymLine(HANDLE hProcess,
             PVOID pvSymbol,
             const char *szSymbolName,
             const char *szFileName,
             DWORD dwLineNumber)
{
    bool ok;

    DWORD64 dwAddr = (DWORD64)(UINT_PTR)pvSymbol;

    checkSym(hProcess, pvSymbol, szSymbolName);

    // Test SymGetLineFromAddr64
    DWORD dwDisplacement;
    IMAGEHLP_LINE64 Line;
    ZeroMemory(&Line, sizeof Line);
    Line.SizeOfStruct = sizeof Line;
    ok = SymGetLineFromAddr64(hProcess, dwAddr, &dwDisplacement, &Line);
    test_line(ok, "SymGetLineFromAddr64(&%s)", szSymbolName);
    if (!ok) {
        test_diagnostic_last_error();
    } else {
        ok = comparePath(Line.FileName, szFileName);
        test_line(ok, "SymGetLineFromAddr64(&%s).FileName", szSymbolName);
        if (!ok) {
            test_diagnostic("FileName = \"%s\" != \"%s\"",
                            Line.FileName, szFileName);
        }
        ok = Line.LineNumber == dwLineNumber;
        test_line(ok, "SymGetLineFromAddr64(&%s).LineNumber", szSymbolName);
        if (Line.LineNumber != dwLineNumber) {
            test_diagnostic("LineNumber = %lu != %lu",
                            Line.LineNumber, dwLineNumber);
        }
    }
}

static void
    __attribute__ ((noinline))
checkCaller(HANDLE hProcess,
            const char *szSymbolName,
            const char *szFileName,
            DWORD dwLineNumber)
{
    void *addr = __builtin_return_address(0);
    checkSymLine(hProcess, addr, szSymbolName, szFileName, dwLineNumber);
}

static void
checkExport(HANDLE hProcess,
            const char *szModuleName,
            const char *szSymbolName)
{
    HMODULE hModule = GetModuleHandleA(szModuleName);
    const PVOID pvSymbol = (PVOID)GetProcAddress(hModule, szSymbolName);
    checkSym(hProcess, pvSymbol, szSymbolName);
}

static const DWORD foo_line = __LINE__; static int foo(int a, int b) {
    return a * b;
}

#define LINE_BARRIER rand();

int
main()
{
    HANDLE hProcess = GetCurrentProcess();
    bool ok;

    HMODULE hMgwHelpDll = GetModuleHandleA("mgwhelp.dll");
    if (!hMgwHelpDll) {
        test_line(false, "GetModuleHandleA(\"mgwhelp.dll\")");
    } else {
        test_line(GetProcAddress(hMgwHelpDll, "SymGetOptions") != NULL, "GetProcAddress(\"SymGetOptions\")");
        test_line(GetProcAddress(hMgwHelpDll, "SymGetOptions@0") == NULL, "!GetProcAddress(\"SymGetOptions\")");
    }

    ok = SymInitialize(hProcess, "", TRUE);
    test_line(ok, "SymInitialize()");
    if (!ok) {
        test_diagnostic_last_error();
    } {
        checkSymLine(hProcess, (PVOID)&foo, "foo", __FILE__, foo_line);

        checkCaller(hProcess, "main", __FILE__, __LINE__); LINE_BARRIER

        // Test DbgHelp fallback
        checkExport(hProcess, "kernel32", "Sleep");

        ok = SymCleanup(hProcess);
        test_line(ok, "SymCleanup()");
        if (!ok) {
            test_diagnostic_last_error();
        }
    }

    test_exit();
}
<|endoftext|>


<commit_before>#ifndef MCMC_BAS_UTIL
#define MCMC_BAS_UTIL
#define OPT_HEADER
#include "mcmc_traits.hpp"
#include <algorithm>
#include <limits>
#include "distribution.hpp"
namespace mcmc_utilities
{
  template <typename T_p,typename T_var>
  struct dist_adapter
  {
      T_var xl,xr;
      const probability_density_1d<T_p,T_var>* ppd;

      T_p operator()(const T_var& x)const
      {
	if(x<=xl||x>=xr)
	  {
	    return std::numeric_limits<T_p>::max();
	  }
	return -(ppd->eval_log(x));
      }
  };

  template <typename T>
  T sqr(T x)
  {
    return x*x;
  }

  template <typename T>
  void shft3(T&a,T& b,T& c,T d)
  {
    mcmc_assign(a,b);
    mcmc_assign(b,c);
    mcmc_assign(c,d);
  }

  template <typename T>
  void shft(T& a,T& b,T& c,T d)
  {
    mcmc_assign(a,b);
    mcmc_assign(b,c);
    mcmc_assign(c,d);
  }
  //  template <typename T>
  //  void swap(T& ax,T& bx)
  //{
    //  swap(ax,bx);
    //    T temp;
    //mcmc_assign(temp,ax);
    //mcmc_assign(ax,bx);
    //mcmc_assign(bx,temp);
    //}

  template <typename T>
  T sign(const T& a,const T& b)
  {
    return b>=0?T(a>=0?T(a):T(-a)):T(a>=0?T(-a):T(a));
  }

  template <typename T>
  void mov3(T& a,T& b,T& c, T& d,T& e,T& f)
  {
    mcmc_assign(a,d);mcmc_assign(b,e);mcmc_assign(c,f);
  }
}

#endif
<commit_msg>	修改：     core/bas_util.hpp<commit_after>#ifndef MCMC_BAS_UTIL
#define MCMC_BAS_UTIL
#define OPT_HEADER
#include "mcmc_traits.hpp"
#include <algorithm>
#include <limits>
#include "distribution.hpp"
namespace mcmc_utilities
{
  template <typename T_p,typename T_var>
  struct dist_adapter
  {
      T_var xl,xr;
      const probability_density_1d<T_p,T_var>* ppd;

      T_p operator()(const T_var& x)const
      {
	if(x<=xl||x>=xr)
	  {
	    return std::numeric_limits<T_p>::max();
	  }
	return -(ppd->eval_log(x));
      }
  };

  template <typename T>
  T sqr(T x)
  {
    return x*x;
  }

  template <typename T>
  void shft3(T&a,T& b,T& c,T d)
  {
    mcmc_assign(a,b);
    mcmc_assign(b,c);
    mcmc_assign(c,d);
  }

  template <typename T>
  void shft(T& a,T& b,T& c,T d)
  {
    mcmc_assign(a,b);
    mcmc_assign(b,c);
    mcmc_assign(c,d);
  }

  template <typename T>
  T sign(const T& a,const T& b)
  {
    return b>=0?T(a>=0?T(a):T(-a)):T(a>=0?T(-a):T(a));
  }

  template <typename T>
  void mov3(T& a,T& b,T& c, T& d,T& e,T& f)
  {
    mcmc_assign(a,d);mcmc_assign(b,e);mcmc_assign(c,f);
  }
}

#endif
<|endoftext|>


<commit_before>#include <gtest/gtest.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include "httpfake.h"
#include "logging/logging.h"
#include "primary/reportqueue.h"
#include "primary/sotauptaneclient.h"
#include "storage/invstorage.h"
#include "test_utils.h"
#include "uptane/tuf.h"
#include "uptane/uptanerepository.h"
#include "uptane_test_common.h"
#include "utilities/utils.h"

namespace bpo = boost::program_options;

boost::filesystem::path build_dir;

/**
 * Check that aktualizr generates random ecu_serial for primary and all
 * secondaries.
 */
TEST(Uptane, RandomSerial) {
  RecordProperty("zephyr_key", "OTA-989,TST-155");
  // Make two configs, neither of which specify a primary serial.
  TemporaryDirectory temp_dir1, temp_dir2;
  Config conf_1("tests/config/basic.toml");
  conf_1.storage.path = temp_dir1.Path();
  Config conf_2("tests/config/basic.toml");
  conf_2.storage.path = temp_dir2.Path();

  conf_1.provision.primary_ecu_serial = "";
  conf_2.provision.primary_ecu_serial = "";

  UptaneTestCommon::addDefaultSecondary(conf_1, temp_dir1, "", "secondary_hardware", false);
  UptaneTestCommon::addDefaultSecondary(conf_2, temp_dir2, "", "secondary_hardware", false);

  // Initialize.
  auto storage_1 = INvStorage::newStorage(conf_1.storage);
  auto storage_2 = INvStorage::newStorage(conf_2.storage);
  auto http1 = std::make_shared<HttpFake>(temp_dir1.Path());
  auto http2 = std::make_shared<HttpFake>(temp_dir2.Path());

  auto uptane_client1 = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf_1, storage_1, http1);
  EXPECT_NO_THROW(uptane_client1->initialize());

  auto uptane_client2 = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf_2, storage_2, http2);
  EXPECT_NO_THROW(uptane_client2->initialize());

  // Verify that none of the serials match.
  EcuSerials ecu_serials_1;
  EcuSerials ecu_serials_2;
  EXPECT_TRUE(storage_1->loadEcuSerials(&ecu_serials_1));
  EXPECT_TRUE(storage_2->loadEcuSerials(&ecu_serials_2));
  EXPECT_EQ(ecu_serials_1.size(), 2);
  EXPECT_EQ(ecu_serials_2.size(), 2);
  EXPECT_FALSE(ecu_serials_1[0].first.ToString().empty());
  EXPECT_FALSE(ecu_serials_1[1].first.ToString().empty());
  EXPECT_FALSE(ecu_serials_2[0].first.ToString().empty());
  EXPECT_FALSE(ecu_serials_2[1].first.ToString().empty());
  EXPECT_NE(ecu_serials_1[0].first, ecu_serials_2[0].first);
  EXPECT_NE(ecu_serials_1[1].first, ecu_serials_2[1].first);
  EXPECT_NE(ecu_serials_1[0].first, ecu_serials_1[1].first);
  EXPECT_NE(ecu_serials_2[0].first, ecu_serials_2[1].first);
}

/**
 * Check that aktualizr saves random ecu_serial for primary and all secondaries.
 *
 * Test with a virtual secondary.
 */
TEST(Uptane, ReloadSerial) {
  RecordProperty("zephyr_key", "OTA-989,TST-156");
  TemporaryDirectory temp_dir;
  EcuSerials ecu_serials_1;
  EcuSerials ecu_serials_2;

  // Initialize. Should store new serials.
  {
    Config conf("tests/config/basic.toml");
    conf.storage.path = temp_dir.Path();
    conf.provision.primary_ecu_serial = "";

    auto storage = INvStorage::newStorage(conf.storage);
    auto http = std::make_shared<HttpFake>(temp_dir.Path());

    UptaneTestCommon::addDefaultSecondary(conf, temp_dir, "", "secondary_hardware", false);
    auto uptane_client = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf, storage, http);

    EXPECT_NO_THROW(uptane_client->initialize());
    EXPECT_TRUE(storage->loadEcuSerials(&ecu_serials_1));
    EXPECT_EQ(ecu_serials_1.size(), 2);
    EXPECT_FALSE(ecu_serials_1[0].first.ToString().empty());
    EXPECT_FALSE(ecu_serials_1[1].first.ToString().empty());
  }

  // Keep storage directory, but initialize new objects. Should load existing
  // serials.
  {
    Config conf("tests/config/basic.toml");
    conf.storage.path = temp_dir.Path();
    conf.provision.primary_ecu_serial = "";

    auto storage = INvStorage::newStorage(conf.storage);
    auto http = std::make_shared<HttpFake>(temp_dir.Path());
    UptaneTestCommon::addDefaultSecondary(conf, temp_dir, "", "secondary_hardware", false);
    auto uptane_client = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf, storage, http);

    EXPECT_NO_THROW(uptane_client->initialize());
    EXPECT_TRUE(storage->loadEcuSerials(&ecu_serials_2));
    EXPECT_EQ(ecu_serials_2.size(), 2);
    EXPECT_FALSE(ecu_serials_2[0].first.ToString().empty());
    EXPECT_FALSE(ecu_serials_2[1].first.ToString().empty());
  }

  // Verify that serials match across initializations.
  EXPECT_EQ(ecu_serials_1[0].first, ecu_serials_2[0].first);
  EXPECT_EQ(ecu_serials_1[1].first, ecu_serials_2[1].first);
  // Sanity check that primary and secondary serials do not match.
  EXPECT_NE(ecu_serials_1[0].first, ecu_serials_1[1].first);
  EXPECT_NE(ecu_serials_2[0].first, ecu_serials_2[1].first);
}

#ifndef __NO_MAIN__
int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  logger_set_threshold(boost::log::trivial::trace);

  if (argc != 2) {
    std::cerr << "Error: " << argv[0] << " requires the path to the build directory as an input argument.\n";
    return EXIT_FAILURE;
  }
  build_dir = argv[1];
  return RUN_ALL_TESTS();
}
#endif
<commit_msg>Tests: change some EXPECT_* to ASSERT_*<commit_after>#include <gtest/gtest.h>

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include <boost/filesystem.hpp>
#include <boost/program_options.hpp>

#include "httpfake.h"
#include "logging/logging.h"
#include "primary/reportqueue.h"
#include "primary/sotauptaneclient.h"
#include "storage/invstorage.h"
#include "test_utils.h"
#include "uptane/tuf.h"
#include "uptane/uptanerepository.h"
#include "uptane_test_common.h"
#include "utilities/utils.h"

namespace bpo = boost::program_options;

boost::filesystem::path build_dir;

/**
 * Check that aktualizr generates random ecu_serial for primary and all
 * secondaries.
 */
TEST(Uptane, RandomSerial) {
  RecordProperty("zephyr_key", "OTA-989,TST-155");
  // Make two configs, neither of which specify a primary serial.
  TemporaryDirectory temp_dir1, temp_dir2;
  Config conf_1("tests/config/basic.toml");
  conf_1.storage.path = temp_dir1.Path();
  Config conf_2("tests/config/basic.toml");
  conf_2.storage.path = temp_dir2.Path();

  conf_1.provision.primary_ecu_serial = "";
  conf_2.provision.primary_ecu_serial = "";

  UptaneTestCommon::addDefaultSecondary(conf_1, temp_dir1, "", "secondary_hardware", false);
  UptaneTestCommon::addDefaultSecondary(conf_2, temp_dir2, "", "secondary_hardware", false);

  // Initialize.
  auto storage_1 = INvStorage::newStorage(conf_1.storage);
  auto storage_2 = INvStorage::newStorage(conf_2.storage);
  auto http1 = std::make_shared<HttpFake>(temp_dir1.Path());
  auto http2 = std::make_shared<HttpFake>(temp_dir2.Path());

  auto uptane_client1 = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf_1, storage_1, http1);
  ASSERT_NO_THROW(uptane_client1->initialize());

  auto uptane_client2 = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf_2, storage_2, http2);
  ASSERT_NO_THROW(uptane_client2->initialize());

  // Verify that none of the serials match.
  EcuSerials ecu_serials_1;
  EcuSerials ecu_serials_2;
  ASSERT_TRUE(storage_1->loadEcuSerials(&ecu_serials_1));
  ASSERT_TRUE(storage_2->loadEcuSerials(&ecu_serials_2));
  ASSERT_EQ(ecu_serials_1.size(), 2);
  ASSERT_EQ(ecu_serials_2.size(), 2);
  EXPECT_FALSE(ecu_serials_1[0].first.ToString().empty());
  EXPECT_FALSE(ecu_serials_1[1].first.ToString().empty());
  EXPECT_FALSE(ecu_serials_2[0].first.ToString().empty());
  EXPECT_FALSE(ecu_serials_2[1].first.ToString().empty());
  EXPECT_NE(ecu_serials_1[0].first, ecu_serials_2[0].first);
  EXPECT_NE(ecu_serials_1[1].first, ecu_serials_2[1].first);
  EXPECT_NE(ecu_serials_1[0].first, ecu_serials_1[1].first);
  EXPECT_NE(ecu_serials_2[0].first, ecu_serials_2[1].first);
}

/**
 * Check that aktualizr saves random ecu_serial for primary and all secondaries.
 *
 * Test with a virtual secondary.
 */
TEST(Uptane, ReloadSerial) {
  RecordProperty("zephyr_key", "OTA-989,TST-156");
  TemporaryDirectory temp_dir;
  EcuSerials ecu_serials_1;
  EcuSerials ecu_serials_2;

  // Initialize. Should store new serials.
  {
    Config conf("tests/config/basic.toml");
    conf.storage.path = temp_dir.Path();
    conf.provision.primary_ecu_serial = "";

    auto storage = INvStorage::newStorage(conf.storage);
    auto http = std::make_shared<HttpFake>(temp_dir.Path());

    UptaneTestCommon::addDefaultSecondary(conf, temp_dir, "", "secondary_hardware", false);
    auto uptane_client = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf, storage, http);

    ASSERT_NO_THROW(uptane_client->initialize());
    ASSERT_TRUE(storage->loadEcuSerials(&ecu_serials_1));
    ASSERT_EQ(ecu_serials_1.size(), 2);
    EXPECT_FALSE(ecu_serials_1[0].first.ToString().empty());
    EXPECT_FALSE(ecu_serials_1[1].first.ToString().empty());
  }

  // Keep storage directory, but initialize new objects. Should load existing
  // serials.
  {
    Config conf("tests/config/basic.toml");
    conf.storage.path = temp_dir.Path();
    conf.provision.primary_ecu_serial = "";

    auto storage = INvStorage::newStorage(conf.storage);
    auto http = std::make_shared<HttpFake>(temp_dir.Path());
    UptaneTestCommon::addDefaultSecondary(conf, temp_dir, "", "secondary_hardware", false);
    auto uptane_client = std_::make_unique<UptaneTestCommon::TestUptaneClient>(conf, storage, http);

    ASSERT_NO_THROW(uptane_client->initialize());
    ASSERT_TRUE(storage->loadEcuSerials(&ecu_serials_2));
    ASSERT_EQ(ecu_serials_2.size(), 2);
    EXPECT_FALSE(ecu_serials_2[0].first.ToString().empty());
    EXPECT_FALSE(ecu_serials_2[1].first.ToString().empty());
  }

  // Verify that serials match across initializations.
  EXPECT_EQ(ecu_serials_1[0].first, ecu_serials_2[0].first);
  EXPECT_EQ(ecu_serials_1[1].first, ecu_serials_2[1].first);
  // Sanity check that primary and secondary serials do not match.
  EXPECT_NE(ecu_serials_1[0].first, ecu_serials_1[1].first);
  EXPECT_NE(ecu_serials_2[0].first, ecu_serials_2[1].first);
}

#ifndef __NO_MAIN__
int main(int argc, char** argv) {
  ::testing::InitGoogleTest(&argc, argv);
  logger_set_threshold(boost::log::trivial::trace);

  if (argc != 2) {
    std::cerr << "Error: " << argv[0] << " requires the path to the build directory as an input argument.\n";
    return EXIT_FAILURE;
  }
  build_dir = argv[1];
  return RUN_ALL_TESTS();
}
#endif
<|endoftext|>


<commit_before>#include "configcontroller.h"
#include "../network/networkmanager.h"
#include "../settings.h"
#include "../log/logger.h"

#include "../webrequester.h"
#include "../network/requests/getconfigrequest.h"
#include "../timing/periodictiming.h"
#include "../client.h"
#include "../timing/timer.h"

#include <QPointer>

LOGGER(ConfigController);

class ConfigController::Private : public QObject
{
    Q_OBJECT

public:
    Private(ConfigController *q)
    : q(q)
    {
        connect(&timer, SIGNAL(timeout()), q, SLOT(update()));
        connect(&timer, SIGNAL(timingChanged()), this, SLOT(onTimingChanged()));
        connect(&requester, SIGNAL(statusChanged(WebRequester::Status)), q, SIGNAL(statusChanged()));
        connect(&requester, SIGNAL(finished()), this, SLOT(onFinished()));
        connect(&requester, SIGNAL(error()), this, SLOT(onError()));

        request.setPath("/supervisor/api/v1/configuration/1/");
        requester.setRequest(&request);
    }

    ConfigController *q;

    // Properties
    QPointer<NetworkManager> networkManager;
    QPointer<Settings> settings;

    WebRequester requester;
    GetConfigRequest request;
    GetConfigResponse *response;

    Timer timer;

    // Functions
public slots:
    void updateTimer();
    void onFinished();
    void onError();
    void onTimingChanged();
};

void ConfigController::Private::updateTimer()
{
    // Set the new url
    QString newUrl = QString("https://%1").arg(settings->config()->configAddress());

    if (requester.url() != newUrl)
    {
        LOG_DEBUG(QString("Config url set to %1").arg(newUrl));
        requester.setUrl(newUrl);
    }

    TimingPtr timing = settings->config()->configTiming();

    if (timing.isNull())
    {
        timing = TimingPtr(new PeriodicTiming(10*60*1000, QDateTime(), QDateTime(), 30*1000));
    }

    timer.setTiming(timing);
    timer.start();
}

void ConfigController::Private::onFinished()
{
    emit q->finished();
}

void ConfigController::Private::onError()
{
    LOG_ERROR(QString("Could not get config from server, trying again later"));
}

void ConfigController::Private::onTimingChanged()
{
    LOG_DEBUG(QString("Config schedule changed, type: %1, nextRun in %2 seconds.")
              .arg(timer.timing()->type())
              .arg(timer.timing()->timeLeft() / 1000));
}

ConfigController::ConfigController(QObject *parent)
: Controller(parent)
, d(new Private(this))
{
}

ConfigController::~ConfigController()
{
    delete d;
}

void ConfigController::update()
{
    d->requester.start();
}

bool ConfigController::init(NetworkManager *networkManager, Settings *settings)
{
    d->networkManager = networkManager;
    d->settings = settings;

    // TODO: This is an evil hack
    d->response = settings->config();
    d->requester.setResponse(d->response);
    connect(d->response, SIGNAL(responseChanged()), d, SLOT(updateTimer()));

    // sets the url into the requester and starts the timer
    d->updateTimer();

    // get new config now
    update();

    return true;
}

Controller::Status ConfigController::status() const
{
    return (Status)d->requester.status();
}

QString ConfigController::errorString() const
{
    return d->requester.errorString();
}

#include "configcontroller.moc"
<commit_msg>Fixed ConfigController: A timing with invalid nextRun is also invalid.<commit_after>#include "configcontroller.h"
#include "../network/networkmanager.h"
#include "../settings.h"
#include "../log/logger.h"

#include "../webrequester.h"
#include "../network/requests/getconfigrequest.h"
#include "../timing/periodictiming.h"
#include "../client.h"
#include "../timing/timer.h"

#include <QPointer>

LOGGER(ConfigController);

class ConfigController::Private : public QObject
{
    Q_OBJECT

public:
    Private(ConfigController *q)
    : q(q)
    {
        connect(&timer, SIGNAL(timeout()), q, SLOT(update()));
        connect(&timer, SIGNAL(timingChanged()), this, SLOT(onTimingChanged()));
        connect(&requester, SIGNAL(statusChanged(WebRequester::Status)), q, SIGNAL(statusChanged()));
        connect(&requester, SIGNAL(finished()), this, SLOT(onFinished()));
        connect(&requester, SIGNAL(error()), this, SLOT(onError()));

        request.setPath("/supervisor/api/v1/configuration/1/");
        requester.setRequest(&request);
    }

    ConfigController *q;

    // Properties
    QPointer<NetworkManager> networkManager;
    QPointer<Settings> settings;

    WebRequester requester;
    GetConfigRequest request;
    GetConfigResponse *response;

    Timer timer;

    // Functions
public slots:
    void updateTimer();
    void onFinished();
    void onError();
    void onTimingChanged();
};

void ConfigController::Private::updateTimer()
{
    // Set the new url
    QString newUrl = QString("https://%1").arg(settings->config()->configAddress());

    if (requester.url() != newUrl)
    {
        LOG_DEBUG(QString("Config url set to %1").arg(newUrl));
        requester.setUrl(newUrl);
    }

    TimingPtr timing = settings->config()->configTiming();

    if (timing.isNull() || !timing->nextRun().isValid())
    {
        timing = TimingPtr(new PeriodicTiming(10*60*1000, QDateTime(), QDateTime(), 30*1000));
    }

    timer.setTiming(timing);
    timer.start();
}

void ConfigController::Private::onFinished()
{
    emit q->finished();
}

void ConfigController::Private::onError()
{
    LOG_ERROR(QString("Could not get config from server, trying again later"));
}

void ConfigController::Private::onTimingChanged()
{
    LOG_DEBUG(QString("Config schedule changed, type: %1, nextRun in %2 seconds.")
              .arg(timer.timing()->type())
              .arg(timer.timing()->timeLeft() / 1000));
}

ConfigController::ConfigController(QObject *parent)
: Controller(parent)
, d(new Private(this))
{
}

ConfigController::~ConfigController()
{
    delete d;
}

void ConfigController::update()
{
    d->requester.start();
}

bool ConfigController::init(NetworkManager *networkManager, Settings *settings)
{
    d->networkManager = networkManager;
    d->settings = settings;

    // TODO: This is an evil hack
    d->response = settings->config();
    d->requester.setResponse(d->response);
    connect(d->response, SIGNAL(responseChanged()), d, SLOT(updateTimer()));

    // sets the url into the requester and starts the timer
    d->updateTimer();

    // get new config now
    update();

    return true;
}

Controller::Status ConfigController::status() const
{
    return (Status)d->requester.status();
}

QString ConfigController::errorString() const
{
    return d->requester.errorString();
}

#include "configcontroller.moc"
<|endoftext|>