<commit_before>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <cassert>

#include <iostream>
#include <memory>
#include <ostream>

#include <boost/algorithm/string.hpp>

#include <config/CoviseConfig.h>

#include <cover/coVRPluginSupport.h>
#include <cover/VRViewer.h>

#include <OpenVRUI/coCheckboxGroup.h>
#include <OpenVRUI/coCheckboxMenuItem.h>
#include <OpenVRUI/coRowMenu.h>
#include <OpenVRUI/coSubMenuItem.h>

#include "drawable.h"
#include "state.h"
#include "visionaray_plugin.h"

namespace visionaray { namespace cover {

//-------------------------------------------------------------------------------------------------
// Private implementation
//

struct Visionaray::impl : vrui::coMenuListener
{

    using check_box     = std::unique_ptr<vrui::coCheckboxMenuItem>;
    using menu          = std::unique_ptr<vrui::coMenu>;
    using radio_button  = std::unique_ptr<vrui::coCheckboxMenuItem>;
    using radio_group   = std::unique_ptr<vrui::coCheckboxGroup>;
    using sub_menu      = std::unique_ptr<vrui::coSubMenuItem>;

    impl()
        : drawable_ptr(new drawable)
    {
        init_state_from_config();
        drawable_ptr->update_state(state, dev_state);
    }

    osg::ref_ptr<osg::Geode>        geode;
    osg::ref_ptr<drawable>          drawable_ptr;

    struct
    {
        menu                        main_menu;
        menu                        algo_menu;
        menu                        dev_menu;
        sub_menu                    main_menu_entry;
        sub_menu                    algo_menu_entry;
        sub_menu                    dev_menu_entry;

        // main menu
        check_box                   toggle_update_mode;

        // algo menu
        radio_group                 algo_group;
        radio_button                simple_button;
        radio_button                whitted_button;
        radio_button                pathtracing_button;

        // dev menu
        check_box                   toggle_bvh_display;
        check_box                   toggle_normal_display;
        check_box                   toggle_tex_coord_display;
    } ui;

    std::shared_ptr<render_state>   state;
    std::shared_ptr<debug_state>    dev_state;

    void init_state_from_config();
    void init_ui();
    void menuEvent(vrui::coMenuItem* item);

};

//-------------------------------------------------------------------------------------------------
// Read state from COVISE config
//

void Visionaray::impl::init_state_from_config()
{

    //
    //
    // <Visionaray>
    //     <DataVariance value="static"  />      <!-- "static" | "dynamic" -->
    //     <Algorithm    value="simple"  />      <!-- "simple" | "whitted" -->
    //     <CPUScheduler numThreads="16" />      <!-- numThreads:Integer   -->
    // </Visioaray>
    //
    //

    state     = std::make_shared<render_state>();
    dev_state = std::make_shared<debug_state>();

    // Read config

    using boost::algorithm::to_lower;

    auto algo_str       = covise::coCoviseConfig::getEntry("COVER.Plugin.Visionaray.Algorithm");
    auto data_var_str   = covise::coCoviseConfig::getEntry("COVER.Plugin.Visionaray.DataVariance");
    auto num_threads    = covise::coCoviseConfig::getInt("numThreads", "COVER.Plugin.Visionaray.CPUScheduler", 0);

    to_lower(algo_str);
    to_lower(data_var_str);

    // Update state

    if (algo_str == "whitted")
    {
        state->algo = Whitted;
    }
    else if (algo_str == "pathtracing")
    {
        state->algo = Pathtracing;
    }
    else
    {
        state->algo = Simple;
    }

    state->data_var     = data_var_str == "dynamic" ? Dynamic : Static;
    state->num_threads  = num_threads;
}

void Visionaray::impl::init_ui()
{
    using namespace vrui;

    ui.main_menu_entry.reset(new coSubMenuItem("Visionaray..."));
    opencover::cover->getMenu()->add(ui.main_menu_entry.get());

    // main menu

    ui.main_menu.reset(new coRowMenu("Visionaray", opencover::cover->getMenu()));
    ui.main_menu_entry->setMenu(ui.main_menu.get());

    ui.toggle_update_mode.reset(new coCheckboxMenuItem("Update scene per frame", state->data_var == Dynamic));
    ui.toggle_update_mode->setMenuListener(this);
    ui.main_menu->add(ui.toggle_update_mode.get());

    // algorithm submenu

    ui.algo_menu_entry.reset(new coSubMenuItem("Rendering algorithm..."));
    ui.main_menu->add(ui.algo_menu_entry.get());

    ui.algo_menu.reset(new coRowMenu("Rendering algorithm", ui.main_menu.get()));
    ui.algo_menu_entry->setMenu(ui.algo_menu.get());

    ui.algo_group.reset(new coCheckboxGroup( /* allow empty selection: */ false ));

    ui.simple_button.reset(new coCheckboxMenuItem("Simple", state->algo == Simple, ui.algo_group.get()));
    ui.simple_button->setMenuListener(this);
    ui.algo_menu->add(ui.simple_button.get());

    ui.whitted_button.reset(new coCheckboxMenuItem("Whitted", state->algo == Whitted, ui.algo_group.get()));
    ui.whitted_button->setMenuListener(this);
    ui.algo_menu->add(ui.whitted_button.get());

    ui.pathtracing_button.reset(new coCheckboxMenuItem("Pathtracing", state->algo == Pathtracing, ui.algo_group.get()));
    ui.pathtracing_button->setMenuListener(this);
    ui.algo_menu->add(ui.pathtracing_button.get());

    // dev submenu at the bottom!

    if (dev_state->debug_mode)
    {
        ui.dev_menu_entry.reset(new coSubMenuItem("Developer..."));
        ui.main_menu->add(ui.dev_menu_entry.get());

        ui.dev_menu.reset(new coRowMenu("Developer", ui.main_menu.get()));
        ui.dev_menu_entry->setMenu(ui.dev_menu.get());

        ui.toggle_bvh_display.reset(new coCheckboxMenuItem("Show BVH outlines", false));
        ui.toggle_bvh_display->setMenuListener(this);
        ui.dev_menu->add(ui.toggle_bvh_display.get());

        ui.toggle_normal_display.reset(new coCheckboxMenuItem("Show surface normals", false));
        ui.toggle_normal_display->setMenuListener(this);
        ui.dev_menu->add(ui.toggle_normal_display.get());

        ui.toggle_tex_coord_display.reset(new coCheckboxMenuItem("Show texture coordinates", false));
        ui.toggle_tex_coord_display->setMenuListener(this);
        ui.dev_menu->add(ui.toggle_tex_coord_display.get());
    }
}

void Visionaray::impl::menuEvent(vrui::coMenuItem* item)
{
    // main menu
    if (item == ui.toggle_update_mode.get())
    {
        state->data_var = ui.toggle_update_mode->getState() ? Dynamic : Static;
    }

    // algorithm submenu
    if (item == ui.simple_button.get())
    {
        state->algo = Simple;
    }
    else if (item == ui.whitted_button.get())
    {
        state->algo = Whitted;
    }
    else if (item == ui.pathtracing_button.get())
    {
        state->algo = Pathtracing;
    }

    // dev submenu
    if (item == ui.toggle_bvh_display.get())
    {
        dev_state->show_bvh = ui.toggle_bvh_display->getState();
    }

    if (item == ui.toggle_normal_display.get())
    {
        dev_state->show_normals = ui.toggle_normal_display->getState();
    }

    if (item == ui.toggle_tex_coord_display.get())
    {
        dev_state->show_tex_coords = ui.toggle_tex_coord_display->getState();
    }
}

//-------------------------------------------------------------------------------------------------
// Visionaray plugin
//

Visionaray::Visionaray()
    : impl_(new impl)
{
}

Visionaray::~Visionaray()
{
    impl_->geode->removeDrawable(impl_->drawable_ptr);
    opencover::cover->getScene()->removeChild(impl_->geode);
}

bool Visionaray::init()
{
    using namespace osg;

    opencover::VRViewer::instance()->culling(false);

    std::cout << "Init Visionaray Plugin!!" << std::endl;

    impl_->init_ui();

    impl_->geode = new osg::Geode;
    impl_->geode->setName("Visionaray");
    impl_->geode->addDrawable(impl_->drawable_ptr);

    opencover::cover->getScene()->addChild(impl_->geode);
    opencover::cover->getObjectsRoot()->setNodeMask
    (
        opencover::cover->getObjectsRoot()->getNodeMask()
     & ~opencover::VRViewer::instance()->getCullMask()
    );

    return true;
}

void Visionaray::preFrame()
{
}

void Visionaray::expandBoundingSphere(osg::BoundingSphere &bs)
{
    impl_->drawable_ptr->expandBoundingSphere(bs);
}

}} // namespace visionaray::cover

COVERPLUGIN(visionaray::cover::Visionaray)
<commit_msg>Reset OpenCOVER's cull mask in plugin d'tor<commit_after>// This file is distributed under the MIT license.
// See the LICENSE file for details.

#include <cassert>

#include <iostream>
#include <memory>
#include <ostream>

#include <boost/algorithm/string.hpp>

#include <config/CoviseConfig.h>

#include <cover/coVRPluginSupport.h>
#include <cover/VRViewer.h>

#include <OpenVRUI/coCheckboxGroup.h>
#include <OpenVRUI/coCheckboxMenuItem.h>
#include <OpenVRUI/coRowMenu.h>
#include <OpenVRUI/coSubMenuItem.h>

#include "drawable.h"
#include "state.h"
#include "visionaray_plugin.h"

namespace visionaray { namespace cover {

//-------------------------------------------------------------------------------------------------
// Private implementation
//

struct Visionaray::impl : vrui::coMenuListener
{

    using check_box     = std::unique_ptr<vrui::coCheckboxMenuItem>;
    using menu          = std::unique_ptr<vrui::coMenu>;
    using radio_button  = std::unique_ptr<vrui::coCheckboxMenuItem>;
    using radio_group   = std::unique_ptr<vrui::coCheckboxGroup>;
    using sub_menu      = std::unique_ptr<vrui::coSubMenuItem>;

    impl()
        : drawable_ptr(new drawable)
    {
        init_state_from_config();
        drawable_ptr->update_state(state, dev_state);
    }

    osg::Node::NodeMask             objroot_node_mask;
    osg::ref_ptr<osg::Geode>        geode;
    osg::ref_ptr<drawable>          drawable_ptr;

    struct
    {
        menu                        main_menu;
        menu                        algo_menu;
        menu                        dev_menu;
        sub_menu                    main_menu_entry;
        sub_menu                    algo_menu_entry;
        sub_menu                    dev_menu_entry;

        // main menu
        check_box                   toggle_update_mode;

        // algo menu
        radio_group                 algo_group;
        radio_button                simple_button;
        radio_button                whitted_button;
        radio_button                pathtracing_button;

        // dev menu
        check_box                   toggle_bvh_display;
        check_box                   toggle_normal_display;
        check_box                   toggle_tex_coord_display;
    } ui;

    std::shared_ptr<render_state>   state;
    std::shared_ptr<debug_state>    dev_state;

