<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,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 mrs06.C
/// @brief Run and manage the DDR4 MRS06 loading
///
// *HWP HWP Owner: Brian Silver <bsilver@us.ibm.com>
// *HWP HWP Backup: Andre Marin <aamarin@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 1
// *HWP Consumed by: FSP:HB

#include <fapi2.H>

#include <mss.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace ddr4
{

///
/// @brief mrs06_data ctor
/// @param[in] a fapi2::TARGET_TYPE_DIMM target
/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
mrs06_data::mrs06_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
    iv_tccd_l(0)
{
    FAPI_TRY( mss::eff_vref_dq_train_value(i_target, &(iv_vrefdq_train_value[0])) );
    FAPI_TRY( mss::eff_vref_dq_train_range(i_target, &(iv_vrefdq_train_range[0])) );
    FAPI_TRY( mss::eff_vref_dq_train_enable(i_target, &(iv_vrefdq_train_enable[0])) );
    FAPI_TRY( mss::eff_dram_tccd_l(i_target, iv_tccd_l) );

    o_rc = fapi2::FAPI2_RC_SUCCESS;
    return;

fapi_try_exit:
    o_rc = fapi2::current_err;
    FAPI_ERR("unable to get attributes for mrs0");
    return;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs06
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs06(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                        ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Check to make sure our ctor worked ok
    mrs06_data l_data( i_target, fapi2::current_err );
    FAPI_TRY( fapi2::current_err, "Unable to construct MRS06 data from attributes");
    FAPI_TRY( mrs06(i_target, l_data, io_inst, i_rank) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs06, data object as input
/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[in] i_data an mrs06_data object, filled in
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                        const mrs06_data& i_data,
                        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{

    constexpr uint64_t VREFDQ_TRAIN_LENGTH = 6;
    constexpr uint64_t VREFDQ_TRAIN_START = 7;
    constexpr uint64_t TCCD_L_LENGTH = 3;
    constexpr uint64_t TCCD_L_START = 7;

    constexpr uint64_t LOWEST_TCCD = 4;
    constexpr uint64_t TCCD_COUNT = 5;
    //                                             4      5     6      7       8
    constexpr uint8_t tccd_l_map[TCCD_COUNT] = { 0b000, 0b001, 0b010, 0b011, 0b100 };

    fapi2::buffer<uint8_t> l_tccd_l_buffer;
    fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;

    FAPI_ASSERT((i_data.iv_tccd_l >= LOWEST_TCCD) && (i_data.iv_tccd_l < (LOWEST_TCCD + TCCD_COUNT)),
                fapi2::MSS_BAD_MR_PARAMETER()
                .set_MR_NUMBER(6)
                .set_PARAMETER(TCCD)
                .set_PARAMETER_VALUE(i_data.iv_tccd_l)
                .set_DIMM_IN_ERROR(i_target),
                "Bad value for TCCD: %d (%s)", i_data.iv_tccd_l, mss::c_str(i_target));

    l_tccd_l_buffer = tccd_l_map[i_data.iv_tccd_l - LOWEST_TCCD];
    l_vrefdq_train_value_buffer = i_data.iv_vrefdq_train_value[mss::index(i_rank)];

    FAPI_INF("MR6 rank %d attributes: TRAIN_V: 0x%x(0x%x), TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x(0x%x)", i_rank,
             i_data.iv_vrefdq_train_value[mss::index(i_rank)], uint8_t(l_vrefdq_train_value_buffer),
             i_data.iv_vrefdq_train_range[mss::index(i_rank)],
             i_data.iv_vrefdq_train_enable[mss::index(i_rank)], i_data.iv_tccd_l, uint8_t(l_tccd_l_buffer));

    mss::swizzle<A0, VREFDQ_TRAIN_LENGTH, VREFDQ_TRAIN_START>(l_vrefdq_train_value_buffer, io_inst.arr0);
    io_inst.arr0.writeBit<A6>(i_data.iv_vrefdq_train_range[mss::index(i_rank)]);
    io_inst.arr0.writeBit<A7>(i_data.iv_vrefdq_train_enable[mss::index(i_rank)]);
    mss::swizzle<A10, TCCD_L_LENGTH, TCCD_L_START>(l_tccd_l_buffer, io_inst.arr0);

    FAPI_INF("MR6: 0x%016llx", uint64_t(io_inst.arr0));

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function for mrs06_decode
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank the rank in question
/// @param[out] o_vrefdq_train_range the vrefdq training range setting
/// @param[out] o_vrefdq_train_enable the vrefdq training enable setting
/// @param[out] o_tccd_l_buffer the tccd_l setting
/// @param[out] o_vrefdq_train_value_buffer the vrefdq training value
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                                      const uint64_t i_rank,
                                      uint8_t& o_vrefdq_train_range,
                                      uint8_t& o_vrefdq_train_enable,
                                      fapi2::buffer<uint8_t>& o_tccd_l_buffer,
                                      fapi2::buffer<uint8_t>& o_vrefdq_train_value_buffer)
{
    o_tccd_l_buffer = 0;
    o_vrefdq_train_value_buffer = 0;

    mss::swizzle<2, 6, A5>(i_inst.arr0, o_vrefdq_train_value_buffer);
    o_vrefdq_train_range = i_inst.arr0.getBit<A6>();
    o_vrefdq_train_enable = i_inst.arr0.getBit<A7>();
    mss::swizzle<5, 3, A12>(i_inst.arr0, o_tccd_l_buffer);

    FAPI_INF("MR6 rank %d decode: TRAIN_V: 0x%x, TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x", i_rank,
             uint8_t(o_vrefdq_train_value_buffer), o_vrefdq_train_range,
             o_vrefdq_train_enable, uint8_t(o_tccd_l_buffer));

    return FAPI2_RC_SUCCESS;
}

///
/// @brief Given a CCS instruction which contains address bits with an encoded MRS6,
/// decode and trace the contents
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                               const uint64_t i_rank)
{
    fapi2::buffer<uint8_t> l_tccd_l_buffer;
    fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;
    uint8_t l_vrefdq_train_range = 0;
    uint8_t l_vrefdq_train_enable = 0;

    return mrs06_decode_helper(i_inst, i_rank, l_vrefdq_train_range, l_vrefdq_train_enable,
                               l_tccd_l_buffer, l_vrefdq_train_value_buffer);
}

fapi2::ReturnCode (*mrs06_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const mrs06_data& i_data,
        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
        const uint64_t i_rank) = &mrs06;

fapi2::ReturnCode (*mrs06_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
                                        const uint64_t i_rank) = &mrs06_decode;

} // ns ddr4
} // ns mss
<commit_msg>L3 draminit and mss_lib<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/dimm/ddr4/mrs06.C $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,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 mrs06.C
/// @brief Run and manage the DDR4 MRS06 loading
///
// *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 <mss.H>
#include <lib/dimm/ddr4/mrs_load_ddr4.H>

using fapi2::TARGET_TYPE_MCBIST;
using fapi2::TARGET_TYPE_DIMM;

using fapi2::FAPI2_RC_SUCCESS;

namespace mss
{

namespace ddr4
{

///
/// @brief mrs06_data ctor
/// @param[in] a fapi2::TARGET_TYPE_DIMM target
/// @param[out] fapi2::ReturnCode FAPI2_RC_SUCCESS iff ok
///
mrs06_data::mrs06_data( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target, fapi2::ReturnCode& o_rc ):
    iv_tccd_l(0)
{
    FAPI_TRY( mss::eff_vref_dq_train_value(i_target, &(iv_vrefdq_train_value[0])), "Error in mrs06_data()" );
    FAPI_TRY( mss::eff_vref_dq_train_range(i_target, &(iv_vrefdq_train_range[0])), "Error in mrs06_data()" );
    FAPI_TRY( mss::eff_vref_dq_train_enable(i_target, &(iv_vrefdq_train_enable[0])), "Error in mrs06_data()" );
    FAPI_TRY( mss::eff_dram_tccd_l(i_target, iv_tccd_l), "Error in mrs06_data()" );

    o_rc = fapi2::FAPI2_RC_SUCCESS;
    return;

fapi_try_exit:
    o_rc = fapi2::current_err;
    FAPI_ERR("%s unable to get attributes for mrs06", mss::c_str(i_target));
    return;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs06
/// @param[in] i_target a fapi2::Target<TARGET_TYPE_DIMM>
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs06(const fapi2::Target<TARGET_TYPE_DIMM>& i_target,
                        ccs::instruction_t<TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{
    // Check to make sure our ctor worked ok
    mrs06_data l_data( i_target, fapi2::current_err );
    FAPI_TRY( fapi2::current_err, "%s Unable to construct MRS06 data from attributes", mss::c_str(i_target) );
    FAPI_TRY( mrs06(i_target, l_data, io_inst, i_rank) );

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Configure the ARR0 of the CCS instruction for mrs06, data object as input
/// @param[in] i_target a fapi2::Target<fapi2::TARGET_TYPE_DIMM>
/// @param[in] i_data an mrs06_data object, filled in
/// @param[in,out] io_inst the instruction to fixup
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff OK
///
fapi2::ReturnCode mrs06(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                        const mrs06_data& i_data,
                        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
                        const uint64_t i_rank)
{

    constexpr uint64_t VREFDQ_TRAIN_LENGTH = 6;
    constexpr uint64_t VREFDQ_TRAIN_START = 7;
    constexpr uint64_t TCCD_L_LENGTH = 3;
    constexpr uint64_t TCCD_L_START = 7;

    constexpr uint64_t LOWEST_TCCD = 4;
    constexpr uint64_t TCCD_COUNT = 5;
    //                                             4      5     6      7       8
    constexpr uint8_t tccd_l_map[TCCD_COUNT] = { 0b000, 0b001, 0b010, 0b011, 0b100 };

    fapi2::buffer<uint8_t> l_tccd_l_buffer;
    fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;

    FAPI_ASSERT((i_data.iv_tccd_l >= LOWEST_TCCD) && (i_data.iv_tccd_l < (LOWEST_TCCD + TCCD_COUNT)),
                fapi2::MSS_BAD_MR_PARAMETER()
                .set_MR_NUMBER(6)
                .set_PARAMETER(TCCD)
                .set_PARAMETER_VALUE(i_data.iv_tccd_l)
                .set_DIMM_IN_ERROR(i_target),
                "Bad value for TCCD: %d (%s)",
                i_data.iv_tccd_l,
                mss::c_str(i_target));

    l_tccd_l_buffer = tccd_l_map[i_data.iv_tccd_l - LOWEST_TCCD];
    l_vrefdq_train_value_buffer = i_data.iv_vrefdq_train_value[mss::index(i_rank)];

    FAPI_INF("%s MR6 rank %d attributes: TRAIN_V: 0x%x(0x%x), TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x(0x%x)",
             mss::c_str(i_target), i_rank, i_data.iv_vrefdq_train_value[mss::index(i_rank)],
             uint8_t(l_vrefdq_train_value_buffer), i_data.iv_vrefdq_train_range[mss::index(i_rank)],
             i_data.iv_vrefdq_train_enable[mss::index(i_rank)], i_data.iv_tccd_l, uint8_t(l_tccd_l_buffer));

    mss::swizzle<A0, VREFDQ_TRAIN_LENGTH, VREFDQ_TRAIN_START>(l_vrefdq_train_value_buffer, io_inst.arr0);
    io_inst.arr0.writeBit<A6>(i_data.iv_vrefdq_train_range[mss::index(i_rank)]);
    io_inst.arr0.writeBit<A7>(i_data.iv_vrefdq_train_enable[mss::index(i_rank)]);
    mss::swizzle<A10, TCCD_L_LENGTH, TCCD_L_START>(l_tccd_l_buffer, io_inst.arr0);

    FAPI_INF("%s MR6: 0x%016llx", mss::c_str(i_target), uint64_t(io_inst.arr0));

    return fapi2::FAPI2_RC_SUCCESS;

fapi_try_exit:
    return fapi2::current_err;
}

///
/// @brief Helper function for mrs06_decode
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank the rank in question
/// @param[out] o_vrefdq_train_range the vrefdq training range setting
/// @param[out] o_vrefdq_train_enable the vrefdq training enable setting
/// @param[out] o_tccd_l_buffer the tccd_l setting
/// @param[out] o_vrefdq_train_value_buffer the vrefdq training value
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs06_decode_helper(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                                      const uint64_t i_rank,
                                      uint8_t& o_vrefdq_train_range,
                                      uint8_t& o_vrefdq_train_enable,
                                      fapi2::buffer<uint8_t>& o_tccd_l_buffer,
                                      fapi2::buffer<uint8_t>& o_vrefdq_train_value_buffer)
{
    o_tccd_l_buffer = 0;
    o_vrefdq_train_value_buffer = 0;

    mss::swizzle<2, 6, A5>(i_inst.arr0, o_vrefdq_train_value_buffer);
    o_vrefdq_train_range = i_inst.arr0.getBit<A6>();
    o_vrefdq_train_enable = i_inst.arr0.getBit<A7>();
    mss::swizzle<5, 3, A12>(i_inst.arr0, o_tccd_l_buffer);

    FAPI_INF("MR6 rank %d decode: TRAIN_V: 0x%x, TRAIN_R: 0x%x, TRAIN_E: 0x%x, TCCD_L: 0x%x",
             i_rank, uint8_t(o_vrefdq_train_value_buffer), o_vrefdq_train_range,
             o_vrefdq_train_enable, uint8_t(o_tccd_l_buffer));

    return FAPI2_RC_SUCCESS;
}

///
/// @brief Given a CCS instruction which contains address bits with an encoded MRS6,
/// decode and trace the contents
/// @param[in] i_inst the CCS instruction
/// @param[in] i_rank the rank in question
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode mrs06_decode(const ccs::instruction_t<TARGET_TYPE_MCBIST>& i_inst,
                               const uint64_t i_rank)
{
    fapi2::buffer<uint8_t> l_tccd_l_buffer;
    fapi2::buffer<uint8_t> l_vrefdq_train_value_buffer;
    uint8_t l_vrefdq_train_range = 0;
    uint8_t l_vrefdq_train_enable = 0;

    return mrs06_decode_helper(i_inst, i_rank, l_vrefdq_train_range, l_vrefdq_train_enable,
                               l_tccd_l_buffer, l_vrefdq_train_value_buffer);
}

fapi2::ReturnCode (*mrs06_data::make_ccs_instruction)(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const mrs06_data& i_data,
        ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& io_inst,
        const uint64_t i_rank) = &mrs06;

fapi2::ReturnCode (*mrs06_data::decode)(const ccs::instruction_t<fapi2::TARGET_TYPE_MCBIST>& i_inst,
                                        const uint64_t i_rank) = &mrs06_decode;

} // ns ddr4
} // ns mss
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,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 spd_factory.H
/// @brief SPD factory and functions
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP

#ifndef _MSS_SPD_FACTORY_H_
#define _MSS_SPD_FACTORY_H_

// std lib
#include <cstdint>
#include <map>
#include <memory>

// fapi2
#include <fapi2.H>
#include <fapi2_spd_access.H>

// mss lib
#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
#include <generic/memory/lib/utils/find.H>

namespace mss
{
namespace spd
{

///
/// @brief       Decodes SPD Revision encoding level
/// @param[in]   i_target dimm target
/// @param[in]   i_spd_data SPD data
/// @param[out]  o_value encoding revision num
/// @return      FAPI2_RC_SUCCESS if okay
/// @note        Decodes SPD Byte 1 (3~0).
/// @note        Item JC-45-2220.01x
/// @note        Page 14-15
/// @note        DDR4 SPD Document Release 3
///
fapi2::ReturnCode rev_encoding_level(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                     const std::vector<uint8_t>& i_spd_data,
                                     uint8_t& o_value);
///
/// @brief       Decodes SPD Revision additions level
/// @param[in]   i_target dimm target
/// @param[in]   i_spd_data SPD blob
/// @param[out]  o_value additions revision num
/// @return      FAPI2_RC_SUCCESS if okay
/// @note        Decodes SPD Byte 1 (bits 7~4).
/// @note        Item JC-45-2220.01x
/// @note        Page 14-15
/// @note        DDR4 SPD Document Release 3
///
fapi2::ReturnCode rev_additions_level(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                      const std::vector<uint8_t>& i_spd_data,
                                      uint8_t& o_value);

///
/// @brief      Decodes hybrid type (whether or not the DIMM is a hybrid) from SPD
/// @param[in]  i_target dimm target
/// @param[in]  i_spd_data SPD data
/// @param[out] o_value hybrid
/// @return     FAPI2_RC_SUCCESS if okay
/// @note       Decodes SPD Byte 3 (bit 7)
/// @note       Item JC-45-2220.01x
/// @note       Page 17
/// @note       DDR4 SPD Document Release 3
///
fapi2::ReturnCode hybrid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                         const std::vector<uint8_t>& i_spd_data,
                         uint8_t& o_value);

///
/// @brief      Decodes hybrid type (hybrid DIMM type) from SPD
/// @param[in]  i_target dimm target
/// @param[in]  i_spd_data SPD data
/// @param[out] o_value hybrid module type
/// @return     FAPI2_RC_SUCCESS if okay
/// @note       Decodes SPD Byte 3 (bits 6~4)
/// @note       Item JC-45-2220.01x
/// @note       Page 17
/// @note       DDR4 SPD Document Release 3
///
fapi2::ReturnCode hybrid_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                              const std::vector<uint8_t>& i_spd_data,
                              uint8_t& o_value);

///
/// @brief      Decodes base module type (DIMM type) from SPD
/// @param[in]  i_target dimm target
/// @param[in]  i_spd_data SPD data
/// @param[out] o_value base module type
/// @return     FAPI2_RC_SUCCESS if okay
/// @note       Decodes SPD Byte 3 (bits 3~0)
/// @note       Item JC-45-2220.01x
/// @note       Page 17
/// @note       DDR4 SPD Document Release 3
///
fapi2::ReturnCode base_module_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                   const std::vector<uint8_t>& i_spd_data,
                                   uint8_t& o_value);
///
/// @brief       Decodes DRAM Device Type
/// @param[in]   i_target dimm target
/// @param[out]  o_value dram device type enumeration
/// @return      FAPI2_RC_SUCCESS if okay
/// @note        Decodes SPD Byte 2
/// @note        Item JC-45-2220.01x
/// @note        Page 16
/// @note        DDR4 SPD Document Release 3
///
fapi2::ReturnCode dram_device_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                   const std::vector<uint8_t>& i_spd_data,
                                   uint8_t& o_value);

///
/// @brief       Wrapper function for finding the raw card
/// @param[in]   i_target the dimm target
/// @param[in]   i_dimm_type
/// @param[in]   i_ref_raw_card_rev for FFDC
/// @param[in]   i_map raw card map
/// @return      rcw_settings vector of rcw settings
/// @note        This specialization is suited for creating a cache with custom
///              SPD data (e.g. testing custom SPD).
///
rcw_settings find_raw_card( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                            const uint64_t i_dimm_type,
                            const uint8_t i_ref_raw_card_rev,
                            const std::vector<std::pair<uint8_t, rcw_settings> > i_map);

///
/// @brief Decodes reference raw card
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 130 (Bits 7~0)
/// @note Item JEDEC Standard No. 21-C
/// @note DDR4 SPD Document Release 2
/// @Note Page 4.1.2.12 - 49
///
fapi2::ReturnCode reference_raw_card(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                     const std::vector<uint8_t>& i_spd_data,
                                     uint8_t& o_output);

///
/// @brief Retrieve current raw card settings
/// based on dimm type and raw card reference rev
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_raw_card raw card settings
/// @return FAPI2_RC_SUCCESS if okay
///
fapi2::ReturnCode raw_card_factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                   const std::vector<uint8_t>& i_spd_data,
                                   rcw_settings& o_raw_card);

///
/// @brief       Object factory to select correct decoder
/// @param[in]   i_target dimm target
/// @param[in]   i_spd_data SPD data
/// @param[out]  o_fact_obj shared pointer to the factory object
/// @return      FAPI2_RC_SUCCESS if okay
/// @note        Factory dependent on SPD revision & dimm type
///
fapi2::ReturnCode factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                          const std::vector<uint8_t>& i_spd_data,
                          std::shared_ptr<decoder>& o_fact_obj);