    void init_state_from_config();
    void init_ui();
    void menuEvent(vrui::coMenuItem* item);

};

//-------------------------------------------------------------------------------------------------
// Read state from COVISE config
//

void Visionaray::impl::init_state_from_config()
{

    //
    //
    // <Visionaray>
    //     <DataVariance value="static"  />      <!-- "static" | "dynamic" -->
    //     <Algorithm    value="simple"  />      <!-- "simple" | "whitted" -->
    //     <CPUScheduler numThreads="16" />      <!-- numThreads:Integer   -->
    // </Visioaray>
    //
    //

    state     = std::make_shared<render_state>();
    dev_state = std::make_shared<debug_state>();

    // Read config

    using boost::algorithm::to_lower;

    auto algo_str       = covise::coCoviseConfig::getEntry("COVER.Plugin.Visionaray.Algorithm");
    auto data_var_str   = covise::coCoviseConfig::getEntry("COVER.Plugin.Visionaray.DataVariance");
    auto num_threads    = covise::coCoviseConfig::getInt("numThreads", "COVER.Plugin.Visionaray.CPUScheduler", 0);

    to_lower(algo_str);
    to_lower(data_var_str);

    // Update state

    if (algo_str == "whitted")
    {
        state->algo = Whitted;
    }
    else if (algo_str == "pathtracing")
    {
        state->algo = Pathtracing;
    }
    else
    {
        state->algo = Simple;
    }

    state->data_var     = data_var_str == "dynamic" ? Dynamic : Static;
    state->num_threads  = num_threads;
}

void Visionaray::impl::init_ui()
{
    using namespace vrui;

    ui.main_menu_entry.reset(new coSubMenuItem("Visionaray..."));
    opencover::cover->getMenu()->add(ui.main_menu_entry.get());

    // main menu

    ui.main_menu.reset(new coRowMenu("Visionaray", opencover::cover->getMenu()));
    ui.main_menu_entry->setMenu(ui.main_menu.get());

    ui.toggle_update_mode.reset(new coCheckboxMenuItem("Update scene per frame", state->data_var == Dynamic));
    ui.toggle_update_mode->setMenuListener(this);
    ui.main_menu->add(ui.toggle_update_mode.get());

    // algorithm submenu

    ui.algo_menu_entry.reset(new coSubMenuItem("Rendering algorithm..."));
    ui.main_menu->add(ui.algo_menu_entry.get());

    ui.algo_menu.reset(new coRowMenu("Rendering algorithm", ui.main_menu.get()));
    ui.algo_menu_entry->setMenu(ui.algo_menu.get());

    ui.algo_group.reset(new coCheckboxGroup( /* allow empty selection: */ false ));

    ui.simple_button.reset(new coCheckboxMenuItem("Simple", state->algo == Simple, ui.algo_group.get()));
    ui.simple_button->setMenuListener(this);
    ui.algo_menu->add(ui.simple_button.get());

    ui.whitted_button.reset(new coCheckboxMenuItem("Whitted", state->algo == Whitted, ui.algo_group.get()));
    ui.whitted_button->setMenuListener(this);
    ui.algo_menu->add(ui.whitted_button.get());

    ui.pathtracing_button.reset(new coCheckboxMenuItem("Pathtracing", state->algo == Pathtracing, ui.algo_group.get()));
    ui.pathtracing_button->setMenuListener(this);
    ui.algo_menu->add(ui.pathtracing_button.get());

    // dev submenu at the bottom!

    if (dev_state->debug_mode)
    {
        ui.dev_menu_entry.reset(new coSubMenuItem("Developer..."));
        ui.main_menu->add(ui.dev_menu_entry.get());

        ui.dev_menu.reset(new coRowMenu("Developer", ui.main_menu.get()));
        ui.dev_menu_entry->setMenu(ui.dev_menu.get());

        ui.toggle_bvh_display.reset(new coCheckboxMenuItem("Show BVH outlines", false));
        ui.toggle_bvh_display->setMenuListener(this);
        ui.dev_menu->add(ui.toggle_bvh_display.get());

        ui.toggle_normal_display.reset(new coCheckboxMenuItem("Show surface normals", false));
        ui.toggle_normal_display->setMenuListener(this);
        ui.dev_menu->add(ui.toggle_normal_display.get());

        ui.toggle_tex_coord_display.reset(new coCheckboxMenuItem("Show texture coordinates", false));
        ui.toggle_tex_coord_display->setMenuListener(this);
        ui.dev_menu->add(ui.toggle_tex_coord_display.get());
    }
}

void Visionaray::impl::menuEvent(vrui::coMenuItem* item)
{
    // main menu
    if (item == ui.toggle_update_mode.get())
    {
        state->data_var = ui.toggle_update_mode->getState() ? Dynamic : Static;
    }

    // algorithm submenu
    if (item == ui.simple_button.get())
    {
        state->algo = Simple;
    }
    else if (item == ui.whitted_button.get())
    {
        state->algo = Whitted;
    }
    else if (item == ui.pathtracing_button.get())
    {
        state->algo = Pathtracing;
    }

    // dev submenu
    if (item == ui.toggle_bvh_display.get())
    {
        dev_state->show_bvh = ui.toggle_bvh_display->getState();
    }

    if (item == ui.toggle_normal_display.get())
    {
        dev_state->show_normals = ui.toggle_normal_display->getState();
    }

    if (item == ui.toggle_tex_coord_display.get())
    {
        dev_state->show_tex_coords = ui.toggle_tex_coord_display->getState();
    }
}

//-------------------------------------------------------------------------------------------------
// Visionaray plugin
//

Visionaray::Visionaray()
    : impl_(new impl)
{
}

Visionaray::~Visionaray()
{
    opencover::cover->getObjectsRoot()->setNodeMask(impl_->objroot_node_mask);
    impl_->geode->removeDrawable(impl_->drawable_ptr);
    opencover::cover->getScene()->removeChild(impl_->geode);
}

bool Visionaray::init()
{
    using namespace osg;

    opencover::VRViewer::instance()->culling(false);

    std::cout << "Init Visionaray Plugin!!" << std::endl;

    impl_->init_ui();

    impl_->geode = new osg::Geode;
    impl_->geode->setName("Visionaray");
    impl_->geode->addDrawable(impl_->drawable_ptr);

    impl_->objroot_node_mask = opencover::cover->getObjectsRoot()->getNodeMask();

    opencover::cover->getScene()->addChild(impl_->geode);
    opencover::cover->getObjectsRoot()->setNodeMask
    (
        opencover::cover->getObjectsRoot()->getNodeMask()
     & ~opencover::VRViewer::instance()->getCullMask()
    );

    return true;
}

void Visionaray::preFrame()
{
}

void Visionaray::expandBoundingSphere(osg::BoundingSphere &bs)
{
    impl_->drawable_ptr->expandBoundingSphere(bs);
}

}} // namespace visionaray::cover

COVERPLUGIN(visionaray::cover::Visionaray)
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/perv/p10_core_checkstop_handler.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2021                        */
/* [+] 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 p10_core_checkstop_handler.C
/// @brief Depending on input flag, trun local xstops into system xstops.
///
/// *HWP HW Maintainer: Manish Chowdhary  <manichow@in.ibm.com>
/// *HWP FW Maintainer: Dan Crowell <dcrowell@us.ibm.com>
/// *HWP Consumed by: HB
///

#include "p10_core_checkstop_handler.H"
#include "p10_scom_c_b.H"
#include "p10_scom_c_d.H"

using namespace scomt;
using namespace scomt::c;

fapi2::ReturnCode p10_core_checkstop_handler(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target_core,
    bool i_override_restore)
{
    FAPI_INF("Entering ...");

    fapi2::buffer<uint64_t> l_action0;
    fapi2::buffer<uint64_t> l_action1;
    uint8_t l_core_unit_pos = 0;
    uint8_t l_dead_core = 0;

    FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_DEAD_CORE_MODE,
                            i_target_core,
                            l_dead_core));

    FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                   i_target_core,
                   l_core_unit_pos);

    if ( l_dead_core )
    {
        FAPI_IMP("p10_core_checkstop_handler: Skipping Phyp Marked dead core %d ", l_core_unit_pos);
        goto fapi_try_exit;
    }

    //if true, save off the original action, and turn local xstops into system xstops.
    if(i_override_restore == CORE_XSTOP_HNDLR__SAVE_AND_ESCALATE)
    {

        // Getting ACTION0
        FAPI_TRY(GET_EC_PC_FIR_CORE_ACTION0(i_target_core, l_action0));

        // Getting ACTION1
        FAPI_TRY(GET_EC_PC_FIR_CORE_ACTION1(i_target_core, l_action1));

        // We want to save the original actions into an attribute for a save-restore
        FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION0, i_target_core, l_action0),
                 "Error from FAPI_ATTR_SET (ATTR_ORIG_FIR_SETTINGS_ACTION0)");

        FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION1, i_target_core, l_action1),
                 "Error from FAPI_ATTR_SET (ATTR_ORIG_FIR_SETTINGS_ACTION1)");

        // For every bit, turn every local xstop (0b11) into system xstops (0b00)
        uint64_t l_local_xstop = l_action0 & l_action1; //gets bits that are both set to 1
        l_action0 &= ~l_local_xstop;
        l_action1 &= ~l_local_xstop;
    }
    else
    {
        // We want to pull out the original actions, and restore them
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION0, i_target_core, l_action0),
                 "Error from FAPI_ATTR_GET (ATTR_ORIG_FIR_SETTINGS_ACTION0)");

        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION1, i_target_core, l_action1),
                 "Error from FAPI_ATTR_GET (ATTR_ORIG_FIR_SETTINGS_ACTION1)");
    }

    // Save off the current values of actions into the register
    FAPI_TRY(PREP_EC_PC_FIR_CORE_ACTION0(i_target_core));
    FAPI_TRY(PUT_EC_PC_FIR_CORE_ACTION0(i_target_core, l_action0));
    FAPI_TRY(PREP_EC_PC_FIR_CORE_ACTION1(i_target_core));
    FAPI_TRY(PUT_EC_PC_FIR_CORE_ACTION1(i_target_core, l_action1));

    FAPI_INF("Exiting ...");

fapi_try_exit:
    return fapi2::current_err;
}
<commit_msg>p10_tod_setup - Mask PC TimeBase Facility FIR.<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p10/procedures/hwp/perv/p10_core_checkstop_handler.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,2022                        */
/* [+] 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 p10_core_checkstop_handler.C
/// @brief Depending on input flag, trun local xstops into system xstops.
///
/// *HWP HW Maintainer: Manish Chowdhary  <manichow@in.ibm.com>
/// *HWP FW Maintainer: Dan Crowell <dcrowell@us.ibm.com>
/// *HWP Consumed by: HB
///

#include "p10_core_checkstop_handler.H"
#include "p10_scom_c_b.H"
#include "p10_scom_c_d.H"
#include <p10_scom_c.H>

using namespace scomt;
using namespace scomt::c;

fapi2::ReturnCode p10_core_checkstop_handler(
    const fapi2::Target<fapi2::TARGET_TYPE_CORE>& i_target_core,
    bool i_override_restore)
{
    FAPI_INF("Entering ...");

    fapi2::buffer<uint64_t> l_action0;
    fapi2::buffer<uint64_t> l_action1;
    fapi2::buffer<uint64_t> l_data;

    uint8_t l_core_unit_pos = 0;
    uint8_t l_dead_core = 0;

    FAPI_TRY(FAPI_ATTR_GET( fapi2::ATTR_DEAD_CORE_MODE,
                            i_target_core,
                            l_dead_core));

    FAPI_ATTR_GET( fapi2::ATTR_CHIP_UNIT_POS,
                   i_target_core,
                   l_core_unit_pos);

    if ( l_dead_core )
    {
        FAPI_IMP("p10_core_checkstop_handler: Skipping Phyp Marked dead core %d ", l_core_unit_pos);
        goto fapi_try_exit;
    }

    //if true, save off the original action, and turn local xstops into system xstops.
    if(i_override_restore == CORE_XSTOP_HNDLR__SAVE_AND_ESCALATE)
    {

        // Getting ACTION0
        FAPI_TRY(GET_EC_PC_FIR_CORE_ACTION0(i_target_core, l_action0));

        // Getting ACTION1
        FAPI_TRY(GET_EC_PC_FIR_CORE_ACTION1(i_target_core, l_action1));

        // We want to save the original actions into an attribute for a save-restore
        FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION0, i_target_core, l_action0),
                 "Error from FAPI_ATTR_SET (ATTR_ORIG_FIR_SETTINGS_ACTION0)");

        FAPI_TRY(FAPI_ATTR_SET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION1, i_target_core, l_action1),
                 "Error from FAPI_ATTR_SET (ATTR_ORIG_FIR_SETTINGS_ACTION1)");

        // For every bit, turn every local xstop (0b11) into system xstops (0b00)
        uint64_t l_local_xstop = l_action0 & l_action1; //gets bits that are both set to 1
        l_action0 &= ~l_local_xstop;
        l_action1 &= ~l_local_xstop;

        // Mask PC TimeBase Facility for TOD setup in istep 18.
        // It's done here because security doesn't allow SCOMs to FIR reg in istep 18.
        FAPI_TRY(PREP_EC_PC_FIR_CORE_FIRMASK_WO_OR(i_target_core));
        l_data.flush<0>();
        SET_EC_PC_FIR_CORE_FIRMASK_MASK_PC_TFAC_XSTOP_ERROR(l_data);
        FAPI_TRY(PUT_EC_PC_FIR_CORE_FIRMASK_WO_OR(i_target_core, l_data));
    }
    else
    {
        // We want to pull out the original actions, and restore them
        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION0, i_target_core, l_action0),
                 "Error from FAPI_ATTR_GET (ATTR_ORIG_FIR_SETTINGS_ACTION0)");

        FAPI_TRY(FAPI_ATTR_GET(fapi2::ATTR_ORIG_FIR_SETTINGS_ACTION1, i_target_core, l_action1),
                 "Error from FAPI_ATTR_GET (ATTR_ORIG_FIR_SETTINGS_ACTION1)");

        // Clear error and unmask PC TimeBase Facility
        FAPI_TRY(PREP_EC_PC_FIR_CORE_WO_AND(i_target_core));
        l_data.flush<1>();
        CLEAR_EC_PC_FIR_CORE_PC_TFAC_XSTOP_ERROR(l_data);
        FAPI_TRY(PUT_EC_PC_FIR_CORE_WO_AND(i_target_core, l_data));

        FAPI_TRY(PREP_EC_PC_FIR_CORE_FIRMASK_WO_AND(i_target_core));
        l_data.flush<1>();
        CLEAR_EC_PC_FIR_CORE_FIRMASK_MASK_PC_TFAC_XSTOP_ERROR(l_data);
        FAPI_TRY(PUT_EC_PC_FIR_CORE_FIRMASK_WO_AND(i_target_core, l_data));
    }

    // Save off the current values of actions into the register
    FAPI_TRY(PREP_EC_PC_FIR_CORE_ACTION0(i_target_core));
    FAPI_TRY(PUT_EC_PC_FIR_CORE_ACTION0(i_target_core, l_action0));
    FAPI_TRY(PREP_EC_PC_FIR_CORE_ACTION1(i_target_core));
    FAPI_TRY(PUT_EC_PC_FIR_CORE_ACTION1(i_target_core, l_action1));

    FAPI_INF("Exiting ...");

fapi_try_exit:
    return fapi2::current_err;
}
<|endoftext|>


<commit_before>#include "NativeCore.hpp"
#include "NativeLogging.hpp"

#include "ss/Augmentor.hpp"
#include "ss/Common.hpp"
#include "ss/KeyFrame.hpp"
#include "ss/VSlam.hpp"
//#include <string>

//static std::string ConvertString(JNIEnv* env, jstring js)
//{
//    const char* stringChars = env->GetStringUTFChars(js, 0);
//    std::string s = std::string(stringChars);
//    env->ReleaseStringUTFChars(js, stringChars);
//    return s;
//}

JNIEXPORT jlong JNICALL Java_edu_stanford_cvgl_artsy_CameraActivity_CreateNativeController
  (JNIEnv *, jobject)
{
	// Create new VSlam object
	return (jlong)(new vslam::VSlam);
}

JNIEXPORT void JNICALL Java_edu_stanford_cvgl_artsy_CameraActivity_DestroyNativeController
  (JNIEnv *, jobject, jlong addr_native_controller)
{
	delete (vslam::VSlam*)(addr_native_controller);
}

JNIEXPORT void JNICALL Java_edu_stanford_cvgl_artsy_CameraActivity_HandleFrame
  (JNIEnv *, jobject, jlong addr_native_controller, jlong addr_rgba)
{
	// Obtain SLAM object and current camera frame
	vslam::VSlam* slam = (vslam::VSlam*)(addr_native_controller);
	cv::Mat* frame = (cv::Mat*)(addr_rgba);
	cvtColor(*frame, *frame, CV_RGBA2BGR);

	// Update SLAM with the current frame
  // clock_t start = clock();
	slam->ProcessFrame(*frame);
  // clock_t end = clock();

  // double processFrameDuration = (end - start) / (double) CLOCKS_PER_SEC;
  // LOG_ERROR("NativeCore", "processFrameDuration: %f", processFrameDuration);

	// Render XYZ and YPR values of the current keyframe
	Augmentor augmentor;
	vslam::KeyFrame currKeyFrame = slam->GetCurrKeyFrame();
  Mat translationMatrix = currKeyFrame.GetTranslation();
  augmentor.DisplayTranslation(*frame, translationMatrix);
  Mat rotationMatrix = currKeyFrame.GetRotation();
  augmentor.DisplayRotation(*frame, rotationMatrix);

	// Render keypoints of the current key frame
	vslam::KeypointArray keypoints = currKeyFrame.GetTrackedKeypoints();
	Scalar kpColor = Scalar(255, 0, 0);
	drawKeypoints(*frame, keypoints, *frame, kpColor);
}

//JNIEXPORT void JNICALL Java_edu_stanford_cvgl_artsy_CameraActivity_SetDataLocation
//  (JNIEnv* env, jobject, jstring path)
//{
//	ar::SetResourceBasePath(ConvertString(env, path));
//}
<commit_msg>cleaned up nativecore.cpp<commit_after>#include "NativeCore.hpp"
#include "NativeLogging.hpp"

#include "ss/Augmentor.hpp"
#include "ss/Common.hpp"
#include "ss/KeyFrame.hpp"
#include "ss/VSlam.hpp"

JNIEXPORT jlong JNICALL Java_edu_stanford_cvgl_artsy_CameraActivity_CreateNativeController
  (JNIEnv *, jobject)
{
	// Create new VSlam object
	return (jlong)(new vslam::VSlam);
}

JNIEXPORT void JNICALL Java_edu_stanford_cvgl_artsy_CameraActivity_DestroyNativeController
  (JNIEnv *, jobject, jlong addr_native_controller)
{
	delete (vslam::VSlam*)(addr_native_controller);
}

JNIEXPORT void JNICALL Java_edu_stanford_cvgl_artsy_CameraActivity_HandleFrame
  (JNIEnv *, jobject, jlong addr_native_controller, jlong addr_rgba)
{
	// Obtain SLAM object and current camera frame
	vslam::VSlam* slam = (vslam::VSlam*)(addr_native_controller);
	cv::Mat* frame = (cv::Mat*)(addr_rgba);
	cvtColor(*frame, *frame, CV_RGBA2BGR);

	// Update SLAM with the current frame
  // clock_t start = clock();
	slam->ProcessFrame(*frame);
  // clock_t end = clock();

  // double processFrameDuration = (end - start) / (double) CLOCKS_PER_SEC;
  // LOG_ERROR("NativeCore", "processFrameDuration: %f", processFrameDuration);

	// Render XYZ and YPR values of the current keyframe
	Augmentor augmentor;
	vslam::KeyFrame currKeyFrame = slam->GetCurrKeyFrame();
  Mat translationMatrix = currKeyFrame.GetTranslation();
  augmentor.DisplayTranslation(*frame, translationMatrix);
  Mat rotationMatrix = currKeyFrame.GetRotation();
  augmentor.DisplayRotation(*frame, rotationMatrix);

	// Render keypoints of the current key frame
	vslam::KeypointArray keypoints = currKeyFrame.GetTrackedKeypoints();
	Scalar kpColor = Scalar(255, 0, 0);
	drawKeypoints(*frame, keypoints, *frame, kpColor);
}<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C $ */
/*                                                                        */
/* 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_config_thermal.C
/// @brief Perform thermal calculations as part of the effective configuration
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <vector>
#include <p9_mss_eff_config_thermal.H>
#include <p9_mss_bulk_pwr_throttles.H>
#include <lib/power_thermal/throttle.H>
#include <lib/power_thermal/decoder.H>
#include <lib/dimm/kind.H>
#include <lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
#include <mss.H>
extern "C"
{
    ///
    /// @brief Perform thermal calculations as part of the effective configuration
    /// @param[in] i_targets an array of MCS targets all on the same VDDR domain
    /// @return FAPI2_RC_SUCCESS iff ok
    /// @note sets ATTR_MSS_MEM_WATT_TARGET, ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT and _PER_SLOT, and ATTR_MSS_PORT_MAXPOWER
    fapi2::ReturnCode p9_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets )
    {

        FAPI_INF("Start effective config thermal");

        uint16_t l_vddr_slope     [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint16_t l_vddr_int       [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint16_t l_total_slope    [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint16_t l_total_int      [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint32_t l_thermal_power  [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        fapi2::ReturnCode l_rc;

        //Gotta convert into fapi2::buffers. Not very elegant
        //Do it here or in the encode and decode functions
        //Not that pretty :(
        std::vector< uint64_t > l_tslope (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
        std::vector< uint64_t > l_tintercept (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
        std::vector< uint64_t > l_tthermal_power_limit (mss::power_thermal::SIZE_OF_THERMAL_ATTR, 0);

        std::vector<fapi2::buffer< uint64_t>> l_slope = {};
        std::vector<fapi2::buffer< uint64_t>> l_intercept = {};
        std::vector<fapi2::buffer< uint64_t>> l_thermal_power_limit = {};

        //Get the vectors of power curves and thermal power limits to convert to buffers
        FAPI_TRY( mss::mrw_pwr_slope (l_tslope.data()), "Error in p9_mss_eff_config_thermal");
        FAPI_TRY( mss::mrw_pwr_intercept (l_tintercept.data()), "Error in p9_mss_eff_config_thermal" );
        FAPI_TRY( mss::mrw_thermal_memory_power_limit (l_tthermal_power_limit.data()), "Error in p9_mss_eff_config_thermal" );
        FAPI_TRY( mss::power_thermal::set_runtime_m_and_watt_limit(i_targets), "Error in p9_mss_eff_config_thermal");

        for (size_t i = 0; i < mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS; ++i)
        {
            for (const auto l_cur : l_tslope)
            {
                fapi2::buffer<uint64_t> l_slope_buf = l_cur;

                if (l_slope_buf != 0)
                {
                    l_slope.push_back(l_slope_buf);
                }
            }

            for (auto l_cur : l_tintercept)
            {
                fapi2::buffer<uint64_t> l_intercept_buf = l_cur;

                if (l_intercept_buf != 0)
                {
                    l_intercept.push_back(l_intercept_buf);
                }
            }

            for (auto l_cur : l_tthermal_power_limit)
            {
                fapi2::buffer<uint64_t> l_tthermal_buf = l_cur;

                if (l_tthermal_buf != 0)
                {
                    l_thermal_power_limit.push_back(l_tthermal_buf);
                }
            }
        }

        //Restore runtime_throttles from safemode setting
        //Decode and set power curve attributes at the same time
        for (const auto& l_mcs : i_targets )
        {
            //Not doing any work if there are no dimms installed
            if (mss::count_dimm(l_mcs) == 0)
            {
                continue;
            }

            FAPI_TRY( mss::power_thermal::get_power_attrs(l_mcs,
                      l_slope,
                      l_intercept,
                      l_thermal_power_limit,
                      l_vddr_slope,
                      l_vddr_int,
                      l_total_slope,
                      l_total_int,
                      l_thermal_power));
            //Sets throttles to max_databus_util value
            FAPI_INF("Restoring throttles");
            FAPI_TRY( mss::power_thermal::restore_runtime_throttles(l_mcs), "Error in p9_mss_eff_config_thermal");

            //Set the power attribute (TOTAL_PWR) to just VDDR for the POWER bulk_pwr_throttles, restore to vddr+vpp  later for OCC
            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
                                    l_mcs,
                                    l_vddr_slope));

            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT,
                                    l_mcs,
                                    l_vddr_int));

            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_DIMM_THERMAL_LIMIT,
                                    l_mcs,
                                    l_thermal_power));
        }

        FAPI_INF("Starting bulk_pwr");
        //get the thermal limits, done per dimm and set to worst case for the slot and port throttles
        //Bulk_pwr sets the general, all purpose ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, _PER_PORT, and MAXPOWER ATTRs
        FAPI_EXEC_HWP(l_rc, p9_mss_bulk_pwr_throttles, i_targets, mss::throttle_type::POWER);
        FAPI_TRY(l_rc, "Failed running p9_mss_bulk_pwr_throttles");

        //Set runtime throttles to worst case between ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT
        //and ATTR_MSS_MEM_RUNTIME_THROTTLED_N_COMMANDS_PER_SLOT and the _PORT equivalents also
        FAPI_INF("Starting update");
        FAPI_TRY( mss::power_thermal::update_runtime_throttles (i_targets), "Error in p9_mss_eff_config_thermal" );
        FAPI_INF("finished update");

        //Set VDDR+VPP power curve values
        for ( const auto& l_mcs : i_targets )
        {
            if (mss::count_dimm(l_mcs) == 0)
            {
                continue;
            }

            FAPI_TRY( mss::power_thermal::get_power_attrs(l_mcs,
                      l_slope,
                      l_intercept,
                      l_thermal_power_limit,
                      l_vddr_slope,
                      l_vddr_int,
                      l_total_slope,
                      l_total_int,
                      l_thermal_power));

            FAPI_INF( "VDDR+VPP power curve slope is %d, int is %d, thermal_power is %d", l_total_slope[0][0], l_total_int[0][0],
                      l_thermal_power[0][0]);

            //Set the power curve attributes (TOTAL_PWR) to vpp+vdd power slope and intercept
            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
                                    l_mcs,
                                    l_total_slope));

            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT,
                                    l_mcs,
                                    l_total_int));
        }

        //Run thermal throttles with the VDDR+VPP power curves
        FAPI_EXEC_HWP(l_rc, p9_mss_bulk_pwr_throttles, i_targets, mss::throttle_type::THERMAL);
        FAPI_TRY(l_rc, "Failed running p9_mss_bulk_pwr_throttles with THERMAL throttling in p9_mss_eff_config_thermal");
        //Update everything to worst case
        FAPI_TRY( mss::power_thermal::update_runtime_throttles (i_targets), "Error in p9_mss_eff_config_thermal" );

        //Done
        FAPI_INF( "End effective config thermal");

    fapi_try_exit:
        return fapi2::current_err;
    }
} //extern C
<commit_msg>Fix eff_config_thermal allocations<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/p9_mss_eff_config_thermal.C $ */
/*                                                                        */
/* 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_config_thermal.C
/// @brief Perform thermal calculations as part of the effective configuration
///
// *HWP HWP Owner: Jacob Harvey <jlharvey@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: FSP:HB

#include <fapi2.H>
#include <vector>
#include <p9_mss_eff_config_thermal.H>
#include <p9_mss_bulk_pwr_throttles.H>
#include <lib/power_thermal/throttle.H>
#include <lib/power_thermal/decoder.H>
#include <lib/dimm/kind.H>
#include <lib/utils/count_dimm.H>
#include <lib/shared/mss_const.H>
#include <mss.H>
extern "C"
{
    ///
    /// @brief Perform thermal calculations as part of the effective configuration
    /// @param[in] i_targets an array of MCS targets all on the same VDDR domain
    /// @return FAPI2_RC_SUCCESS iff ok
    /// @note sets ATTR_MSS_MEM_WATT_TARGET, ATTR_MSS_RUNTIME_MEM_THROTTLED_N_COMMANDS_PER_PORT and _PER_SLOT, and ATTR_MSS_PORT_MAXPOWER
    fapi2::ReturnCode p9_mss_eff_config_thermal( const std::vector< fapi2::Target<fapi2::TARGET_TYPE_MCS> >& i_targets )
    {
        FAPI_INF("Start effective config thermal");
        fapi2::ReturnCode l_rc;

        std::vector< uint64_t > l_slope (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
        std::vector< uint64_t > l_intercept (mss::power_thermal::SIZE_OF_POWER_CURVES_ATTRS, 0);
        std::vector< uint64_t > l_thermal_power_limit (mss::power_thermal::SIZE_OF_THERMAL_ATTR, 0);

        uint16_t l_vddr_slope     [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint16_t l_vddr_int       [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint16_t l_total_slope    [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint16_t l_total_int      [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};
        uint32_t l_thermal_power  [mss::PORTS_PER_MCS][mss::MAX_DIMM_PER_PORT] = {};

        FAPI_TRY( mss::mrw_pwr_slope (l_slope.data()), "Error in p9_mss_eff_config_thermal");
        FAPI_TRY( mss::mrw_pwr_intercept (l_intercept.data()), "Error in p9_mss_eff_config_thermal" );
        FAPI_TRY( mss::mrw_thermal_memory_power_limit (l_thermal_power_limit.data()), "Error in p9_mss_eff_config_thermal" );
        FAPI_TRY( mss::power_thermal::set_runtime_m_and_watt_limit (i_targets), "Error in p9_mss_eff_config_thermal");

        FAPI_INF("Size of vectors are %d %d %d", l_slope.size(), l_intercept.size(), l_thermal_power_limit.size());

        //Restore runtime_throttles from safemode setting
        //Decode and set power curve attributes at the same time
        for (const auto& l_mcs : i_targets )
        {
            //Not doing any work if there are no dimms installed
            if (mss::count_dimm(l_mcs) == 0)
            {
                FAPI_INF("Skipping eff_config thermal because no dimms %s", mss::c_str(l_mcs));
                continue;
            }

            FAPI_TRY( mss::power_thermal::get_power_attrs(l_mcs,
                      l_slope,
                      l_intercept,
                      l_thermal_power_limit,
                      l_vddr_slope,
                      l_vddr_int,
                      l_total_slope,
                      l_total_int,
                      l_thermal_power));

            //Sets throttles to max_databus_util value
            FAPI_INF("Restoring throttles");
            FAPI_TRY( mss::power_thermal::restore_runtime_throttles(l_mcs), "Error in p9_mss_eff_config_thermal");

            //Set the power attribute (TOTAL_PWR) to just VDDR for the POWER bulk_pwr_throttles, restore to vddr+vpp  later for OCC
            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
                                    l_mcs,
                                    l_vddr_slope));

            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT,
                                    l_mcs,
                                    l_vddr_int));

            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_DIMM_THERMAL_LIMIT,
                                    l_mcs,
                                    l_thermal_power));
        }

        FAPI_INF("Starting bulk_pwr");
        //get the thermal limits, done per dimm and set to worst case for the slot and port throttles
        //Bulk_pwr sets the general, all purpose ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT, _PER_PORT, and MAXPOWER ATTRs
        FAPI_EXEC_HWP(l_rc, p9_mss_bulk_pwr_throttles, i_targets, mss::throttle_type::POWER);
        FAPI_TRY(l_rc, "Failed running p9_mss_bulk_pwr_throttles");

        //Set runtime throttles to worst case between ATTR_MSS_MEM_THROTTLED_N_COMMANDS_PER_SLOT
        //and ATTR_MSS_MEM_RUNTIME_THROTTLED_N_COMMANDS_PER_SLOT and the _PORT equivalents also
        FAPI_INF("Starting update");
        FAPI_TRY( mss::power_thermal::update_runtime_throttles (i_targets), "Error in p9_mss_eff_config_thermal" );
        FAPI_INF("finished update");

        //Set VDDR+VPP power curve values
        for ( const auto& l_mcs : i_targets )
        {
            if (mss::count_dimm(l_mcs) == 0)
            {
                continue;
            }

            //Zero out the arrays
            memset(l_vddr_slope, 0, sizeof(l_vddr_slope));
            memset(l_vddr_int, 0, sizeof(l_vddr_int));
            memset(l_total_slope, 0, sizeof(l_total_slope));
            memset(l_total_int, 0, sizeof(l_total_int));
            memset(l_thermal_power, 0, sizeof(l_thermal_power));

            FAPI_TRY( mss::power_thermal::get_power_attrs(l_mcs,
                      l_slope,
                      l_intercept,
                      l_thermal_power_limit,
                      l_vddr_slope,
                      l_vddr_int,
                      l_total_slope,
                      l_total_int,
                      l_thermal_power));

            FAPI_INF( "VDDR+VPP power curve slope is %d, int is %d, thermal_power is %d", l_total_slope[0][0], l_total_int[0][0],
                      l_thermal_power[0][0]);

            //Set the power curve attributes (TOTAL_PWR) to vpp+vdd power slope and intercept
            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_SLOPE,
                                    l_mcs,
                                    l_total_slope));

            FAPI_TRY( FAPI_ATTR_SET(fapi2::ATTR_MSS_TOTAL_PWR_INTERCEPT,
                                    l_mcs,
                                    l_total_int));
        }

        //Run thermal throttles with the VDDR+VPP power curves
        FAPI_EXEC_HWP(l_rc, p9_mss_bulk_pwr_throttles, i_targets, mss::throttle_type::THERMAL);
        FAPI_TRY(l_rc, "Failed running p9_mss_bulk_pwr_throttles with THERMAL throttling in p9_mss_eff_config_thermal");
        //Update everything to worst case
        FAPI_TRY( mss::power_thermal::update_runtime_throttles (i_targets), "Error in p9_mss_eff_config_thermal" );

        //Done
        FAPI_INF( "End effective config thermal");

    fapi_try_exit:
        return fapi2::current_err;
    }
} //extern C
<|endoftext|>


<commit_before>#include <node.h>
#include "nan.h"

NAN_METHOD(ReturnString) {
  NanScope();
  Nan::Encoding enc = Nan::UTF8;
  size_t bc;
  unsigned int flags = v8::String::HINT_MANY_WRITES_EXPECTED | v8::String::NO_NULL_TERMINATION;

  if (args[1]->IsUint32()) {
    enc = (Nan::Encoding) args[1]->Uint32Value();
  }

  if (args[2]->IsUint32()) {
    flags = args[2]->Uint32Value();
  }

  char *s = NanFromV8String(args[0].As<v8::Object>(), enc, &bc, NULL, 0, flags);
  if (enc == Nan::UCS2) {
    NanReturnValue(v8::String::New(reinterpret_cast<uint16_t *>(s), flags & v8::String::NO_NULL_TERMINATION ? bc / 2 : - 1));
  } else {
    NanReturnValue(v8::String::New(s, flags & v8::String::NO_NULL_TERMINATION ? bc : -1));
  }
}

NAN_METHOD(ReturnCString) {
  NanScope();

  size_t bc;
  char *s = NanCString(args[0].As<v8::Object>(), &bc);
  v8::Local<v8::String> str = v8::String::New(s);
  delete[] s;

  NanReturnValue(str);
}

NAN_METHOD(CompareCStringToBuffer) {
  NanScope();

  size_t expectedLen = node::Buffer::Length(args[1]->ToObject());
  char* expectedChars = node::Buffer::Data(args[1]->ToObject());

  size_t actualLen;
  char* actualChars = NanCString(args[0], &actualLen);

  if (actualLen != expectedLen) {
    NanThrowError(v8::String::New("actual length != expected length"));
    NanReturnUndefined();
  }

  if (expectedChars[expectedLen] != '\0') {
    NanThrowError(v8::String::New("should be null-terminated"));
    NanReturnUndefined();
  }

  if (strncmp(actualChars, expectedChars, expectedLen) != 0) {
    NanThrowError(v8::String::New("actual chars != expected chars"));
    NanReturnUndefined();
  }

  NanReturnValue(v8::Boolean::New(true));
}

NAN_METHOD(CompareRawStringToBuffer) {
  NanScope();

  size_t expectedLen = node::Buffer::Length(args[1]->ToObject());
  char* expectedChars = node::Buffer::Data(args[1]->ToObject());

  size_t actualLen;
  char* decoded = (char*)NanRawString(args[0], Nan::BASE64, &actualLen, NULL, 0, v8::String::HINT_MANY_WRITES_EXPECTED);
  char actualChars[actualLen];
  memcpy(actualChars, decoded, actualLen);
  delete[] decoded;

  if (actualLen != expectedLen) {
    NanThrowError(v8::String::New("actual length != expected length"));
    NanReturnUndefined();
  }

  if (expectedChars[expectedLen] == '\0') {
    NanThrowError(v8::String::New("should not be null-terminated"));
    NanReturnUndefined();
  }

  if (strncmp(actualChars, expectedChars, expectedLen) != '\0') {
    NanThrowError(v8::String::New("actual chars != expected chars"));
    NanReturnUndefined();
  }

  NanReturnValue(v8::Boolean::New(true));
}

v8::Persistent<v8::FunctionTemplate> returnString_persistent;
v8::Persistent<v8::FunctionTemplate> returnCString_persistent;
v8::Persistent<v8::FunctionTemplate> compareCStringToBuffer_persistent;
v8::Persistent<v8::FunctionTemplate> compareRawStringToBuffer_persistent;

void Init (v8::Handle<v8::Object> target) {
  NanScope();

  v8::Local<v8::FunctionTemplate> returnString = v8::FunctionTemplate::New(ReturnString);
  NanAssignPersistent(v8::FunctionTemplate, returnString_persistent, returnString);
  target->Set(
      NanSymbol("returnString")
    , returnString->GetFunction()
  );
  v8::Local<v8::FunctionTemplate> returnCString = v8::FunctionTemplate::New(ReturnCString);
  NanAssignPersistent(v8::FunctionTemplate, returnCString_persistent, returnCString);
  target->Set(
      NanSymbol("returnCString")
    , returnCString->GetFunction()
  );
  v8::Local<v8::FunctionTemplate> compareCStringToBuffer = v8::FunctionTemplate::New(CompareCStringToBuffer);
  NanAssignPersistent(v8::FunctionTemplate, compareCStringToBuffer_persistent, compareCStringToBuffer);
  target->Set(
      NanSymbol("compareCStringToBuffer")
    , compareCStringToBuffer->GetFunction()
  );
  v8::Local<v8::FunctionTemplate> compareRawStringToBuffer = v8::FunctionTemplate::New(CompareRawStringToBuffer);
  NanAssignPersistent(v8::FunctionTemplate, compareRawStringToBuffer_persistent, compareRawStringToBuffer);
  target->Set(
      NanSymbol("compareRawStringToBuffer")
    , compareRawStringToBuffer->GetFunction()
  );
}

NODE_MODULE(fromv8string, Init)
<commit_msg>fix strncmp<commit_after>#include <node.h>
#include "nan.h"

NAN_METHOD(ReturnString) {
  NanScope();
  Nan::Encoding enc = Nan::UTF8;
  size_t bc;
  unsigned int flags = v8::String::HINT_MANY_WRITES_EXPECTED | v8::String::NO_NULL_TERMINATION;

  if (args[1]->IsUint32()) {
    enc = (Nan::Encoding) args[1]->Uint32Value();
  }

  if (args[2]->IsUint32()) {
    flags = args[2]->Uint32Value();
  }

  char *s = NanFromV8String(args[0].As<v8::Object>(), enc, &bc, NULL, 0, flags);
  if (enc == Nan::UCS2) {
    NanReturnValue(v8::String::New(reinterpret_cast<uint16_t *>(s), flags & v8::String::NO_NULL_TERMINATION ? bc / 2 : - 1));
  } else {
    NanReturnValue(v8::String::New(s, flags & v8::String::NO_NULL_TERMINATION ? bc : -1));
  }
}

NAN_METHOD(ReturnCString) {
  NanScope();

  size_t bc;
  char *s = NanCString(args[0].As<v8::Object>(), &bc);
  v8::Local<v8::String> str = v8::String::New(s);
  delete[] s;

  NanReturnValue(str);
}

NAN_METHOD(CompareCStringToBuffer) {
  NanScope();

  size_t expectedLen = node::Buffer::Length(args[1]->ToObject());
  char* expectedChars = node::Buffer::Data(args[1]->ToObject());

  size_t actualLen;
  char* actualChars = NanCString(args[0], &actualLen);

  if (actualLen != expectedLen) {
    NanThrowError(v8::String::New("actual length != expected length"));
    NanReturnUndefined();
  }

  if (expectedChars[expectedLen] != '\0') {
    NanThrowError(v8::String::New("should be null-terminated"));
    NanReturnUndefined();
  }

  if (strncmp(actualChars, expectedChars, expectedLen) != 0) {
    NanThrowError(v8::String::New("actual chars != expected chars"));
    NanReturnUndefined();
  }

  NanReturnValue(v8::Boolean::New(true));
}

NAN_METHOD(CompareRawStringToBuffer) {
  NanScope();

  size_t expectedLen = node::Buffer::Length(args[1]->ToObject());
  char* expectedChars = node::Buffer::Data(args[1]->ToObject());

  size_t actualLen;
  char* decoded = (char*)NanRawString(args[0], Nan::BASE64, &actualLen, NULL, 0, v8::String::HINT_MANY_WRITES_EXPECTED);
  char actualChars[actualLen];
  memcpy(actualChars, decoded, actualLen);
  delete[] decoded;

  if (actualLen != expectedLen) {
    NanThrowError(v8::String::New("actual length != expected length"));
    NanReturnUndefined();
  }

  if (expectedChars[expectedLen] == '\0') {
    NanThrowError(v8::String::New("should not be null-terminated"));
    NanReturnUndefined();
  }

  if (strncmp(actualChars, expectedChars, expectedLen) != 0) {
    NanThrowError(v8::String::New("actual chars != expected chars"));
    NanReturnUndefined();
  }

  NanReturnValue(v8::Boolean::New(true));
}

v8::Persistent<v8::FunctionTemplate> returnString_persistent;
v8::Persistent<v8::FunctionTemplate> returnCString_persistent;
v8::Persistent<v8::FunctionTemplate> compareCStringToBuffer_persistent;
v8::Persistent<v8::FunctionTemplate> compareRawStringToBuffer_persistent;

void Init (v8::Handle<v8::Object> target) {
  NanScope();

  v8::Local<v8::FunctionTemplate> returnString = v8::FunctionTemplate::New(ReturnString);
  NanAssignPersistent(v8::FunctionTemplate, returnString_persistent, returnString);
  target->Set(
      NanSymbol("returnString")
    , returnString->GetFunction()
  );
  v8::Local<v8::FunctionTemplate> returnCString = v8::FunctionTemplate::New(ReturnCString);
  NanAssignPersistent(v8::FunctionTemplate, returnCString_persistent, returnCString);
  target->Set(
      NanSymbol("returnCString")
    , returnCString->GetFunction()
  );
  v8::Local<v8::FunctionTemplate> compareCStringToBuffer = v8::FunctionTemplate::New(CompareCStringToBuffer);
  NanAssignPersistent(v8::FunctionTemplate, compareCStringToBuffer_persistent, compareCStringToBuffer);
  target->Set(
      NanSymbol("compareCStringToBuffer")
    , compareCStringToBuffer->GetFunction()
  );
  v8::Local<v8::FunctionTemplate> compareRawStringToBuffer = v8::FunctionTemplate::New(CompareRawStringToBuffer);
  NanAssignPersistent(v8::FunctionTemplate, compareRawStringToBuffer_persistent, compareRawStringToBuffer);
  target->Set(
      NanSymbol("compareRawStringToBuffer")
    , compareRawStringToBuffer->GetFunction()
  );
}

NODE_MODULE(fromv8string, Init)
<|endoftext|>


<commit_before>#include <node.h>
#include "nan.h"
#include <string>

class SetterGetter : public node::ObjectWrap {
public:
  static void Init (v8::Handle<v8::Object> target);
  static v8::Handle<v8::Value> NewInstance ();
  static NAN_METHOD(New);
  static NAN_METHOD(Log);
  static NAN_GETTER(GetProp1);
  static NAN_GETTER(GetProp2);
  static NAN_SETTER(SetProp2);

  SetterGetter();

  std::string log;
  std::string prop1;
  std::string prop2;
};

static v8::Persistent<v8::FunctionTemplate> settergetter_constructor;

NAN_METHOD(CreateNew) {
  NanScope();
  NanReturnValue(SetterGetter::NewInstance());
}

SetterGetter::SetterGetter() {
  prop1.assign("this is property 1");
}

void SetterGetter::Init(v8::Handle<v8::Object> target) {
  v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(SetterGetter::New)
;
  NanAssignPersistent(v8::FunctionTemplate, settergetter_constructor, tpl);
  tpl->SetClassName(NanSymbol("SetterGetter"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  NODE_SET_PROTOTYPE_METHOD(tpl, "log", SetterGetter::Log);
  v8::Local<v8::ObjectTemplate> proto = tpl->PrototypeTemplate();
  proto->SetAccessor(NanSymbol("prop1"), SetterGetter::GetProp1);
  proto->SetAccessor(NanSymbol("prop2"), SetterGetter::GetProp2, SetterGetter::SetProp2);

  v8::Local<v8::Function> createnew =
    v8::FunctionTemplate::New(CreateNew)->GetFunction();
  target->Set(NanSymbol("create"), createnew);
}

v8::Handle<v8::Value> SetterGetter::NewInstance () {
  v8::Local<v8::FunctionTemplate> constructorHandle =
      NanPersistentToLocal(settergetter_constructor);
  v8::Local<v8::Object> instance =
    constructorHandle->GetFunction()->NewInstance(0, NULL);
  return instance;
}

NAN_METHOD(SetterGetter::New) {
  NanScope();

  SetterGetter* settergetter = new SetterGetter();
  settergetter->log.append("New()\n");
  settergetter->Wrap(args.This());

  NanReturnValue(args.This());
}

NAN_GETTER(SetterGetter::GetProp1) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());
  settergetter->log.append("Prop1:GETTER(");
  settergetter->log.append(settergetter->prop1);
  settergetter->log.append(")\n");

  NanReturnValue(v8::String::New(settergetter->prop1.c_str()));
}

NAN_GETTER(SetterGetter::GetProp2) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());
  settergetter->log.append("Prop2:GETTER(");
  settergetter->log.append(settergetter->prop2);
  settergetter->log.append(")\n");

  NanReturnValue(v8::String::New(settergetter->prop2.c_str()));
}

NAN_SETTER(SetterGetter::SetProp2) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());
    settergetter->prop2.assign(NanFromV8String(value));
  settergetter->log.append("Prop2:SETTER(");
  settergetter->log.append(settergetter->prop2);
  settergetter->log.append(")\n");
}

NAN_METHOD(SetterGetter::Log) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());

  NanReturnValue(v8::String::New(settergetter->log.c_str()));
}

NODE_MODULE(settergetter, SetterGetter::Init)
<commit_msg>test: fix buffer overrun in settergetter test<commit_after>#include <node.h>
#include "nan.h"
#include <string>

class SetterGetter : public node::ObjectWrap {
public:
  static void Init (v8::Handle<v8::Object> target);
  static v8::Handle<v8::Value> NewInstance ();
  static NAN_METHOD(New);
  static NAN_METHOD(Log);
  static NAN_GETTER(GetProp1);
  static NAN_GETTER(GetProp2);
  static NAN_SETTER(SetProp2);

  SetterGetter();

  std::string log;
  std::string prop1;
  std::string prop2;
};

static v8::Persistent<v8::FunctionTemplate> settergetter_constructor;

NAN_METHOD(CreateNew) {
  NanScope();
  NanReturnValue(SetterGetter::NewInstance());
}

SetterGetter::SetterGetter() {
  prop1.assign("this is property 1");
}

void SetterGetter::Init(v8::Handle<v8::Object> target) {
  v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(SetterGetter::New)
;
  NanAssignPersistent(v8::FunctionTemplate, settergetter_constructor, tpl);
  tpl->SetClassName(NanSymbol("SetterGetter"));
  tpl->InstanceTemplate()->SetInternalFieldCount(1);
  NODE_SET_PROTOTYPE_METHOD(tpl, "log", SetterGetter::Log);
  v8::Local<v8::ObjectTemplate> proto = tpl->PrototypeTemplate();
  proto->SetAccessor(NanSymbol("prop1"), SetterGetter::GetProp1);
  proto->SetAccessor(NanSymbol("prop2"), SetterGetter::GetProp2, SetterGetter::SetProp2);

  v8::Local<v8::Function> createnew =
    v8::FunctionTemplate::New(CreateNew)->GetFunction();
  target->Set(NanSymbol("create"), createnew);
}

v8::Handle<v8::Value> SetterGetter::NewInstance () {
  v8::Local<v8::FunctionTemplate> constructorHandle =
      NanPersistentToLocal(settergetter_constructor);
  v8::Local<v8::Object> instance =
    constructorHandle->GetFunction()->NewInstance(0, NULL);
  return instance;
}

NAN_METHOD(SetterGetter::New) {
  NanScope();

  SetterGetter* settergetter = new SetterGetter();
  settergetter->log.append("New()\n");
  settergetter->Wrap(args.This());

  NanReturnValue(args.This());
}

NAN_GETTER(SetterGetter::GetProp1) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());
  settergetter->log.append("Prop1:GETTER(");
  settergetter->log.append(settergetter->prop1);
  settergetter->log.append(")\n");

  NanReturnValue(v8::String::New(settergetter->prop1.c_str()));
}

NAN_GETTER(SetterGetter::GetProp2) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());
  settergetter->log.append("Prop2:GETTER(");
  settergetter->log.append(settergetter->prop2);
  settergetter->log.append(")\n");

  NanReturnValue(v8::String::New(settergetter->prop2.c_str()));
}

NAN_SETTER(SetterGetter::SetProp2) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());
    settergetter->prop2.assign(NanCString(value, NULL));
  settergetter->log.append("Prop2:SETTER(");
  settergetter->log.append(settergetter->prop2);
  settergetter->log.append(")\n");
}

NAN_METHOD(SetterGetter::Log) {
  NanScope();

  SetterGetter* settergetter =
    node::ObjectWrap::Unwrap<SetterGetter>(args.This());

  NanReturnValue(v8::String::New(settergetter->log.c_str()));
}

NODE_MODULE(settergetter, SetterGetter::Init)
<|endoftext|>


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

#include "utils.h"

#include "client_http.h"

//
// Xapian http client
//

HttpClient::HttpClient(ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, double active_timeout_, double idle_timeout_)
	: BaseClient(loop, sock_, database_pool_, active_timeout_, idle_timeout_)
{
	parser.data = this;
	http_parser_init(&parser, HTTP_REQUEST);
	LOG_CONN(this, "Got connection (sock=%d), %d http client(s) connected.\n", sock, ++total_clients);
}

HttpClient::~HttpClient()
{
	total_clients--;
}

void HttpClient::on_read(const char *buf, ssize_t received)
{
	size_t parsed = http_parser_execute(&parser, &settings, buf, received);
	if (parsed == received) {
		if (parser.state == 1 || parser.state == 18) { // dead or message_complete
			try {
				//					LOG_HTTP_PROTO(this, "METHOD: %d\n", parser.method);
				//					LOG_HTTP_PROTO(this, "PATH: '%s'\n", repr(path).c_str());
				//					LOG_HTTP_PROTO(this, "BODY: '%s'\n", repr(body).c_str());
				write("HTTP/1.1 200 OK\r\n"
					  "Content-Length: 3\r\n"
					  "\r\n"
					  "OK!");
				if (parser.state == 1) close();
			} catch (...) {
				LOG_ERR(this, "ERROR!\n");
			}
		}
	} else {
		enum http_errno err = HTTP_PARSER_ERRNO(&parser);
		const char *desc = http_errno_description(err);
		const char *msg = err != HPE_OK ? desc : "incomplete request";
		LOG_HTTP_PROTO(this, msg);
		// Handle error. Just close the connection.
		destroy();
	}
}

//
// HTTP parser callbacks.
//

const http_parser_settings HttpClient::settings = {
	.on_message_begin = on_info,
	.on_headers_complete = on_info,
	.on_message_complete = on_info,
	.on_header_field = on_data,
	.on_header_value = on_data,
	.on_url = on_data,
	.on_status = on_data,
	.on_body = on_data
};

int HttpClient::on_info(http_parser* p) {
	HttpClient *self = static_cast<HttpClient *>(p->data);

	LOG_HTTP_PROTO_PARSER(self, "%3d. (INFO)\n", p->state);

	switch (p->state) {
		case 18:  // message_complete
			break;
		case 19:  // message_begin
			self->path.clear();
			self->body.clear();
			break;
	}

	return 0;
}

int HttpClient::on_data(http_parser* p, const char *at, size_t length) {
	HttpClient *self = static_cast<HttpClient *>(p->data);

	LOG_HTTP_PROTO_PARSER(self, "%3d. %s\n", p->state, repr(at, length).c_str());

	switch (p->state) {
		case 32: // path
			self->path = std::string(at, length);
			break;
		case 62: // data
			self->body = std::string(at, length);
			break;
	}

	return 0;
}
<commit_msg>Response with body in a string<commit_after>#include <sys/socket.h>

#include "utils.h"

#include "client_http.h"

//
// Xapian http client
//

HttpClient::HttpClient(ev::loop_ref *loop, int sock_, DatabasePool *database_pool_, double active_timeout_, double idle_timeout_)
	: BaseClient(loop, sock_, database_pool_, active_timeout_, idle_timeout_)
{
	parser.data = this;
	http_parser_init(&parser, HTTP_REQUEST);
	LOG_CONN(this, "Got connection (sock=%d), %d http client(s) connected.\n", sock, ++total_clients);
}

HttpClient::~HttpClient()
{
	total_clients--;
}

void HttpClient::on_read(const char *buf, ssize_t received)
{
	size_t parsed = http_parser_execute(&parser, &settings, buf, received);
	if (parsed == received) {
		if (parser.state == 1 || parser.state == 18) { // dead or message_complete
			try {
				//					LOG_HTTP_PROTO(this, "METHOD: %d\n", parser.method);
				//					LOG_HTTP_PROTO(this, "PATH: '%s'\n", repr(path).c_str());
				//					LOG_HTTP_PROTO(this, "BODY: '%s'\n", repr(body).c_str());
				char tmp[20];
				std::string body("OK!");
				std::string response;
				response += "HTTP/";
				sprintf(tmp, "%d.%d", parser.http_major, parser.http_minor);
				response += tmp;
				response += " 200 OK\r\n";
				response += "Content-Length: ";
				sprintf(tmp, "%ld", body.size());
				response += tmp;
				response += "\r\n";
				write(response + "\r\n" + body);
				if (parser.state == 1) close();
			} catch (...) {
				LOG_ERR(this, "ERROR!\n");
			}
		}
	} else {
		enum http_errno err = HTTP_PARSER_ERRNO(&parser);
		const char *desc = http_errno_description(err);
		const char *msg = err != HPE_OK ? desc : "incomplete request";
		LOG_HTTP_PROTO(this, msg);
		// Handle error. Just close the connection.
		destroy();
	}
}

//
// HTTP parser callbacks.
//

const http_parser_settings HttpClient::settings = {
	.on_message_begin = on_info,
	.on_headers_complete = on_info,
	.on_message_complete = on_info,
	.on_header_field = on_data,
	.on_header_value = on_data,
	.on_url = on_data,
	.on_status = on_data,
	.on_body = on_data
};

int HttpClient::on_info(http_parser* p) {
	HttpClient *self = static_cast<HttpClient *>(p->data);

	LOG_HTTP_PROTO_PARSER(self, "%3d. (INFO)\n", p->state);

	switch (p->state) {
		case 18:  // message_complete
			break;
		case 19:  // message_begin
			self->path.clear();
			self->body.clear();
			break;
	}

	return 0;
}

int HttpClient::on_data(http_parser* p, const char *at, size_t length) {
	HttpClient *self = static_cast<HttpClient *>(p->data);

	LOG_HTTP_PROTO_PARSER(self, "%3d. %s\n", p->state, repr(at, length).c_str());

	switch (p->state) {
		case 32: // path
			self->path = std::string(at, length);
			break;
		case 62: // data
			self->body = std::string(at, length);
			break;
	}

	return 0;
}
<|endoftext|>


<commit_before>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 Vince Durham
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2019 Daniel Kraft
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.

#include <auxpow.h>

#include <consensus/consensus.h>
#include <consensus/merkle.h>
#include <hash.h>
#include <primitives/block.h>
#include <script/script.h>
#include <util/strencodings.h>
#include <util/system.h>

#include <algorithm>

namespace
{

/**
 * Decodes a 32-bit little endian integer from raw bytes.
 */