///
/// @brief Determines & sets effective config for number of master ranks per dimm
/// @param[in] i_target DIMM fapi2::Target
/// @param[in] i_pDecoder shared_ptr to SPD decoder
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note This is done after the SPD cache is configured so that it can reflect the results of the
/// factory and we don't need to worry about SPD versions. This is expressly different than the dram and dimm setters
///
fapi2::ReturnCode master_ranks_per_dimm_setter(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const std::shared_ptr<decoder>& i_pDecoder);

///
/// @brief       Creates factory object & SPD data caches
/// @tparam T    fapi2::TargetType, MCA, MCS, MCBIST, PROC_CHIP are possible TargetTypes
/// @param[in]   i_target the fapi2 target to find DIMMs on
/// @param[out]  o_factory_caches vector of factory objects
/// @param[in]   i_pDecoder optional input decoder to insert custom decoder (nullptr default)
/// @return      FAPI2_RC_SUCCESS if okay
///
template<fapi2::TargetType T>
fapi2::ReturnCode populate_decoder_caches(const fapi2::Target<T>& i_target,
        std::vector< std::shared_ptr<decoder> >& o_factory_caches,
        const std::shared_ptr<decoder>& i_pDecoder = nullptr)
{
    // Input decoder for this version of populating cache would get overriden
    // so I don't bother with it in this specialization
    std::shared_ptr<decoder> l_pDecoder;

    for( const auto& l_dimm : find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
    {
        size_t l_size = 0;
        FAPI_TRY( fapi2::getSPD(l_dimm, nullptr, l_size),
                  "%s. Failed to retrieve SPD blob size", mss::c_str(i_target) );

        {
            // "Container" for SPD data
            std::vector<uint8_t> l_spd(l_size);

            // Retrieve SPD data
            FAPI_TRY( fapi2::getSPD(l_dimm, l_spd.data(), l_size),
                      "%s. Failed to retrieve SPD data", mss::c_str(i_target) );

            // Retrieve factory object instance & populate spd data for that instance
            FAPI_TRY( factory(l_dimm, l_spd, l_pDecoder),
                      "%s. Failed SPD factory, could not instantiate decoder object", mss::c_str(i_target) );

            // Populate spd caches
            o_factory_caches.push_back( l_pDecoder );
        }

        // Populate some of the DIMM attributes early. This allows the following code to make
        // decisions based on DIMM information. Expressly done after the factory has decided on the SPD version
        FAPI_TRY( master_ranks_per_dimm_setter(l_dimm, l_pDecoder),
                  "%s. Failed master_ranks_per_dimm_setter()", mss::c_str(i_target) );

    }// end dimm

fapi_try_exit:
    return fapi2::current_err;
}

}// spd