uint32_t
DecodeLE32 (const unsigned char* bytes)
{
  uint32_t res = 0;
  for (int i = 0; i < 4; ++i)
    {
      res <<= 8;
      res |= bytes[3 - i];
    }
  return res;
}

} // anonymous namespace

bool
CAuxPow::check (const uint256& hashAuxBlock, int nChainId,
                const Consensus::Params& params) const
{
    if (params.fStrictChainId && parentBlock.GetChainId () == nChainId)
        return error("Aux POW parent has our chain ID");

    if (vChainMerkleBranch.size() > 30)
        return error("Aux POW chain merkle branch too long");

    // Check that the chain merkle root is in the coinbase
    const uint256 nRootHash
      = CheckMerkleBranch (hashAuxBlock, vChainMerkleBranch, nChainIndex);
    valtype vchRootHash(nRootHash.begin (), nRootHash.end ());
    std::reverse (vchRootHash.begin (), vchRootHash.end ()); // correct endian

    // Check that we are in the parent block merkle tree
    if (CheckMerkleBranch(coinbaseTx->GetHash(), vMerkleBranch, 0)
          != parentBlock.hashMerkleRoot)
        return error("Aux POW merkle root incorrect");

    // Check that there is at least one input.
    if (coinbaseTx->vin.empty())
        return error("Aux POW coinbase has no inputs");

    const CScript script = coinbaseTx->vin[0].scriptSig;

    // Check that the same work is not submitted twice to our chain.
    //

    const unsigned char* const mmHeaderBegin = pchMergedMiningHeader;
    const unsigned char* const mmHeaderEnd
        = mmHeaderBegin + sizeof (pchMergedMiningHeader);
    CScript::const_iterator pcHead =
        std::search(script.begin(), script.end(), mmHeaderBegin, mmHeaderEnd);

    CScript::const_iterator pc =
        std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end());

    if (pc == script.end())
        return error("Aux POW missing chain merkle root in parent coinbase");

    if (pcHead != script.end())
    {
        // Enforce only one chain merkle root by checking that a single instance of the merged
        // mining header exists just before.
        if (script.end() != std::search(pcHead + 1, script.end(),
                                        mmHeaderBegin, mmHeaderEnd))
            return error("Multiple merged mining headers in coinbase");
        if (pcHead + sizeof(pchMergedMiningHeader) != pc)
            return error("Merged mining header is not just before chain merkle root");
    }
    else
    {
        return error("Missing auxpow header");
    }

    // Ensure we are at a deterministic point in the merkle leaves by hashing
    // a nonce and our chain ID and comparing to the index.
    pc += vchRootHash.size();
    if (script.end() - pc < 8)
        return error("Aux POW missing chain merkle tree size and nonce in parent coinbase");

    const uint32_t nSize = DecodeLE32 (&pc[0]);
    const unsigned merkleHeight = vChainMerkleBranch.size ();
    if (nSize != (1u << merkleHeight))
        return error("Aux POW merkle branch size does not match parent coinbase");

    const uint32_t nNonce = DecodeLE32 (&pc[4]);
    if (nChainIndex != getExpectedIndex (nNonce, nChainId, merkleHeight))
        return error("Aux POW wrong index");

    return true;
}

int
CAuxPow::getExpectedIndex (uint32_t nNonce, int nChainId, unsigned h)
{
  // Choose a pseudo-random slot in the chain merkle tree
  // but have it be fixed for a size/nonce/chain combination.
  //
  // This prevents the same work from being used twice for the
  // same chain while reducing the chance that two chains clash
  // for the same slot.

  /* This computation can overflow the uint32 used.  This is not an issue,
     though, since we take the mod against a power-of-two in the end anyway.
     This also ensures that the computation is, actually, consistent
     even if done in 64 bits as it was in the past on some systems.
     Note that h is always <= 30 (enforced by the maximum allowed chain
     merkle branch length), so that 32 bits are enough for the computation.  */

  uint32_t rand = nNonce;
  rand = rand * 1103515245 + 12345;
  rand += nChainId;
  rand = rand * 1103515245 + 12345;

  return rand % (1u << h);
}

uint256
CAuxPow::CheckMerkleBranch (uint256 hash,
                            const std::vector<uint256>& vMerkleBranch,
                            int nIndex)
{
  if (nIndex == -1)
    return uint256 ();
  for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin ());
       it != vMerkleBranch.end (); ++it)
  {
    if (nIndex & 1)
      hash = Hash (it->begin (), it->end (), hash.begin (), hash.end ());
    else
      hash = Hash (hash.begin (), hash.end (), it->begin (), it->end ());
    nIndex >>= 1;
  }
  return hash;
}