///
/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD
/// @param[in] i_pDecoder the SPD decoder
/// @param[out] o_value tCKmin value in ps
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode get_tckmin(const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
                             uint64_t& o_value);

///
/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD
/// @param[in] i_pDecoder SPD decoder
/// @param[out] o_value tCKmax value in ps
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode get_tckmax(const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
                             uint64_t& o_value);

}// mss

#endif //_MSS_SPD_FACTORY_H_
<commit_msg>Add address translation (xlate) support for 4Gbx8 and unit tests<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/chips/p9/procedures/hwp/memory/lib/spd/spd_factory.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,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 spd_factory.H
/// @brief SPD factory and functions
///
// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Stephen Glancy <sglancy@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP

#ifndef _MSS_SPD_FACTORY_H_
#define _MSS_SPD_FACTORY_H_

// std lib
#include <cstdint>
#include <map>
#include <memory>

// fapi2
#include <fapi2.H>
#include <fapi2_spd_access.H>

// mss lib
#include <generic/memory/lib/spd/common/ddr4/spd_decoder_ddr4.H>
#include <generic/memory/lib/utils/find.H>

namespace mss
{
namespace spd
{

///
/// @brief Decodes SPD Revision encoding level
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_value encoding revision num
/// @return FAPI2_RC_SUCCESS if okay
/// @note Decodes SPD Byte 1 (3~0).
/// @note Item JC-45-2220.01x
/// @note Page 14-15
/// @note DDR4 SPD Document Release 3
///
fapi2::ReturnCode rev_encoding_level(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                     const std::vector<uint8_t>& i_spd_data,
                                     uint8_t& o_value);
///
/// @brief Decodes SPD Revision additions level
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD blob
/// @param[out] o_value additions revision num
/// @return FAPI2_RC_SUCCESS if okay
/// @note Decodes SPD Byte 1 (bits 7~4).
/// @note Item JC-45-2220.01x
/// @note Page 14-15
/// @note DDR4 SPD Document Release 3
///
fapi2::ReturnCode rev_additions_level(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                      const std::vector<uint8_t>& i_spd_data,
                                      uint8_t& o_value);

///
/// @brief Decodes hybrid type (whether or not the DIMM is a hybrid) from SPD
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_value hybrid
/// @return FAPI2_RC_SUCCESS if okay
/// @note Decodes SPD Byte 3 (bit 7)
/// @note Item JC-45-2220.01x
/// @note Page 17
/// @note DDR4 SPD Document Release 3
///
fapi2::ReturnCode hybrid(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                         const std::vector<uint8_t>& i_spd_data,
                         uint8_t& o_value);

///
/// @brief Decodes hybrid type (hybrid DIMM type) from SPD
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_value hybrid module type
/// @return FAPI2_RC_SUCCESS if okay
/// @note Decodes SPD Byte 3 (bits 6~4)
/// @note Item JC-45-2220.01x
/// @note Page 17
/// @note DDR4 SPD Document Release 3
///
fapi2::ReturnCode hybrid_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                              const std::vector<uint8_t>& i_spd_data,
                              uint8_t& o_value);

///
/// @brief Decodes base module type (DIMM type) from SPD
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_value base module type
/// @return FAPI2_RC_SUCCESS if okay
/// @note Decodes SPD Byte 3 (bits 3~0)
/// @note Item JC-45-2220.01x
/// @note Page 17
/// @note DDR4 SPD Document Release 3
///
fapi2::ReturnCode base_module_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                   const std::vector<uint8_t>& i_spd_data,
                                   uint8_t& o_value);
///
/// @brief Decodes DRAM Device Type
/// @param[in] i_target dimm target
/// @param[out] o_value dram device type enumeration
/// @return FAPI2_RC_SUCCESS if okay
/// @note Decodes SPD Byte 2
/// @note Item JC-45-2220.01x
/// @note Page 16
/// @note DDR4 SPD Document Release 3
///
fapi2::ReturnCode dram_device_type(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                   const std::vector<uint8_t>& i_spd_data,
                                   uint8_t& o_value);

///
/// @brief Wrapper function for finding the raw card -- helper for testing
/// @param[in] i_target the dimm target
/// @param[in] i_dimm_type
/// @param[in] i_ref_raw_card_rev for FFDC
/// @param[in] i_mrw_supported_rc
/// @param[in] i_map raw card map
/// @param[out] o_rcw raw card setting
/// @return rcw_settings vector of rcw settings
/// @note This specialization is suited for creating a cache with custom
/// SPD data (e.g. testing custom SPD).
/// @note MRW attributes are read-only, this function provides a mechanism to test
/// different code paths.
///
fapi2::ReturnCode find_raw_card_helper( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                        const uint64_t i_dimm_type,
                                        const uint8_t i_ref_raw_card_rev,
                                        const uint8_t i_mrw_supported_rc,
                                        const std::vector<std::pair<uint8_t, rcw_settings> >& i_map,
                                        rcw_settings& o_raw_card);

///
/// @brief Wrapper function for finding the raw card
/// @param[in] i_target the dimm target
/// @param[in] i_dimm_type
/// @param[in] i_ref_raw_card_rev for FFDC
/// @param[in] i_map raw card map
/// @param[out] o_rcw raw card setting
/// @return rcw_settings vector of rcw settings
/// @note This specialization is suited for creating a cache with custom
/// SPD data (e.g. testing custom SPD).
///
fapi2::ReturnCode find_raw_card( const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                 const uint64_t i_dimm_type,
                                 const uint8_t i_ref_raw_card_rev,
                                 const std::vector<std::pair<uint8_t, rcw_settings> >& i_map,
                                 rcw_settings& o_raw_card);

///
/// @brief Decodes reference raw card
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_output encoding from SPD
/// @return FAPI2_RC_SUCCESS if okay
/// @note SPD Byte 130 (Bits 7~0)
/// @note Item JEDEC Standard No. 21-C
/// @note DDR4 SPD Document Release 2
/// @Note Page 4.1.2.12 - 49
///
fapi2::ReturnCode reference_raw_card(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                     const std::vector<uint8_t>& i_spd_data,
                                     uint8_t& o_output);

///
/// @brief Retrieve current raw card settings
/// based on dimm type and raw card reference rev
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_raw_card raw card settings
/// @return FAPI2_RC_SUCCESS if okay
///
fapi2::ReturnCode raw_card_factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                                   const std::vector<uint8_t>& i_spd_data,
                                   rcw_settings& o_raw_card);

///
/// @brief Object factory to select correct decoder
/// @param[in] i_target dimm target
/// @param[in] i_spd_data SPD data
/// @param[out] o_fact_obj shared pointer to the factory object
/// @return FAPI2_RC_SUCCESS if okay
/// @note Factory dependent on SPD revision & dimm type
///
fapi2::ReturnCode factory(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
                          const std::vector<uint8_t>& i_spd_data,
                          std::shared_ptr<decoder>& o_fact_obj);

///
/// @brief Determines & sets effective config for number of master ranks per dimm
/// @param[in] i_target DIMM fapi2::Target
/// @param[in] i_pDecoder shared_ptr to SPD decoder
/// @return fapi2::FAPI2_RC_SUCCESS if okay
/// @note This is done after the SPD cache is configured so that it can reflect the results of the
/// factory and we don't need to worry about SPD versions. This is expressly different than the dram and dimm setters
///
fapi2::ReturnCode master_ranks_per_dimm_setter(const fapi2::Target<fapi2::TARGET_TYPE_DIMM>& i_target,
        const std::shared_ptr<decoder>& i_pDecoder);

///
/// @brief Creates factory object & SPD data caches
/// @tparam T fapi2::TargetType, MCA, MCS, MCBIST, PROC_CHIP are possible TargetTypes
/// @param[in] i_target the fapi2 target to find DIMMs on
/// @param[out] o_factory_caches vector of factory objects
/// @param[in] i_pDecoder optional input decoder to insert custom decoder (nullptr default)
/// @return FAPI2_RC_SUCCESS if okay
///
template<fapi2::TargetType T>
fapi2::ReturnCode populate_decoder_caches(const fapi2::Target<T>& i_target,
        std::vector< std::shared_ptr<decoder> >& o_factory_caches,
        const std::shared_ptr<decoder>& i_pDecoder = nullptr)
{
    // Input decoder for this version of populating cache would get overriden
    // so I don't bother with it in this specialization
    std::shared_ptr<decoder> l_pDecoder;

    for( const auto& l_dimm : find_targets<fapi2::TARGET_TYPE_DIMM>(i_target) )
    {
        size_t l_size = 0;
        FAPI_TRY( fapi2::getSPD(l_dimm, nullptr, l_size),
                  "%s. Failed to retrieve SPD blob size", mss::c_str(i_target) );

        {
            // "Container" for SPD data
            std::vector<uint8_t> l_spd(l_size);

            // Retrieve SPD data
            FAPI_TRY( fapi2::getSPD(l_dimm, l_spd.data(), l_size),
                      "%s. Failed to retrieve SPD data", mss::c_str(i_target) );

            // Retrieve factory object instance & populate spd data for that instance
            FAPI_TRY( factory(l_dimm, l_spd, l_pDecoder),
                      "%s. Failed SPD factory, could not instantiate decoder object", mss::c_str(i_target) );

            // Populate spd caches
            o_factory_caches.push_back( l_pDecoder );
        }

        // Populate some of the DIMM attributes early. This allows the following code to make
        // decisions based on DIMM information. Expressly done after the factory has decided on the SPD version
        FAPI_TRY( master_ranks_per_dimm_setter(l_dimm, l_pDecoder),
                  "%s. Failed master_ranks_per_dimm_setter()", mss::c_str(i_target) );

    }// end dimm

fapi_try_exit:
    return fapi2::current_err;
}

}// spd

///
/// @brief Retrieves SDRAM Minimum Cycle Time (tCKmin) from SPD
/// @param[in] i_pDecoder the SPD decoder
/// @param[out] o_value tCKmin value in ps
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode get_tckmin(const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
                             uint64_t& o_value);

///
/// @brief Retrieves SDRAM Maximum Cycle Time (tCKmax) from SPD
/// @param[in] i_pDecoder SPD decoder
/// @param[out] o_value tCKmax value in ps
/// @return FAPI2_RC_SUCCESS iff ok
///
fapi2::ReturnCode get_tckmax(const std::shared_ptr<mss::spd::decoder>& i_pDecoder,
                             uint64_t& o_value);

}// mss

#endif //_MSS_SPD_FACTORY_H_
<|endoftext|>


<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/shared/mss_generic_consts.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,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                                                     */
<commit_msg>Add SPD reader and traits DDR4 def<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/import/generic/memory/lib/utils/shared/mss_generic_consts.H $ */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2018,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 mss_generic_consts.H
/// @brief Common constants to be shared
///

// *HWP HWP Owner: Andre Marin <aamarin@us.ibm.com>
// *HWP HWP Backup: Louis Stermole <stermole@us.ibm.com>
// *HWP Team: Memory
// *HWP Level: 3
// *HWP Consumed by: HB:FSP

#ifndef _MSS_GENERIC_CONSTS_H_
#define _MSS_GENERIC_CONSTS_H_

#include <cstdint>

namespace mss
{

///
/// @brief FFDC generic codes
///
enum generic_ffdc_codes
{
    // Starting at 0x1%%% to avoid
    // any collisions with values
    // from controller specific ffdc codes
    SET_ATTR_DIMM_TYPE = 0x1000,
    SET_ATTR_DRAM_GEN = 0x1001,
    SET_ATTR_HYBRID = 0x1002,
    SET_ATTR_HYBRID_MEDIA = 0x1003,
    SET_ATTR_MASTER_RANKS = 0x1004,
    PRE_DATA_ENGINE_CTOR = 0x1005,
    EXTRACT_SPD_FLD = 0x1006,
    SPD_READER = 0x1007,
    BASE_CNFG_MAKE_OBJ = 0x1008,
    DIMM_MODULE_MAKE_OBJ = 0x1009,
    CREATE_BASE_CNFG_FACTORY = 0x100A,
    CREATE_MODULE_FACTORY = 0x100B,
    GET_TIMEBASES_FTB = 0x100F,
    GET_TIMEBASES_MTB = 0x1010,
};

///
/// @brief DRAM generation selector
///
enum device_type
{
    DDR4 = 0x0c,
};

enum rev : uint8_t
{
    V1_0 = 0x10, ///< represents Rev 1.0
    V1_1 = 0x11, ///< represents Rev 1.1
    V1_2 = 0x12, ///< represents Rev 1.2

    // These module revisions can vary independently
    // so we track the largest decoded revision here.
    GEN_SEC_MAX = V1_1,
    RDIMM_MAX = V1_1,
    LRDIMM_MAX = V1_2,
};

///
/// @brief SPD module parameters
/// @note helps distinguish SPD decoder sections
///
enum parameters
{
    BASE_CNFG,
    RDIMM_MODULE,
    LRDIMM_MODULE,
};

}// mss

#endif
<|endoftext|>


<commit_before>#include <iostream>
#include <vector>
#include <cmath>
#include <assert.h>
#include <atomic>
#include <algorithm>
#include <gtest/gtest.h>
#include "../algorithm.h"
#include "../parallel_async.h"
#include "../sequence_async.h"
#include "../async.h"
#include "../task.h"

class Parallel2Test : testing::Test { };

TEST(Parallel2Test, Test1)
{
	auto f1 = asyncply::_async([](int data){return data;}, 10);
	ASSERT_EQ(f1.get(), 10);
}

TEST(Parallel2Test, Test2)
{
	auto f1 = asyncply::async([](){return 15;});
	auto f2 = f1->then([](int data) {
		std::cout << "post, received: " << data << std::endl;
		return data + 6;
	});
	ASSERT_EQ(f2->get(), 15 + 6);
}

TEST(Parallel2Test, Test3)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	asyncply::for_each(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	ASSERT_EQ(total, 3600);
}

TEST(Parallel2Test, Test3_async)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	auto task = asyncply::for_each_async(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	task->get();
	ASSERT_EQ(total, 3600);
}

#if 0

TEST(Parallel2Test, collapse_double)
{
	double total_ps = asyncply::parallel(
		[]()
		{
			double data = 1.0;
			return asyncply::sequence(data,
				[](double data)
				{
					return data + 1.0;
				},
				[](double data)
				{
					return data + 1.0;
				});
		},
		[]()
		{
			double data = 1.0;
			return asyncply::sequence(data,
				[](double data)
				{
					return data + 1.0;
				},
				[](double data)
				{
					return data + 1.0;
				});
		}
	);
	ASSERT_EQ(total_ps, 6);
}

#endif

#if 1

TEST(Parallel2Test, Test5)
{
	std::atomic<int> total;
	total = 0;
	auto process = asyncply::parallel_async(
				[&total]()
				{
					std::cout << "hi" << std::endl;
					total += 1;
				},
				[&total]()
				{
					std::cout << "bye" << std::endl;
					total += 1;
				}
			);
	auto process2 = process->then([&total]()
			{
				std::cout << "no accum" << std::endl;
				total += 1;
			});
	process2->get();
	ASSERT_EQ(total, 3);
}