std::unique_ptr<CAuxPow>
CAuxPow::createAuxPow (const CPureBlockHeader& header)
{
  assert (header.IsAuxpow ());

  /* Build a minimal coinbase script input for merge-mining.  */
  const uint256 blockHash = header.GetHash ();
  valtype inputData(blockHash.begin (), blockHash.end ());
  std::reverse (inputData.begin (), inputData.end ());
  inputData.push_back (1);
  inputData.insert (inputData.end (), 7, 0);

  /* Fake a parent-block coinbase with just the required input
     script and no outputs.  */
  CMutableTransaction coinbase;
  coinbase.vin.resize (1);
  coinbase.vin[0].prevout.SetNull ();
  coinbase.vin[0].scriptSig = (CScript () << inputData);
  assert (coinbase.vout.empty ());
  CTransactionRef coinbaseRef = MakeTransactionRef (coinbase);

  /* Build a fake parent block with the coinbase.  */
  CBlock parent;
  parent.nVersion = 1;
  parent.vtx.resize (1);
  parent.vtx[0] = coinbaseRef;
  parent.hashMerkleRoot = BlockMerkleRoot (parent);

  /* Construct the auxpow object.  */
  std::unique_ptr<CAuxPow> auxpow(new CAuxPow (std::move (coinbaseRef)));
  assert (auxpow->vMerkleBranch.empty ());
  assert (auxpow->vChainMerkleBranch.empty ());
  auxpow->nChainIndex = 0;
  auxpow->parentBlock = parent;

  return auxpow;
}