TEST(Parallel2Test, Test6)
{
	std::atomic<int> total;
	total = 0;
	{
		auto process = asyncply::parallel_async(
					[&total]()
					{
						std::cout << "hi" << std::endl;
						total += 1;
					},
					[&total]()
					{
						std::cout << "bye" << std::endl;
						total += 1;
					}
				);
		auto process_then = process->then([&total]()
				{
					std::cout << "no accum" << std::endl;
					total += 1;
				});
		process_then->get();
	}
	ASSERT_EQ(total, 3);
}

#endif

<commit_msg>comment tests<commit_after>#include <iostream>
#include <vector>
#include <cmath>
#include <assert.h>
#include <atomic>
#include <algorithm>
#include <gtest/gtest.h>
#include "../algorithm.h"
#include "../parallel_async.h"
#include "../sequence_async.h"
#include "../async.h"
#include "../task.h"

class Parallel2Test : testing::Test { };

TEST(Parallel2Test, Test1)
{
	auto f1 = asyncply::_async([](int data){return data;}, 10);
	ASSERT_EQ(f1.get(), 10);
}

TEST(Parallel2Test, Test2)
{
	auto f1 = asyncply::async([](){return 15;});
	auto f2 = f1->then([](int data) {
		std::cout << "post, received: " << data << std::endl;
		return data + 6;
	});
	ASSERT_EQ(f2->get(), 15 + 6);
}

TEST(Parallel2Test, Test3)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	asyncply::for_each(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	ASSERT_EQ(total, 3600);
}

TEST(Parallel2Test, Test3_async)
{
	std::vector<int> a;
	for(int i=0; i<100; ++i)
	{
		a.push_back(1);
		a.push_back(4);
		a.push_back(12);
		a.push_back(-3);
		a.push_back(22);
	}
	std::atomic<int> total;
	total = 0;
	auto task = asyncply::for_each_async(a.begin(), a.end(), [&total](int i) {
		total += i;
	});
	task->get();
	ASSERT_EQ(total, 3600);
}

#if 0

TEST(Parallel2Test, collapse_double)
{
	double total_ps = asyncply::parallel(
		[]()
		{
			double data = 1.0;
			return asyncply::sequence(data,
				[](double data)
				{
					return data + 1.0;
				},
				[](double data)
				{
					return data + 1.0;
				});
		},
		[]()
		{
			double data = 1.0;
			return asyncply::sequence(data,
				[](double data)
				{
					return data + 1.0;
				},
				[](double data)
				{
					return data + 1.0;
				});
		}
	);
	ASSERT_EQ(total_ps, 6);
}

#endif

#if 0

TEST(Parallel2Test, Test5)
{
	std::atomic<int> total;
	total = 0;
	auto process = asyncply::parallel_async(
				[&total]()
				{
					std::cout << "hi" << std::endl;
					total += 1;
				},
				[&total]()
				{
					std::cout << "bye" << std::endl;
					total += 1;
				}
			);
	auto process2 = process->then([&total]()
			{
				std::cout << "no accum" << std::endl;
				total += 1;
			});
	process2->get();
	ASSERT_EQ(total, 3);
}

TEST(Parallel2Test, Test6)
{
	std::atomic<int> total;
	total = 0;
	{
		auto process = asyncply::parallel_async(
					[&total]()
					{
						std::cout << "hi" << std::endl;
						total += 1;
					},
					[&total]()
					{
						std::cout << "bye" << std::endl;
						total += 1;
					}
				);
		auto process_then = process->then([&total]()
				{
					std::cout << "no accum" << std::endl;
					total += 1;
				});
		process_then->get();
	}
	ASSERT_EQ(total, 3);
}

#endif

<|endoftext|>


<commit_before>/*
 * The Biomechanical ToolKit
 * Copyright (c) 2009-2011, Arnaud Barr
 * 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(s) 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.
 */
#include "btkVTKAxesWidget.h"

#include <vtkCamera.h>
#include <vtkCoordinate.h>
#include <vtkObjectFactory.h>
#include <vtkAxesActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>

namespace btk
{

  /**
   * @class VTKAxesWidget btkVTKAxesWidget.h
   * @brief VTK widget displaying global axes orientation
   *
   * By default, this widget is not visible. To display it, use the method VTKAxesWidget::SetEnabled().
   * However, before enable it, you must set the interactor (@see VTKAxesWidget::SetInteractor())
   * and the parent's renderer (@see VTKAxesWidget::SetParentRenderer()).
   * This class contains its own vtkAxesActor.
   *
   * This class is inpired of the class vtkOrientationMarkerWidget in VTK.
   *
   * @ingroup BTKVTK
   */

  /**
   * @fn static VTKAxesWidget* VTKAxesWidget::New()
   * Constructs a VTKAxesWidget object and return it as a pointer.
   */
  vtkStandardNewMacro(VTKAxesWidget);
  vtkCxxRevisionMacro(VTKAxesWidget, "$Revision: 0.1 $");

  /**
   * Prints object informations.
   */
  void VTKAxesWidget::PrintSelf(ostream& os, vtkIndent indent)
  {
    this->Superclass::PrintSelf(os, indent);
    os << indent << "AxesActor: " << this->mp_AxesActor << endl;
  };

  /**
   * Sets axes geometry.
   */
  void VTKAxesWidget::SetAxesActor(vtkAxesActor* actor)
  {
    vtkSetObjectBodyMacro(mp_AxesActor, vtkAxesActor, actor);
  };

  /**
   * @fn vtkAxesActor* VTKAxesWidget::GetAxesActor()
   * Returns axes object.
   */

  /**
   * Set the parents' renderer.
   */
  void VTKAxesWidget::SetParentRenderer(vtkRenderer* ren)
  {
    vtkSetObjectBodyMacro(mp_ParentRenderer, vtkRenderer, ren);
  };

  /**
   * @fn vtkRenderer* VTKAxesWidget::GetParentRenderer()
   * Returns the parent's renderer.
   */

  /**
   * Sets the reauired windows interactor to catch commands.
   */
  void VTKAxesWidget::SetInteractor(vtkRenderWindowInteractor* iren)
  {
    if (this->mp_WindowInteractor == iren)
      return;
    this->mp_WindowInteractor = iren;
    this->Modified();
  };

  /**
   * @fn vtkRenderWindowInteractor* VTKAxesWidget::GetInteractor()
   * Returns the interactor.
   */

  /**
   * Sets position and size of the widget in the parent's view.
   */
  void VTKAxesWidget::SetViewport(double minX, double minY,
                                  double maxX, double maxY)
  {
    this->mp_Renderer->SetViewport(minX, minY, maxX, maxY);
  };

  /**
   * Returns position and size of the widget.
   */
  double* VTKAxesWidget::GetViewport()
  {
    return this->mp_Renderer->GetViewport();
  };

  /**
   * Sets the visibility state of the widget.
   */
  void VTKAxesWidget::SetEnabled(int enabling)
  {
    if (!this->mp_WindowInteractor)
      vtkErrorMacro("The interactor must be set prior to enabling/disabling widget");

    if (enabling)
    {
      if (this->mp_AxesActor->GetVisibility())
        return;
      if (!this->mp_ParentRenderer)
      {
        vtkErrorMacro("The parent renderer must be set prior to enabling this widget");
        return;
      }
      this->mp_ParentRenderer->GetRenderWindow()->AddRenderer(this->mp_Renderer);
      if (this->mp_ParentRenderer->GetRenderWindow()->GetNumberOfLayers() < 2)
        this->mp_ParentRenderer->GetRenderWindow()->SetNumberOfLayers(2);

      this->mp_AxesActor->SetVisibility(1);
      // We need to copy the camera before the compositing observer is called.
      // Compositing temporarily changes the camera to display an image.
      this->mp_StartEventObserverId =
        this->mp_ParentRenderer->AddObserver(vtkCommand::StartEvent, this->mp_Observer, 1);
      this->InvokeEvent(vtkCommand::EnableEvent, NULL);
    }
    else
    {
      if (!this->mp_AxesActor->GetVisibility())
        return;

      this->mp_AxesActor->SetVisibility(0);
      if (this->mp_ParentRenderer)
      {
        if (this->mp_ParentRenderer->GetRenderWindow())
        {
          this->mp_ParentRenderer->GetRenderWindow()->RemoveRenderer(this->mp_Renderer);
          this->mp_AxesActor->ReleaseGraphicsResources(this->mp_ParentRenderer->GetRenderWindow());
        }
        if (this->mp_StartEventObserverId != 0)
          this->mp_ParentRenderer->RemoveObserver(this->mp_StartEventObserverId);
      }
      this->InvokeEvent(vtkCommand::DisableEvent, NULL);
    }
  };

  /**
   * Method called by the observer to update axes orientation.
   */
  void VTKAxesWidget::ExecuteEvent(vtkObject* /* o */,
                                   unsigned long /* event */,
                                   void* /*calldata */)
  {
    if (!this->mp_ParentRenderer)
      return;

    vtkCamera* camera = this->mp_ParentRenderer->GetActiveCamera();
    double pos[3], fp[3], viewup[3];
    camera->GetPosition(pos);
    camera->GetFocalPoint(fp);
    camera->GetViewUp(viewup);

    camera = this->mp_Renderer->GetActiveCamera();
    camera->SetPosition(pos);
    camera->SetFocalPoint(fp);
    camera->SetViewUp(viewup);
    this->mp_Renderer->ResetCamera();
  };

  /**
   * Constructor.
   */
  VTKAxesWidget::VTKAxesWidget()
  : vtkObject()
  {
    this->mp_Observer = VTKAxesWidgetObserver::New();
    this->mp_Observer->SetAxesWidget(this);
    this->mp_Renderer = vtkRenderer::New();
    this->mp_Renderer->SetViewport(0.0, 0.0, 0.2, 0.2);
    this->mp_Renderer->SetLayer(1);
    this->mp_Renderer->InteractiveOff();
    this->mp_AxesActor = vtkAxesActor::New();
    this->mp_AxesActor->SetVisibility(0);
    this->mp_Renderer->AddActor(this->mp_AxesActor);
    this->mp_ParentRenderer = 0;
    this->mp_WindowInteractor = 0;
    this->mp_StartEventObserverId = 0;
  };

  /**
   * Destructor.
   */
  VTKAxesWidget::~VTKAxesWidget()
  {
    this->mp_Observer->Delete();
    this->mp_AxesActor->Delete();
    this->SetParentRenderer(0);
    this->mp_Renderer->Delete();
  };
};<commit_msg>[UPD] Shadow for the caption text in the VTKAxesWidget class removed.<commit_after>/*
 * The Biomechanical ToolKit
 * Copyright (c) 2009-2011, Arnaud Barr
 * 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(s) 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.
 */
#include "btkVTKAxesWidget.h"

#include <vtkCamera.h>
#include <vtkCoordinate.h>
#include <vtkObjectFactory.h>
#include <vtkAxesActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCaptionActor2D.h>
#include <vtkTextProperty.h>

namespace btk
{

  /**
   * @class VTKAxesWidget btkVTKAxesWidget.h
   * @brief VTK widget displaying global axes orientation
   *
   * By default, this widget is not visible. To display it, use the method VTKAxesWidget::SetEnabled().
   * However, before enable it, you must set the interactor (@see VTKAxesWidget::SetInteractor())
   * and the parent's renderer (@see VTKAxesWidget::SetParentRenderer()).
   * This class contains its own vtkAxesActor.
   *
   * This class is inpired of the class vtkOrientationMarkerWidget in VTK.
   *
   * @ingroup BTKVTK
   */

  /**
   * @fn static VTKAxesWidget* VTKAxesWidget::New()
   * Constructs a VTKAxesWidget object and return it as a pointer.
   */
  vtkStandardNewMacro(VTKAxesWidget);
  vtkCxxRevisionMacro(VTKAxesWidget, "$Revision: 0.1 $");

  /**
   * Prints object informations.
   */
  void VTKAxesWidget::PrintSelf(ostream& os, vtkIndent indent)
  {
    this->Superclass::PrintSelf(os, indent);
    os << indent << "AxesActor: " << this->mp_AxesActor << endl;
  };

  /**
   * Sets axes geometry.
   */
  void VTKAxesWidget::SetAxesActor(vtkAxesActor* actor)
  {
    vtkSetObjectBodyMacro(mp_AxesActor, vtkAxesActor, actor);
  };

  /**
   * @fn vtkAxesActor* VTKAxesWidget::GetAxesActor()
   * Returns axes object.
   */

  /**
   * Set the parents' renderer.
   */
  void VTKAxesWidget::SetParentRenderer(vtkRenderer* ren)
  {
    vtkSetObjectBodyMacro(mp_ParentRenderer, vtkRenderer, ren);
  };

  /**
   * @fn vtkRenderer* VTKAxesWidget::GetParentRenderer()
   * Returns the parent's renderer.
   */

  /**
   * Sets the reauired windows interactor to catch commands.
   */
  void VTKAxesWidget::SetInteractor(vtkRenderWindowInteractor* iren)
  {
    if (this->mp_WindowInteractor == iren)
      return;
    this->mp_WindowInteractor = iren;
    this->Modified();
  };

  /**
   * @fn vtkRenderWindowInteractor* VTKAxesWidget::GetInteractor()
   * Returns the interactor.
   */

  /**
   * Sets position and size of the widget in the parent's view.
   */
  void VTKAxesWidget::SetViewport(double minX, double minY,
                                  double maxX, double maxY)
  {
    this->mp_Renderer->SetViewport(minX, minY, maxX, maxY);
  };

  /**
   * Returns position and size of the widget.
   */
  double* VTKAxesWidget::GetViewport()
  {
    return this->mp_Renderer->GetViewport();
  };

  /**
   * Sets the visibility state of the widget.
   */
  void VTKAxesWidget::SetEnabled(int enabling)
  {
    if (!this->mp_WindowInteractor)
      vtkErrorMacro("The interactor must be set prior to enabling/disabling widget");

    if (enabling)
    {
      if (this->mp_AxesActor->GetVisibility())
        return;
      if (!this->mp_ParentRenderer)
      {
        vtkErrorMacro("The parent renderer must be set prior to enabling this widget");
        return;
      }
      this->mp_ParentRenderer->GetRenderWindow()->AddRenderer(this->mp_Renderer);
      if (this->mp_ParentRenderer->GetRenderWindow()->GetNumberOfLayers() < 2)
        this->mp_ParentRenderer->GetRenderWindow()->SetNumberOfLayers(2);

      this->mp_AxesActor->SetVisibility(1);
      // We need to copy the camera before the compositing observer is called.
      // Compositing temporarily changes the camera to display an image.
      this->mp_StartEventObserverId =
        this->mp_ParentRenderer->AddObserver(vtkCommand::StartEvent, this->mp_Observer, 1);
      this->InvokeEvent(vtkCommand::EnableEvent, NULL);
    }
    else
    {
      if (!this->mp_AxesActor->GetVisibility())
        return;

      this->mp_AxesActor->SetVisibility(0);
      if (this->mp_ParentRenderer)
      {
        if (this->mp_ParentRenderer->GetRenderWindow())
        {
          this->mp_ParentRenderer->GetRenderWindow()->RemoveRenderer(this->mp_Renderer);
          this->mp_AxesActor->ReleaseGraphicsResources(this->mp_ParentRenderer->GetRenderWindow());
        }
        if (this->mp_StartEventObserverId != 0)
          this->mp_ParentRenderer->RemoveObserver(this->mp_StartEventObserverId);
      }
      this->InvokeEvent(vtkCommand::DisableEvent, NULL);
    }
  };

  /**
   * Method called by the observer to update axes orientation.
   */
  void VTKAxesWidget::ExecuteEvent(vtkObject* /* o */,
                                   unsigned long /* event */,
                                   void* /*calldata */)
  {
    if (!this->mp_ParentRenderer)
      return;

    vtkCamera* camera = this->mp_ParentRenderer->GetActiveCamera();
    double pos[3], fp[3], viewup[3];
    camera->GetPosition(pos);
    camera->GetFocalPoint(fp);
    camera->GetViewUp(viewup);

    camera = this->mp_Renderer->GetActiveCamera();
    camera->SetPosition(pos);
    camera->SetFocalPoint(fp);
    camera->SetViewUp(viewup);
    this->mp_Renderer->ResetCamera();
  };

  /**
   * Constructor.
   */
  VTKAxesWidget::VTKAxesWidget()
  : vtkObject()
  {
    this->mp_Observer = VTKAxesWidgetObserver::New();
    this->mp_Observer->SetAxesWidget(this);
    this->mp_Renderer = vtkRenderer::New();
    this->mp_Renderer->SetViewport(0.0, 0.0, 0.2, 0.2);
    this->mp_Renderer->SetLayer(1);
    this->mp_Renderer->InteractiveOff();
    this->mp_AxesActor = vtkAxesActor::New();
    this->mp_AxesActor->GetXAxisCaptionActor2D()->GetCaptionTextProperty()->ShadowOff();
    this->mp_AxesActor->GetYAxisCaptionActor2D()->GetCaptionTextProperty()->ShadowOff();
    this->mp_AxesActor->GetZAxisCaptionActor2D()->GetCaptionTextProperty()->ShadowOff();
    this->mp_AxesActor->SetVisibility(0);
    this->mp_Renderer->AddActor(this->mp_AxesActor);
    this->mp_ParentRenderer = 0;
    this->mp_WindowInteractor = 0;
    this->mp_StartEventObserverId = 0;
  };

  /**
   * Destructor.
   */
  VTKAxesWidget::~VTKAxesWidget()
  {
    this->mp_Observer->Delete();
    this->mp_AxesActor->Delete();
    this->SetParentRenderer(0);
    this->mp_Renderer->Delete();
  };
};<|endoftext|>


<commit_before><commit_msg>comment<commit_after><|endoftext|>


<commit_before>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <config_features.h>
#include "formulagroup.hxx"
#include "document.hxx"
#include "formulacell.hxx"
#include "tokenarray.hxx"
#include "compiler.hxx"
#include "interpre.hxx"
#include "scmatrix.hxx"

#include "formula/vectortoken.hxx"

#include <vector>

#define USE_DUMMY_INTERPRETER 1

#if USE_DUMMY_INTERPRETER
#include <cstdio>
#endif