CPureBlockHeader&
CAuxPow::initAuxPow (CBlockHeader& header)
{
  /* Set auxpow flag right now, since we take the block hash below when creating
     the minimal auxpow for header.  */
  header.SetAuxpowVersion(true);

  std::unique_ptr<CAuxPow> apow = createAuxPow (header);
  CPureBlockHeader& result = apow->parentBlock;
  header.SetAuxpow (std::move (apow));

  return result;
}<commit_msg>fix hash in auxpow<commit_after>// Copyright (c) 2009-2010 Satoshi Nakamoto
// Copyright (c) 2011 Vince Durham
// Copyright (c) 2009-2014 The Bitcoin developers
// Copyright (c) 2014-2019 Daniel Kraft
// Distributed under the MIT/X11 software license, see the accompanying
// file license.txt or http://www.opensource.org/licenses/mit-license.php.

#include <auxpow.h>

#include <consensus/consensus.h>
#include <consensus/merkle.h>
#include <hash.h>
#include <primitives/block.h>
#include <script/script.h>
#include <util/strencodings.h>
#include <util/system.h>

#include <algorithm>

namespace
{

/**
 * Decodes a 32-bit little endian integer from raw bytes.
 */
uint32_t
DecodeLE32 (const unsigned char* bytes)
{
  uint32_t res = 0;
  for (int i = 0; i < 4; ++i)
    {
      res <<= 8;
      res |= bytes[3 - i];
    }
  return res;
}

} // anonymous namespace

bool
CAuxPow::check (const uint256& hashAuxBlock, int nChainId,
                const Consensus::Params& params) const
{
    if (params.fStrictChainId && parentBlock.GetChainId () == nChainId)
        return error("Aux POW parent has our chain ID");

    if (vChainMerkleBranch.size() > 30)
        return error("Aux POW chain merkle branch too long");

    // Check that the chain merkle root is in the coinbase
    const uint256 nRootHash
      = CheckMerkleBranch (hashAuxBlock, vChainMerkleBranch, nChainIndex);
    valtype vchRootHash(nRootHash.begin (), nRootHash.end ());
    std::reverse (vchRootHash.begin (), vchRootHash.end ()); // correct endian

    // Check that we are in the parent block merkle tree
    if (CheckMerkleBranch(coinbaseTx->GetHash(), vMerkleBranch, 0)
          != parentBlock.hashMerkleRoot)
        return error("Aux POW merkle root incorrect");

    // Check that there is at least one input.
    if (coinbaseTx->vin.empty())
        return error("Aux POW coinbase has no inputs");

    const CScript script = coinbaseTx->vin[0].scriptSig;

    // Check that the same work is not submitted twice to our chain.
    //

    const unsigned char* const mmHeaderBegin = pchMergedMiningHeader;
    const unsigned char* const mmHeaderEnd
        = mmHeaderBegin + sizeof (pchMergedMiningHeader);
    CScript::const_iterator pcHead =
        std::search(script.begin(), script.end(), mmHeaderBegin, mmHeaderEnd);

    CScript::const_iterator pc =
        std::search(script.begin(), script.end(), vchRootHash.begin(), vchRootHash.end());

    if (pc == script.end())
        return error("Aux POW missing chain merkle root in parent coinbase");

    if (pcHead != script.end())
    {
        // Enforce only one chain merkle root by checking that a single instance of the merged
        // mining header exists just before.
        if (script.end() != std::search(pcHead + 1, script.end(),
                                        mmHeaderBegin, mmHeaderEnd))
            return error("Multiple merged mining headers in coinbase");
        if (pcHead + sizeof(pchMergedMiningHeader) != pc)
            return error("Merged mining header is not just before chain merkle root");
    }
    else
    {
        return error("Missing auxpow header");
    }

    // Ensure we are at a deterministic point in the merkle leaves by hashing
    // a nonce and our chain ID and comparing to the index.
    pc += vchRootHash.size();
    if (script.end() - pc < 8)
        return error("Aux POW missing chain merkle tree size and nonce in parent coinbase");

    const uint32_t nSize = DecodeLE32 (&pc[0]);
    const unsigned merkleHeight = vChainMerkleBranch.size ();
    if (nSize != (1u << merkleHeight))
        return error("Aux POW merkle branch size does not match parent coinbase");

    const uint32_t nNonce = DecodeLE32 (&pc[4]);
    if (nChainIndex != getExpectedIndex (nNonce, nChainId, merkleHeight))
        return error("Aux POW wrong index");

    return true;
}

int
CAuxPow::getExpectedIndex (uint32_t nNonce, int nChainId, unsigned h)
{
  // Choose a pseudo-random slot in the chain merkle tree
  // but have it be fixed for a size/nonce/chain combination.
  //
  // This prevents the same work from being used twice for the
  // same chain while reducing the chance that two chains clash
  // for the same slot.

  /* This computation can overflow the uint32 used.  This is not an issue,
     though, since we take the mod against a power-of-two in the end anyway.
     This also ensures that the computation is, actually, consistent
     even if done in 64 bits as it was in the past on some systems.
     Note that h is always <= 30 (enforced by the maximum allowed chain
     merkle branch length), so that 32 bits are enough for the computation.  */

  uint32_t rand = nNonce;
  rand = rand * 1103515245 + 12345;
  rand += nChainId;
  rand = rand * 1103515245 + 12345;

  return rand % (1u << h);
}