namespace sc {

ScMatrixRef FormulaGroupInterpreterSoftware::inverseMatrix(const ScMatrix& /*rMat*/)
{
    return ScMatrixRef();
}

bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                                                const ScFormulaCellGroupRef& xGroup,
                                                ScTokenArray& rCode)
{
    // Decompose the group into individual cells and calculate them individually.

    // The caller must ensure that the top position is the start position of
    // the group.

    ScAddress aTmpPos = rTopPos;
    std::vector<double> aResults;
    aResults.reserve(xGroup->mnLength);
    for (SCROW i = 0; i < xGroup->mnLength; ++i, aTmpPos.IncRow())
    {
        ScTokenArray aCode2;
        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
        {
            switch (p->GetType())
            {
                case formula::svSingleVectorRef:
                {
                    const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
                    const double* pArray = p2->GetArray();
                    aCode2.AddDouble(static_cast<size_t>(i) < p2->GetArrayLength() ? pArray[i] : 0.0);
                }
                break;
                case formula::svDoubleVectorRef:
                {
                    const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
                    const std::vector<const double*>& rArrays = p2->GetArrays();
                    size_t nColSize = rArrays.size();
                    size_t nRowStart = p2->IsStartFixed() ? 0 : i;
                    size_t nRowEnd = p2->GetRefRowSize() - 1;
                    if (!p2->IsEndFixed())
                        nRowEnd += i;
                    size_t nRowSize = nRowEnd - nRowStart + 1;
                    ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
                    for (size_t nCol = 0; nCol < nColSize; ++nCol)
                    {
                        const double* pArray = rArrays[nCol];
                        for (size_t nRow = 0; nRow < nRowSize; ++nRow)
                        {
                            if (nRowStart + nRow < p2->GetArrayLength())
                            {
                                double fVal = pArray[nRowStart+nRow];
                                pMat->PutDouble(fVal, nCol, nRow);
                            }
                        }
                    }

                    ScMatrixToken aTok(pMat);
                    aCode2.AddToken(aTok);
                }
                break;
                default:
                    aCode2.AddToken(*p);
            }
        }

        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
        if (!pDest)
            return false;

        ScCompiler aComp(&rDoc, aTmpPos, aCode2);
        aComp.SetGrammar(rDoc.GetGrammar());
        aComp.CompileTokenArray(); // Create RPN token array.
        ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
        aInterpreter.Interpret();
        aResults.push_back(aInterpreter.GetResultToken()->GetDouble());
    } // for loop end (xGroup->mnLength)

    if (!aResults.empty())
        rDoc.SetFormulaResults(rTopPos, &aResults[0], aResults.size());

    return true;
}

// TODO: load module, hook symbol out, check it works, UI on failure etc.
namespace opencl {
    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
}
FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;

#if USE_DUMMY_INTERPRETER
class FormulaGroupInterpreterDummy : public FormulaGroupInterpreter
{
    enum Mode {
        WRITE_OUTPUT = 0
    };
    Mode meMode;
public:
    FormulaGroupInterpreterDummy()
    {
        const char *pValue = getenv("FORMULA_GROUP_DUMMY");
        meMode = static_cast<Mode>(OString(pValue, strlen(pValue)).toInt32());
        fprintf(stderr, "Using Dummy Formula Group interpreter mode %d\n", (int)meMode);
    }

    virtual ScMatrixRef inverseMatrix(const ScMatrix& /*rMat*/)
    {
        return ScMatrixRef();
    }

    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                           const ScFormulaCellGroupRef& xGroup,
                           ScTokenArray& rCode)
    {
        (void)rCode;

        // Write simple data back into the sheet
        if (meMode == WRITE_OUTPUT)
        {
            double *pDoubles = new double[xGroup->mnLength];
            for (sal_Int32 i = 0; i < xGroup->mnLength; i++)
                pDoubles[i] = 42.0 + i;
            rDoc.SetFormulaResults(rTopPos, pDoubles, xGroup->mnLength);
            delete [] pDoubles;
        }
        return true;
    }
};
#endif

/// load and/or configure the correct formula group interpreter
FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
{
    static bool bOpenCLEnabled = false;

#if USE_DUMMY_INTERPRETER
    if (getenv("FORMULA_GROUP_DUMMY"))
    {
        delete msInstance;
        return msInstance = new sc::FormulaGroupInterpreterDummy();
    }
#endif

    if ( msInstance &&
         bOpenCLEnabled != ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
    {
        delete msInstance;
        msInstance = NULL;
    }

    if ( !msInstance )
    {
#if HAVE_FEATURE_OPENCL
        if ( ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
            msInstance = sc::opencl::createFormulaGroupInterpreter();
#endif
        if ( !msInstance ) // software fallback
            msInstance = new sc::FormulaGroupInterpreterSoftware();
    }

    return msInstance;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<commit_msg>avoid regular re-creation of the formulagroup interpreter.<commit_after>/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 */

#include <config_features.h>
#include "formulagroup.hxx"
#include "document.hxx"
#include "formulacell.hxx"
#include "tokenarray.hxx"
#include "compiler.hxx"
#include "interpre.hxx"
#include "scmatrix.hxx"

#include "formula/vectortoken.hxx"

#include <vector>

#define USE_DUMMY_INTERPRETER 1

#if USE_DUMMY_INTERPRETER
#include <cstdio>
#endif

namespace sc {

ScMatrixRef FormulaGroupInterpreterSoftware::inverseMatrix(const ScMatrix& /*rMat*/)
{
    return ScMatrixRef();
}

bool FormulaGroupInterpreterSoftware::interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                                                const ScFormulaCellGroupRef& xGroup,
                                                ScTokenArray& rCode)
{
    // Decompose the group into individual cells and calculate them individually.

    // The caller must ensure that the top position is the start position of
    // the group.

    ScAddress aTmpPos = rTopPos;
    std::vector<double> aResults;
    aResults.reserve(xGroup->mnLength);
    for (SCROW i = 0; i < xGroup->mnLength; ++i, aTmpPos.IncRow())
    {
        ScTokenArray aCode2;
        for (const formula::FormulaToken* p = rCode.First(); p; p = rCode.Next())
        {
            switch (p->GetType())
            {
                case formula::svSingleVectorRef:
                {
                    const formula::SingleVectorRefToken* p2 = static_cast<const formula::SingleVectorRefToken*>(p);
                    const double* pArray = p2->GetArray();
                    aCode2.AddDouble(static_cast<size_t>(i) < p2->GetArrayLength() ? pArray[i] : 0.0);
                }
                break;
                case formula::svDoubleVectorRef:
                {
                    const formula::DoubleVectorRefToken* p2 = static_cast<const formula::DoubleVectorRefToken*>(p);
                    const std::vector<const double*>& rArrays = p2->GetArrays();
                    size_t nColSize = rArrays.size();
                    size_t nRowStart = p2->IsStartFixed() ? 0 : i;
                    size_t nRowEnd = p2->GetRefRowSize() - 1;
                    if (!p2->IsEndFixed())
                        nRowEnd += i;
                    size_t nRowSize = nRowEnd - nRowStart + 1;
                    ScMatrixRef pMat(new ScMatrix(nColSize, nRowSize, 0.0));
                    for (size_t nCol = 0; nCol < nColSize; ++nCol)
                    {
                        const double* pArray = rArrays[nCol];
                        for (size_t nRow = 0; nRow < nRowSize; ++nRow)
                        {
                            if (nRowStart + nRow < p2->GetArrayLength())
                            {
                                double fVal = pArray[nRowStart+nRow];
                                pMat->PutDouble(fVal, nCol, nRow);
                            }
                        }
                    }

                    ScMatrixToken aTok(pMat);
                    aCode2.AddToken(aTok);
                }
                break;
                default:
                    aCode2.AddToken(*p);
            }
        }

        ScFormulaCell* pDest = rDoc.GetFormulaCell(aTmpPos);
        if (!pDest)
            return false;

        ScCompiler aComp(&rDoc, aTmpPos, aCode2);
        aComp.SetGrammar(rDoc.GetGrammar());
        aComp.CompileTokenArray(); // Create RPN token array.
        ScInterpreter aInterpreter(pDest, &rDoc, aTmpPos, aCode2);
        aInterpreter.Interpret();
        aResults.push_back(aInterpreter.GetResultToken()->GetDouble());
    } // for loop end (xGroup->mnLength)

    if (!aResults.empty())
        rDoc.SetFormulaResults(rTopPos, &aResults[0], aResults.size());

    return true;
}

// TODO: load module, hook symbol out, check it works, UI on failure etc.
namespace opencl {
    extern sc::FormulaGroupInterpreter *createFormulaGroupInterpreter();
}
FormulaGroupInterpreter *FormulaGroupInterpreter::msInstance = NULL;

#if USE_DUMMY_INTERPRETER
class FormulaGroupInterpreterDummy : public FormulaGroupInterpreter
{
    enum Mode {
        WRITE_OUTPUT = 0
    };
    Mode meMode;
public:
    FormulaGroupInterpreterDummy()
    {
        const char *pValue = getenv("FORMULA_GROUP_DUMMY");
        meMode = static_cast<Mode>(OString(pValue, strlen(pValue)).toInt32());
        fprintf(stderr, "Using Dummy Formula Group interpreter mode %d\n", (int)meMode);
    }

    virtual ScMatrixRef inverseMatrix(const ScMatrix& /*rMat*/)
    {
        return ScMatrixRef();
    }

    virtual bool interpret(ScDocument& rDoc, const ScAddress& rTopPos,
                           const ScFormulaCellGroupRef& xGroup,
                           ScTokenArray& rCode)
    {
        (void)rCode;

        // Write simple data back into the sheet
        if (meMode == WRITE_OUTPUT)
        {
            double *pDoubles = new double[xGroup->mnLength];
            for (sal_Int32 i = 0; i < xGroup->mnLength; i++)
                pDoubles[i] = 42.0 + i;
            rDoc.SetFormulaResults(rTopPos, pDoubles, xGroup->mnLength);
            delete [] pDoubles;
        }
        return true;
    }
};
#endif

/// load and/or configure the correct formula group interpreter
FormulaGroupInterpreter *FormulaGroupInterpreter::getStatic()
{
    static bool bOpenCLEnabled = false;

#if USE_DUMMY_INTERPRETER
    if (getenv("FORMULA_GROUP_DUMMY"))
    {
        delete msInstance;
        return msInstance = new sc::FormulaGroupInterpreterDummy();
    }
#endif

    if ( msInstance &&
         bOpenCLEnabled != ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
    {
        bOpenCLEnabled = ScInterpreter::GetGlobalConfig().mbOpenCLEnabled;
        delete msInstance;
        msInstance = NULL;
    }

    if ( !msInstance )
    {
#if HAVE_FEATURE_OPENCL
        if ( ScInterpreter::GetGlobalConfig().mbOpenCLEnabled )
            msInstance = sc::opencl::createFormulaGroupInterpreter();
#endif
        if ( !msInstance ) // software fallback
            msInstance = new sc::FormulaGroupInterpreterSoftware();
    }

    return msInstance;
}

}

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
<|endoftext|>


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

#include "capsule_shape_2d.h"

#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"

Vector<Vector2> CapsuleShape2D::_get_points() const {

	Vector<Vector2> points;
	for (int i = 0; i < 24; i++) {
		Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5);

		points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs);
		if (i == 6 || i == 18)
			points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs);
	}

	return points;
}

bool CapsuleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {

	return Geometry::is_point_in_polygon(p_point, _get_points());
}

void CapsuleShape2D::_update_shape() {

	Physics2DServer::get_singleton()->shape_set_data(get_rid(), Vector2(radius, height));
	emit_changed();
}

void CapsuleShape2D::set_radius(real_t p_radius) {

	radius = p_radius;
	_update_shape();
}

real_t CapsuleShape2D::get_radius() const {

	return radius;
}

void CapsuleShape2D::set_height(real_t p_height) {

	height = p_height;
	_update_shape();
}

real_t CapsuleShape2D::get_height() const {

	return height;
}

void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) {

	Vector<Vector2> points = _get_points();
	Vector<Color> col;
	col.push_back(p_color);
	VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}

Rect2 CapsuleShape2D::get_rect() const {

	Vector2 he = Point2(get_radius(), get_radius() + get_height() * 0.5);
	Rect2 rect;
	rect.position = -he;
	rect.size = he * 2.0;
	return rect;
}

void CapsuleShape2D::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape2D::set_radius);
	ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape2D::get_radius);

	ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape2D::set_height);
	ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape2D::get_height);

	ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius"), "set_radius", "get_radius");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height");
}

CapsuleShape2D::CapsuleShape2D() :
		Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) {

	radius = 10;
	height = 20;
	_update_shape();
}
<commit_msg>Prevent CapsuleShape2D height from being less than zero.<commit_after>/*************************************************************************/
/*  capsule_shape_2d.cpp                                                 */
/*************************************************************************/
/*                       This file is part of:                           */
/*                           GODOT ENGINE                                */
/*                      https://godotengine.org                          */
/*************************************************************************/
/* Copyright (c) 2007-2020 Juan Linietsky, Ariel Manzur.                 */
/* Copyright (c) 2014-2020 Godot Engine contributors (cf. AUTHORS.md).   */
/*                                                                       */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the       */
/* "Software"), to deal in the Software without restriction, including   */
/* without limitation the rights to use, copy, modify, merge, publish,   */
/* distribute, sublicense, and/or sell copies of the Software, and to    */
/* permit persons to whom the Software is furnished to do so, subject to */
/* the following conditions:                                             */
/*                                                                       */
/* The above copyright notice and this permission notice shall be        */
/* included in all copies or substantial portions of the Software.       */
/*                                                                       */
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,       */
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF    */
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY  */
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,  */
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE     */
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.                */
/*************************************************************************/

#include "capsule_shape_2d.h"

#include "servers/physics_2d_server.h"
#include "servers/visual_server.h"

Vector<Vector2> CapsuleShape2D::_get_points() const {

	Vector<Vector2> points;
	for (int i = 0; i < 24; i++) {
		Vector2 ofs = Vector2(0, (i > 6 && i <= 18) ? -get_height() * 0.5 : get_height() * 0.5);

		points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() + ofs);
		if (i == 6 || i == 18)
			points.push_back(Vector2(Math::sin(i * Math_PI * 2 / 24.0), Math::cos(i * Math_PI * 2 / 24.0)) * get_radius() - ofs);
	}

	return points;
}

bool CapsuleShape2D::_edit_is_selected_on_click(const Point2 &p_point, double p_tolerance) const {

	return Geometry::is_point_in_polygon(p_point, _get_points());
}

void CapsuleShape2D::_update_shape() {

	Physics2DServer::get_singleton()->shape_set_data(get_rid(), Vector2(radius, height));
	emit_changed();
}

void CapsuleShape2D::set_radius(real_t p_radius) {

	radius = p_radius;
	_update_shape();
}

real_t CapsuleShape2D::get_radius() const {

	return radius;
}

void CapsuleShape2D::set_height(real_t p_height) {

	height = p_height;
	if (height < 0)
		height = 0;

	_update_shape();
}

real_t CapsuleShape2D::get_height() const {

	return height;
}

void CapsuleShape2D::draw(const RID &p_to_rid, const Color &p_color) {

	Vector<Vector2> points = _get_points();
	Vector<Color> col;
	col.push_back(p_color);
	VisualServer::get_singleton()->canvas_item_add_polygon(p_to_rid, points, col);
}

Rect2 CapsuleShape2D::get_rect() const {

	Vector2 he = Point2(get_radius(), get_radius() + get_height() * 0.5);
	Rect2 rect;
	rect.position = -he;
	rect.size = he * 2.0;
	return rect;
}

void CapsuleShape2D::_bind_methods() {

	ClassDB::bind_method(D_METHOD("set_radius", "radius"), &CapsuleShape2D::set_radius);
	ClassDB::bind_method(D_METHOD("get_radius"), &CapsuleShape2D::get_radius);

	ClassDB::bind_method(D_METHOD("set_height", "height"), &CapsuleShape2D::set_height);
	ClassDB::bind_method(D_METHOD("get_height"), &CapsuleShape2D::get_height);

	ADD_PROPERTY(PropertyInfo(Variant::REAL, "radius"), "set_radius", "get_radius");
	ADD_PROPERTY(PropertyInfo(Variant::REAL, "height"), "set_height", "get_height");
}

CapsuleShape2D::CapsuleShape2D() :
		Shape2D(Physics2DServer::get_singleton()->capsule_shape_create()) {

	radius = 10;
	height = 20;
	_update_shape();
}
<|endoftext|>


<commit_before>// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#ifndef ENABLE_METRICS_PREVIEW
#  include "opentelemetry/sdk/metrics/async_instruments.h"
#  include "opentelemetry/sdk/metrics/state/metric_storage.h"
#  include "opentelemetry/sdk_config.h"

#  include <cmath>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace metrics
{

ObservableInstrument::ObservableInstrument(InstrumentDescriptor instrument_descriptor,
                                           std::unique_ptr<AsyncWritableMetricStorage> storage,
                                           std::shared_ptr<ObservableRegistry> observable_registry)
    : instrument_descriptor_(instrument_descriptor),
      storage_(std::move(storage)),
      observable_registry_{observable_registry}

{}

void ObservableInstrument::AddCallback(opentelemetry::metrics::ObservableCallbackPtr callback,
                                       void *state) noexcept
{
  observable_registry_->AddCallback(callback, state, this);
}

void ObservableInstrument::RemoveCallback(opentelemetry::metrics::ObservableCallbackPtr callback,
                                          void *state) noexcept
{
  observable_registry_->AddCallback(callback, state, this);
}

const InstrumentDescriptor &ObservableInstrument::GetInstrumentDescriptor()
{
  return instrument_descriptor_;
}

AsyncWritableMetricStorage *ObservableInstrument::GetMetricStorage()
{
  return storage_.get();
}

}  // namespace metrics
}  // namespace sdk
OPENTELEMETRY_END_NAMESPACE
#endif
<commit_msg>Fix ObservableInstrument::RemoveCallback (#1582)<commit_after>// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

#ifndef ENABLE_METRICS_PREVIEW
#  include "opentelemetry/sdk/metrics/async_instruments.h"
#  include "opentelemetry/sdk/metrics/state/metric_storage.h"
#  include "opentelemetry/sdk_config.h"

#  include <cmath>

OPENTELEMETRY_BEGIN_NAMESPACE
namespace sdk
{
namespace metrics
{

ObservableInstrument::ObservableInstrument(InstrumentDescriptor instrument_descriptor,
                                           std::unique_ptr<AsyncWritableMetricStorage> storage,
                                           std::shared_ptr<ObservableRegistry> observable_registry)
    : instrument_descriptor_(instrument_descriptor),
      storage_(std::move(storage)),
      observable_registry_{observable_registry}

{}

void ObservableInstrument::AddCallback(opentelemetry::metrics::ObservableCallbackPtr callback,
                                       void *state) noexcept
{
  observable_registry_->AddCallback(callback, state, this);
}

void ObservableInstrument::RemoveCallback(opentelemetry::metrics::ObservableCallbackPtr callback,
                                          void *state) noexcept
{
  observable_registry_->RemoveCallback(callback, state, this);
}

const InstrumentDescriptor &ObservableInstrument::GetInstrumentDescriptor()
{
  return instrument_descriptor_;
}

AsyncWritableMetricStorage *ObservableInstrument::GetMetricStorage()
{
  return storage_.get();
}

}  // namespace metrics
}  // namespace sdk
OPENTELEMETRY_END_NAMESPACE
#endif
<|endoftext|>