uint256
CAuxPow::CheckMerkleBranch (uint256 hash,
                            const std::vector<uint256>& vMerkleBranch,
                            int nIndex)
{
  if (nIndex == -1)
    return uint256 ();
  for (std::vector<uint256>::const_iterator it(vMerkleBranch.begin ());
       it != vMerkleBranch.end (); ++it)
  {
    if (nIndex & 1)
      hash = Hash (*it, hash);
    else
      hash = Hash (hash, *it);
    nIndex >>= 1;
  }
  return hash;
}

std::unique_ptr<CAuxPow>
CAuxPow::createAuxPow (const CPureBlockHeader& header)
{
  assert (header.IsAuxpow ());

  /* Build a minimal coinbase script input for merge-mining.  */
  const uint256 blockHash = header.GetHash ();
  valtype inputData(blockHash.begin (), blockHash.end ());
  std::reverse (inputData.begin (), inputData.end ());
  inputData.push_back (1);
  inputData.insert (inputData.end (), 7, 0);

  /* Fake a parent-block coinbase with just the required input
     script and no outputs.  */
  CMutableTransaction coinbase;
  coinbase.vin.resize (1);
  coinbase.vin[0].prevout.SetNull ();
  coinbase.vin[0].scriptSig = (CScript () << inputData);
  assert (coinbase.vout.empty ());
  CTransactionRef coinbaseRef = MakeTransactionRef (coinbase);

  /* Build a fake parent block with the coinbase.  */
  CBlock parent;
  parent.nVersion = 1;
  parent.vtx.resize (1);
  parent.vtx[0] = coinbaseRef;
  parent.hashMerkleRoot = BlockMerkleRoot (parent);

  /* Construct the auxpow object.  */
  std::unique_ptr<CAuxPow> auxpow(new CAuxPow (std::move (coinbaseRef)));
  assert (auxpow->vMerkleBranch.empty ());
  assert (auxpow->vChainMerkleBranch.empty ());
  auxpow->nChainIndex = 0;
  auxpow->parentBlock = parent;

  return auxpow;
}

CPureBlockHeader&
CAuxPow::initAuxPow (CBlockHeader& header)
{
  /* Set auxpow flag right now, since we take the block hash below when creating
     the minimal auxpow for header.  */
  header.SetAuxpowVersion(true);

  std::unique_ptr<CAuxPow> apow = createAuxPow (header);
  CPureBlockHeader& result = apow->parentBlock;
  header.SetAuxpow (std::move (apow));

  return result;
}<|endoftext|>


<commit_before>/*
 * Copyright (c) 2011 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2004-2006 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: Nathan Binkert
 *          Ali Saidi
 */

#include <sstream>

#include "base/trace.hh"
#include "arch/utility.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/events.hh"
#include "kern/linux/printk.hh"
#include "kern/system_events.hh"
#include "sim/arguments.hh"
#include "sim/pseudo_inst.hh"
#include "sim/system.hh"

namespace Linux {

void
DebugPrintkEvent::process(ThreadContext *tc)
{
    if (DTRACE(DebugPrintf)) {
        std::stringstream ss;
        Arguments args(tc);
        Printk(ss, args);
        StringWrap name(tc->getSystemPtr()->name() + ".dprintk");
        DPRINTFN("%s", ss.str());
    }
    SkipFuncEvent::process(tc);
}

void
UDelayEvent::process(ThreadContext *tc)
{
    int arg_num  = 0;

    // Get the time in native size
    uint64_t time = TheISA::getArgument(tc, arg_num,  (uint16_t)-1, false);

    // convert parameter to ns
    if (argDivToNs)
        time /= argDivToNs;

    time *= argMultToNs;

    // Convert ns to ticks
    time *= SimClock::Int::ns;

    SkipFuncEvent::process(tc);

    PseudoInst::quiesceNs(tc, time);
}

} // namespace linux
<commit_msg>ARM: Fix multiplication error in udelay<commit_after>/*
 * Copyright (c) 2011 ARM Limited
 * All rights reserved
 *
 * The license below extends only to copyright in the software and shall
 * not be construed as granting a license to any other intellectual
 * property including but not limited to intellectual property relating
 * to a hardware implementation of the functionality of the software
 * licensed hereunder.  You may use the software subject to the license
 * terms below provided that you ensure that this notice is replicated
 * unmodified and in its entirety in all distributions of the software,
 * modified or unmodified, in source code or in binary form.
 *
 * Copyright (c) 2004-2006 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: Nathan Binkert
 *          Ali Saidi
 */

#include <sstream>

#include "base/trace.hh"
#include "arch/utility.hh"
#include "cpu/thread_context.hh"
#include "kern/linux/events.hh"
#include "kern/linux/printk.hh"
#include "kern/system_events.hh"
#include "sim/arguments.hh"
#include "sim/pseudo_inst.hh"
#include "sim/system.hh"

namespace Linux {

void
DebugPrintkEvent::process(ThreadContext *tc)
{
    if (DTRACE(DebugPrintf)) {
        std::stringstream ss;
        Arguments args(tc);
        Printk(ss, args);
        StringWrap name(tc->getSystemPtr()->name() + ".dprintk");
        DPRINTFN("%s", ss.str());
    }
    SkipFuncEvent::process(tc);
}

void
UDelayEvent::process(ThreadContext *tc)
{
    int arg_num  = 0;

    // Get the time in native size
    uint64_t time = TheISA::getArgument(tc, arg_num,  (uint16_t)-1, false);

    // convert parameter to ns
    if (argDivToNs)
        time /= argDivToNs;

    time *= argMultToNs;

    SkipFuncEvent::process(tc);

    PseudoInst::quiesceNs(tc, time);
}

} // namespace linux
<|endoftext|>


<commit_before>/*
 *  Copyright (C) 2004 Steve Harris, Uwe Koloska
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation; either version 2.1 of the
 *  License, or (at your option) any later version.
 *
 *  This 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 Lesser General Public License for more details.
 *
 *  $Id$
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <vector>

#include "lo/lo.h"
using namespace std;

int done = 0;

struct member {
    int pid;
    char hostname[128];
};

vector<member> members;

void error(int num, const char *m, const char *path);

int ping_handler(const char *path, const char *types, lo_arg ** argv,
                int argc, void *data, void *user_data);

int quit_handler(const char *path, const char *types, lo_arg ** argv,
                 int argc, void *data, void *user_data);

int main()
{
    /* make address for multicast ip
     * pick a port number for you by passing NULL as the last argument */

    lo_address t = lo_address_new("239.255.0.1", "7770");
    // lo_server multi = lo_server_new_multicast("drone", "7771", error);
    /* start a new server on port 7770 */
    lo_server_thread st = lo_server_thread_new_multicast("239.255.0.1", "7770", error);

    /* add method that will match the path /foo/bar, with two numbers, coerced
     * to float and int */
    lo_server_thread_add_method(st, "/ping", "fi", ping_handler, NULL);

    /* add method that will match the path /quit with no args */
    lo_server_thread_add_method(st, "/quit", "", quit_handler, NULL);

    lo_server_thread_start(st);

    while (!done) {
#ifdef WIN32
        Sleep(1);
#else
        usleep(1000000);
#endif
        char hostname[128] = "";

        gethostname(hostname, sizeof(hostname));

        int pid = getpid();
        cerr << "pid: " << pid << " || hostname : " << hostname << endl;
        lo_send(t, "/ping", "is", pid, hostname);
        // lo_send_from(t, st, now, "/foo/bar", "ff", 0.12345678f, 23.0f);
    }

    lo_server_thread_free(st);

    return 0;
}

void error(int num, const char *msg, const char *path)
{
    printf("liblo server error %d in path %s: %s\n", num, path, msg);
    fflush(stdout);
}

/* catch any incoming messages and display them. returning 1 means that the
 * message has not been fully handled and the server should try other methods */
int ping_handler(const char *path, const char *types, lo_arg ** argv,
                int argc, void *data, void *user_data)
{
    cerr << "PID: " << argv[0]->i << " || path : " << argv[1]->s << endl;
    /* example showing pulling the argument values out of the argv array */
    printf("%s <- f:%f, i:%d\n\n", path, argv[0]->f, argv[1]->i);
    fflush(stdout);

    return 0;
}

int quit_handler(const char *path, const char *types, lo_arg ** argv,
                 int argc, void *data, void *user_data)
{
    done = 1;
    printf("quiting\n\n");
    fflush(stdout);

    return 0;
}

/* vi:set ts=8 sts=4 sw=4: */
<commit_msg>maybe fix?<commit_after>/*
 *  Copyright (C) 2004 Steve Harris, Uwe Koloska
 *
 *  This program is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU Lesser General Public License as
 *  published by the Free Software Foundation; either version 2.1 of the
 *  License, or (at your option) any later version.
 *
 *  This 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 Lesser General Public License for more details.
 *
 *  $Id$
 */

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <iostream>
#include <vector>

#include "lo/lo.h"
using namespace std;

int done = 0;

struct member {
    int pid;
    char hostname[128];
};

vector<member> members;

void error(int num, const char *m, const char *path);

int ping_handler(const char *path, const char *types, lo_arg ** argv,
                int argc, void *data, void *user_data);

int quit_handler(const char *path, const char *types, lo_arg ** argv,
                 int argc, void *data, void *user_data);

int main()
{
    /* make address for multicast ip
     * pick a port number for you by passing NULL as the last argument */

    lo_address t = lo_address_new("localhost", "7770");
    // lo_server multi = lo_server_new_multicast("drone", "7771", error);
    /* start a new server on port 7770 */
    lo_server_thread st = lo_server_thread_new_multicast("239.255.0.1", "7770", error);

    /* add method that will match the path /foo/bar, with two numbers, coerced
     * to float and int */
    lo_server_thread_add_method(st, "/ping", "fi", ping_handler, NULL);

    /* add method that will match the path /quit with no args */
    lo_server_thread_add_method(st, "/quit", "", quit_handler, NULL);

    lo_server_thread_start(st);

    while (!done) {
#ifdef WIN32
        Sleep(1);
#else
        usleep(1000000);
#endif
        char hostname[128] = "";

        gethostname(hostname, sizeof(hostname));

        int pid = getpid();
        cerr << "pid: " << pid << " || hostname : " << hostname << endl;
        lo_send(t, "/ping", "is", pid, hostname);
        // lo_send_from(t, st, now, "/foo/bar", "ff", 0.12345678f, 23.0f);
    }

    lo_server_thread_free(st);

    return 0;
}

void error(int num, const char *msg, const char *path)
{
    printf("liblo server error %d in path %s: %s\n", num, path, msg);
    fflush(stdout);
}

/* catch any incoming messages and display them. returning 1 means that the
 * message has not been fully handled and the server should try other methods */
int ping_handler(const char *path, const char *types, lo_arg ** argv,
                int argc, void *data, void *user_data)
{
    cerr << "PID: " << argv[0]->i << " || path : " << argv[1]->s << endl;
    /* example showing pulling the argument values out of the argv array */
    printf("%s <- f:%f, i:%d\n\n", path, argv[0]->f, argv[1]->i);
    fflush(stdout);

    return 0;
}

int quit_handler(const char *path, const char *types, lo_arg ** argv,
                 int argc, void *data, void *user_data)
{
    done = 1;
    printf("quiting\n\n");
    fflush(stdout);

    return 0;
}

/* vi:set ts=8 sts=4 sw=4: */
<|endoftext|>