<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2017                        */
/* [+] 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  prdfMemTdCtlr_rt.C
 *  @brief A state machine for memory Targeted Diagnostics (runtime only).
 */

#include <prdfMemTdCtlr.H>

// Platform includes
#include <prdfMemEccAnalysis.H>
#include <prdfMemScrubUtils.H>
#include <prdfMemTps.H>
#include <prdfMemUtils.H>
#include <prdfMemVcm.H>
#include <prdfP9McaDataBundle.H>
#include <prdfP9McaExtraSig.H>
#include <prdfPlatServices.H>

using namespace TARGETING;

namespace PRDF
{

using namespace PlatServices;

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
uint32_t MemTdCtlr<T>::handleTdEvent( STEP_CODE_DATA_STRUCT & io_sc,
                                      TdEntry * i_entry )
{
    #define PRDF_FUNC "[MemTdCtlr::handleTdEvent] "

    uint32_t o_rc = SUCCESS;

    do
    {
        // Make sure the TD controller is initialized.
        o_rc = initialize();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "initialize() failed on 0x%08x",
                      iv_chip->getHuid() );
            break;
        }

        // Add this entry to the queue.
        iv_queue.push( i_entry );

        // Don't interrupt a TD procedure if one is already in progress.
        if ( nullptr != iv_curProcedure ) break;

        // Stop background scrubbing.
        o_rc = stopBgScrub<T>( iv_chip );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "stopBgScrub<T>(0x%08x) failed",
                      iv_chip->getHuid() );
            break;
        }

        // Since we had to manually stop the maintenance command, refresh all
        // relevant registers that may have changed since the initial capture.
        // TODO: RTC 166837

        // It is possible that background scrub could have found an ECC error
        // before we had a chance to stop the command. Therefore, we need to
        // call analyzeCmdComplete() first so that any ECC errors found can be
        // handled. Also, analyzeCmdComplete() will initialize the variables
        // needed so we know where to restart background scrubbing.
        bool junk = false;
        o_rc = analyzeCmdComplete( junk, io_sc );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "analyzeCmdComplete(0x%08x) failed",
                      iv_chip->getHuid() );
            break;
        }

        // Move onto the next step in the state machine.
        o_rc = nextStep( io_sc );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "nextStep() failed on 0x%08x",
                      iv_chip->getHuid() );
            break;
        }

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
uint32_t MemTdCtlr<T>::initialize()
{
    #define PRDF_FUNC "[MemTdCtlr::initialize] "

    uint32_t o_rc = SUCCESS;

    do
    {
        if ( iv_initialized ) break; // nothing to do

        // Add any unverified chip marks to the TD queue
        // TODO: RTC 171866

        // At this point, the TD controller is initialized.
        iv_initialized = true;

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
uint32_t MemTdCtlr<T>::defaultStep( STEP_CODE_DATA_STRUCT & io_sc )
{
    #define PRDF_FUNC "[MemTdCtlr::defaultStep] "

    uint32_t o_rc = SUCCESS;

    if ( iv_resumeBgScrub )
    {
        // Background scrubbing paused for FFDC collection only. Resume the
        // current command.

        iv_resumeBgScrub = false;

        PRDF_TRAC( PRDF_FUNC "Calling resumeBgScrub<T>(0x%08x)",
                   iv_chip->getHuid() );

        o_rc = resumeBgScrub<T>( iv_chip );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "resumeBgScrub<T>(0x%08x) failed",
                      iv_chip->getHuid() );
        }
    }
    else
    {
        // A TD procedure has completed. Restart background scrubbing on the
        // next rank.

        TdRankListEntry nextRank = iv_rankList.getNext( iv_stoppedRank );

        PRDF_TRAC( PRDF_FUNC "Calling startBgScrub<T>(0x%08x, m%ds%d)",
                   nextRank.getChip()->getHuid(),
                   nextRank.getRank().getMaster(),
                   nextRank.getRank().getSlave() );

        o_rc = startBgScrub<T>( nextRank.getChip(), nextRank.getRank() );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "startBgScrub<T>(0x%08x,m%ds%d) failed",
                      nextRank.getChip()->getHuid(),
                      nextRank.getRank().getMaster(),
                      nextRank.getRank().getSlave() );
        }
    }

    return o_rc;

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

template <TARGETING::TYPE T, typename D>
uint32_t __checkEcc( ExtensibleChip * i_chip, TdQueue & io_queue,
                     const MemAddr & i_addr, bool & o_errorsFound,
                     STEP_CODE_DATA_STRUCT & io_sc )
{
    #define PRDF_FUNC "[__checkEcc] "

    PRDF_ASSERT( nullptr != i_chip );
    PRDF_ASSERT( T == i_chip->getType() );

    uint32_t o_rc = SUCCESS;

    o_errorsFound = false;

    TargetHandle_t trgt = i_chip->getTrgt();
    HUID           huid = i_chip->getHuid();

    MemRank rank = i_addr.getRank();

    do
    {
        // Check for ECC errors.
        uint32_t eccAttns = 0;
        o_rc = checkEccFirs<T>( i_chip, eccAttns );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "checkEccFirs<T>(0x%08x) failed", huid );
            break;
        }

        if ( 0 != (eccAttns & MAINT_INT_NCE_ETE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintINTER_CTE);

            // Can't do any more isolation at this time. So add the rank to the
            // callout list.
            MemoryMru mm { trgt, rank, MemoryMruData::CALLOUT_RANK };
            io_sc.service_data->SetCallout( mm );

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );
        }

        if ( 0 != (eccAttns & MAINT_SOFT_NCE_ETE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintSOFT_CTE );

            // Can't do any more isolation at this time. So add the rank to the
            // callout list.
            MemoryMru mm { trgt, rank, MemoryMruData::CALLOUT_RANK };
            io_sc.service_data->SetCallout( mm );

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );
        }

        if ( 0 != (eccAttns & MAINT_HARD_NCE_ETE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintHARD_CTE );

            // Query the per-symbol counters for the hard CE symbol.
            MemUtils::MaintSymbols symData; MemSymbol junk;
            o_rc = MemUtils::collectCeStats<T>( i_chip, rank, symData, junk );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "MemUtils::collectCeStats(0x%08x,m%ds%d) "
                          "failed", huid, rank.getMaster(), rank.getSlave() );
                break;
            }

            // The command will have stopped on the first occurrence. So there
            // should only be one symbol in the list.
            PRDF_ASSERT( 1 == symData.size() );

            // Add the symbol to the callout list.
            MemoryMru mm { trgt, rank, symData[0].symbol };
            io_sc.service_data->SetCallout( mm );

            // Any hard CEs in MNFG should be immediately reported.
            if ( mfgMode() )
                io_sc.service_data->setServiceCall();

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );

            /* TODO RTC 136129
            // Dynamically deallocation the page.
            o_rc = MemDealloc::page<T>( i_chip, i_addr );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "MemDealloc::page(0x%08x) failed", huid );
                break;
            }
            */
        }

        if ( 0 != (eccAttns & MAINT_MPE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintMPE );

            // Add entry to UE table.
            D db = static_cast<D>(i_chip->getDataBundle());
            db->iv_ueTable.addEntry( UE_TABLE::SCRUB_MPE, i_addr );

            // Read the chip mark from markstore.
            MemMark chipMark;
            o_rc = MarkStore::readChipMark<T>( i_chip, rank, chipMark );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "readChipMark<T>(0x%08x,%d) failed",
                          huid, rank.getMaster() );
                break;
            }

            // If the chip mark is not valid, then somehow the chip mark was
            // placed on a rank other than the rank in which the command
            // stopped. This would most likely be a code bug.
            PRDF_ASSERT( chipMark.isValid() );

            // Add the mark to the callout list.
            MemoryMru mm { trgt, rank, chipMark.getSymbol() };
            io_sc.service_data->SetCallout( mm );

            // Add a VCM procedure to the queue.
            TdEntry * e = new VcmEvent<T>{ i_chip, rank, chipMark };
            io_queue.push( e );
        }

        if ( 0 != (eccAttns & MAINT_RCE_ETE) )
        {
            o_errorsFound = true;

            // TODO: RTC 171867
        }

        if ( 0 != (eccAttns & MAINT_UE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintUE );

            // Since this will be a predictive callout, change the primary
            // signature as well.
            io_sc.service_data->setSignature( huid, PRDFSIG_MaintUE );

            // Add entry to UE table.
            D db = static_cast<D>(i_chip->getDataBundle());
            db->iv_ueTable.addEntry( UE_TABLE::SCRUB_UE, i_addr );

            // Add the rank to the callout list.
            MemEcc::calloutMemUe<T>( i_chip, rank, io_sc );

            // Make the error log predictive.
            io_sc.service_data->setServiceCall();

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );

            /* TODO RTC 136129
            // Dynamically deallocation the rank.
            o_rc = MemDealloc::rank<T>( i_chip, rank );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "MemDealloc::rank(0x%08x, m%ds%d) failed",
                          huid, rank.getMaster(), rank.getSlave() );
                break;
            }
            */
        }

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}

template
uint32_t __checkEcc<TYPE_MCA, McaDataBundle *>( ExtensibleChip * i_chip,
                                                TdQueue & io_queue,
                                                const MemAddr & i_addr,
                                                bool & o_errorsFound,
                                                STEP_CODE_DATA_STRUCT & io_sc );

/* TODO RTC 157888
template
uint32_t __checkEcc<TYPE_MBA>( ExtensibleChip * i_chip, TdQueue & io_queue,
                               const MemAddr & i_addr, bool & o_errorsFound,
                               STEP_CODE_DATA_STRUCT & io_sc );
*/

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
void MemTdCtlr<T>::collectStateCaptureData( STEP_CODE_DATA_STRUCT & io_sc,
                                            const char * i_startEnd )
{
    #define PRDF_FUNC "[MemTdCtlr<T>::collectStateCaptureData] "

    // TODO RTC 167827

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

// Avoid linker errors with the template.
template class MemTdCtlr<TYPE_MCBIST>;
template class MemTdCtlr<TYPE_MBA>;

//------------------------------------------------------------------------------

} // end namespace PRDF

<commit_msg>PRD: runtime IUE handling in MNFG mode<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/plat/mem/prdfMemTdCtlr_rt.C $               */
/*                                                                        */
/* OpenPOWER HostBoot Project                                             */
/*                                                                        */
/* Contributors Listed Below - COPYRIGHT 2016,2017                        */
/* [+] 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  prdfMemTdCtlr_rt.C
 *  @brief A state machine for memory Targeted Diagnostics (runtime only).
 */

#include <prdfMemTdCtlr.H>

// Platform includes
#include <prdfMemEccAnalysis.H>
#include <prdfMemScrubUtils.H>
#include <prdfMemTps.H>
#include <prdfMemUtils.H>
#include <prdfMemVcm.H>
#include <prdfP9McaDataBundle.H>
#include <prdfP9McaExtraSig.H>
#include <prdfPlatServices.H>

using namespace TARGETING;

namespace PRDF
{

using namespace PlatServices;

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
uint32_t MemTdCtlr<T>::handleTdEvent( STEP_CODE_DATA_STRUCT & io_sc,
                                      TdEntry * i_entry )
{
    #define PRDF_FUNC "[MemTdCtlr::handleTdEvent] "

    uint32_t o_rc = SUCCESS;

    do
    {
        // Make sure the TD controller is initialized.
        o_rc = initialize();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "initialize() failed on 0x%08x",
                      iv_chip->getHuid() );
            break;
        }

        // Add this entry to the queue.
        iv_queue.push( i_entry );

        // Don't interrupt a TD procedure if one is already in progress.
        if ( nullptr != iv_curProcedure ) break;

        // Stop background scrubbing.
        o_rc = stopBgScrub<T>( iv_chip );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "stopBgScrub<T>(0x%08x) failed",
                      iv_chip->getHuid() );
            break;
        }

        // Since we had to manually stop the maintenance command, refresh all
        // relevant registers that may have changed since the initial capture.
        // TODO: RTC 166837

        // It is possible that background scrub could have found an ECC error
        // before we had a chance to stop the command. Therefore, we need to
        // call analyzeCmdComplete() first so that any ECC errors found can be
        // handled. Also, analyzeCmdComplete() will initialize the variables
        // needed so we know where to restart background scrubbing.
        bool junk = false;
        o_rc = analyzeCmdComplete( junk, io_sc );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "analyzeCmdComplete(0x%08x) failed",
                      iv_chip->getHuid() );
            break;
        }

        // Move onto the next step in the state machine.
        o_rc = nextStep( io_sc );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "nextStep() failed on 0x%08x",
                      iv_chip->getHuid() );
            break;
        }

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
uint32_t MemTdCtlr<T>::initialize()
{
    #define PRDF_FUNC "[MemTdCtlr::initialize] "

    uint32_t o_rc = SUCCESS;

    do
    {
        if ( iv_initialized ) break; // nothing to do

        // Add any unverified chip marks to the TD queue
        // TODO: RTC 171866

        // At this point, the TD controller is initialized.
        iv_initialized = true;

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
uint32_t MemTdCtlr<T>::defaultStep( STEP_CODE_DATA_STRUCT & io_sc )
{
    #define PRDF_FUNC "[MemTdCtlr::defaultStep] "

    uint32_t o_rc = SUCCESS;

    if ( iv_resumeBgScrub )
    {
        // Background scrubbing paused for FFDC collection only. Resume the
        // current command.

        iv_resumeBgScrub = false;

        PRDF_TRAC( PRDF_FUNC "Calling resumeBgScrub<T>(0x%08x)",
                   iv_chip->getHuid() );

        o_rc = resumeBgScrub<T>( iv_chip );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "resumeBgScrub<T>(0x%08x) failed",
                      iv_chip->getHuid() );
        }
    }
    else
    {
        // A TD procedure has completed. Restart background scrubbing on the
        // next rank.

        TdRankListEntry nextRank = iv_rankList.getNext( iv_stoppedRank );

        PRDF_TRAC( PRDF_FUNC "Calling startBgScrub<T>(0x%08x, m%ds%d)",
                   nextRank.getChip()->getHuid(),
                   nextRank.getRank().getMaster(),
                   nextRank.getRank().getSlave() );

        o_rc = startBgScrub<T>( nextRank.getChip(), nextRank.getRank() );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "startBgScrub<T>(0x%08x,m%ds%d) failed",
                      nextRank.getChip()->getHuid(),
                      nextRank.getRank().getMaster(),
                      nextRank.getRank().getSlave() );
        }
    }

    return o_rc;

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

template<TARGETING::TYPE T>
uint32_t __handleRceEte( ExtensibleChip * i_chip, bool & o_errorsFound,
                         STEP_CODE_DATA_STRUCT & io_sc );

template<>
uint32_t __handleRceEte<TYPE_MCA>( ExtensibleChip * i_chip,
                                   bool & o_errorsFound,
                                   STEP_CODE_DATA_STRUCT & io_sc )
{
    #define PRDF_FUNC "[__handleRceEte] "

    uint32_t o_rc = SUCCESS;

    // Should only get this attention in MNFG mode.
    PRDF_ASSERT( mfgMode() );

    do
    {
        // The RCE ETE attention could be from IUE, IMPE, or IRCD. Need to check
        // MCAECCFIR[37] to determine if there was at least one IUE.
        SCAN_COMM_REGISTER_CLASS * fir = i_chip->getRegister( "MCAECCFIR" );
        o_rc = fir->Read();
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "Read() failed on MCAECCFIR: i_chip=0x%08x",
                      i_chip->getHuid() );
            break;
        }
        if ( !fir->IsBitSet(37) ) break; // nothing else to do

        // Handle the IUE.
        o_errorsFound = true;
        io_sc.service_data->AddSignatureList( i_chip->getTrgt(),
                                              PRDFSIG_MaintIUE );
        o_rc = MemEcc::analyzeMaintIue<TYPE_MCA,McaDataBundle *>(i_chip, io_sc);
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "analyzeMaintIue(0x%08x) failed",
                      i_chip->getHuid() );
            break;
        }

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}

/* TODO RTC 157888
template<>
uint32_t __handleRceEte<TYPE_MBA>( ExtensibleChip * i_chip,
                                   bool & o_errorsFound,
                                   STEP_CODE_DATA_STRUCT & io_sc )
{
    #define PRDF_FUNC "[__handleRceEte] "

    uint32_t o_rc = SUCCESS;

    do
    {

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}
*/

//------------------------------------------------------------------------------

template <TARGETING::TYPE T, typename D>
uint32_t __checkEcc( ExtensibleChip * i_chip, TdQueue & io_queue,
                     const MemAddr & i_addr, bool & o_errorsFound,
                     STEP_CODE_DATA_STRUCT & io_sc )
{
    #define PRDF_FUNC "[__checkEcc] "

    PRDF_ASSERT( nullptr != i_chip );
    PRDF_ASSERT( T == i_chip->getType() );

    uint32_t o_rc = SUCCESS;

    o_errorsFound = false;

    TargetHandle_t trgt = i_chip->getTrgt();
    HUID           huid = i_chip->getHuid();

    MemRank rank = i_addr.getRank();

    do
    {
        // Check for ECC errors.
        uint32_t eccAttns = 0;
        o_rc = checkEccFirs<T>( i_chip, eccAttns );
        if ( SUCCESS != o_rc )
        {
            PRDF_ERR( PRDF_FUNC "checkEccFirs<T>(0x%08x) failed", huid );
            break;
        }

        if ( 0 != (eccAttns & MAINT_INT_NCE_ETE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintINTER_CTE);

            // Can't do any more isolation at this time. So add the rank to the
            // callout list.
            MemoryMru mm { trgt, rank, MemoryMruData::CALLOUT_RANK };
            io_sc.service_data->SetCallout( mm );

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );
        }

        if ( 0 != (eccAttns & MAINT_SOFT_NCE_ETE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintSOFT_CTE );

            // Can't do any more isolation at this time. So add the rank to the
            // callout list.
            MemoryMru mm { trgt, rank, MemoryMruData::CALLOUT_RANK };
            io_sc.service_data->SetCallout( mm );

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );
        }

        if ( 0 != (eccAttns & MAINT_HARD_NCE_ETE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintHARD_CTE );

            // Query the per-symbol counters for the hard CE symbol.
            MemUtils::MaintSymbols symData; MemSymbol junk;
            o_rc = MemUtils::collectCeStats<T>( i_chip, rank, symData, junk );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "MemUtils::collectCeStats(0x%08x,m%ds%d) "
                          "failed", huid, rank.getMaster(), rank.getSlave() );
                break;
            }

            // The command will have stopped on the first occurrence. So there
            // should only be one symbol in the list.
            PRDF_ASSERT( 1 == symData.size() );

            // Add the symbol to the callout list.
            MemoryMru mm { trgt, rank, symData[0].symbol };
            io_sc.service_data->SetCallout( mm );

            // Any hard CEs in MNFG should be immediately reported.
            if ( mfgMode() )
                io_sc.service_data->setServiceCall();

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );

            /* TODO RTC 136129
            // Dynamically deallocation the page.
            o_rc = MemDealloc::page<T>( i_chip, i_addr );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "MemDealloc::page(0x%08x) failed", huid );
                break;
            }
            */
        }

        if ( 0 != (eccAttns & MAINT_MPE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintMPE );

            // Add entry to UE table.
            D db = static_cast<D>(i_chip->getDataBundle());
            db->iv_ueTable.addEntry( UE_TABLE::SCRUB_MPE, i_addr );

            // Read the chip mark from markstore.
            MemMark chipMark;
            o_rc = MarkStore::readChipMark<T>( i_chip, rank, chipMark );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "readChipMark<T>(0x%08x,%d) failed",
                          huid, rank.getMaster() );
                break;
            }

            // If the chip mark is not valid, then somehow the chip mark was
            // placed on a rank other than the rank in which the command
            // stopped. This would most likely be a code bug.
            PRDF_ASSERT( chipMark.isValid() );

            // Add the mark to the callout list.
            MemoryMru mm { trgt, rank, chipMark.getSymbol() };
            io_sc.service_data->SetCallout( mm );

            // Add a VCM procedure to the queue.
            TdEntry * e = new VcmEvent<T>{ i_chip, rank, chipMark };
            io_queue.push( e );
        }

        if ( 0 != (eccAttns & MAINT_RCE_ETE) )
        {
            o_rc = __handleRceEte<T>( i_chip, o_errorsFound, io_sc );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "__handleRceEte<T>(0x%08x) failed", huid );
                break;
            }
        }

        if ( 0 != (eccAttns & MAINT_UE) )
        {
            o_errorsFound = true;
            io_sc.service_data->AddSignatureList( trgt, PRDFSIG_MaintUE );

            // Since this will be a predictive callout, change the primary
            // signature as well.
            io_sc.service_data->setSignature( huid, PRDFSIG_MaintUE );

            // Add entry to UE table.
            D db = static_cast<D>(i_chip->getDataBundle());
            db->iv_ueTable.addEntry( UE_TABLE::SCRUB_UE, i_addr );

            // Add the rank to the callout list.
            MemEcc::calloutMemUe<T>( i_chip, rank, io_sc );

            // Make the error log predictive.
            io_sc.service_data->setServiceCall();

            // Add a TPS procedure to the queue.
            TdEntry * e = new TpsEvent<T>{ i_chip, rank };
            io_queue.push( e );

            /* TODO RTC 136129
            // Dynamically deallocation the rank.
            o_rc = MemDealloc::rank<T>( i_chip, rank );
            if ( SUCCESS != o_rc )
            {
                PRDF_ERR( PRDF_FUNC "MemDealloc::rank(0x%08x, m%ds%d) failed",
                          huid, rank.getMaster(), rank.getSlave() );
                break;
            }
            */
        }

    } while (0);

    return o_rc;

    #undef PRDF_FUNC
}

template
uint32_t __checkEcc<TYPE_MCA, McaDataBundle *>( ExtensibleChip * i_chip,
                                                TdQueue & io_queue,
                                                const MemAddr & i_addr,
                                                bool & o_errorsFound,
                                                STEP_CODE_DATA_STRUCT & io_sc );

/* TODO RTC 157888
template
uint32_t __checkEcc<TYPE_MBA>( ExtensibleChip * i_chip, TdQueue & io_queue,
                               const MemAddr & i_addr, bool & o_errorsFound,
                               STEP_CODE_DATA_STRUCT & io_sc );
*/

//------------------------------------------------------------------------------

template <TARGETING::TYPE T>
void MemTdCtlr<T>::collectStateCaptureData( STEP_CODE_DATA_STRUCT & io_sc,
                                            const char * i_startEnd )
{
    #define PRDF_FUNC "[MemTdCtlr<T>::collectStateCaptureData] "

    // TODO RTC 167827

    #undef PRDF_FUNC
}

//------------------------------------------------------------------------------

// Avoid linker errors with the template.
template class MemTdCtlr<TYPE_MCBIST>;
template class MemTdCtlr<TYPE_MBA>;

//------------------------------------------------------------------------------

} // end namespace PRDF

<|endoftext|>


<commit_before>/*****************************************************************************
  bamAncillary.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licensed under the GNU General Public License 2.0 license.
******************************************************************************/
#include "BamAncillary.h"
using namespace std;

// 10   15   20      25    30               4000
// acccctttggacct---ataggga.................aaaa
// acccc---ggaccttttataggga.................aaaa
// 5M   3D 6M    2I 7M      20N             4M

namespace BamTools {
    void getBamBlocks(const BamAlignment &bam, const RefVector &refs,
                      vector<BED> &blocks, bool breakOnDeletionOps) {

        CHRPOS currPosition = bam.Position;
        CHRPOS blockStart   = bam.Position;
        string chrom        = refs.at(bam.RefID).RefName;
        string name         = bam.Name;
        string strand       = "+";
        string score        = ToString(bam.MapQuality);
        char  prevOp        = '\0';
        if (bam.IsReverseStrand()) strand = "-";
        bool blocksFound = false;

        vector<CigarOp>::const_iterator cigItr = bam.CigarData.begin();
        vector<CigarOp>::const_iterator cigEnd = bam.CigarData.end();
        for ( ; cigItr != cigEnd; ++cigItr ) {
            if (cigItr->Type == 'M') {
                currPosition += cigItr->Length;
                // we only want to create a new block if the current M op
                // was preceded by an N op or a D op (and we are breaking on D ops)
                if ((prevOp == 'D' && breakOnDeletionOps == true) || (prevOp == 'N')) {
                    blocks.push_back( BED(chrom, blockStart, currPosition, name, score, strand) );
                    blockStart = currPosition;
                }
            }
            else if (cigItr->Type == 'D') {
                if (breakOnDeletionOps == false)
                    currPosition += cigItr->Length;
                else {
                    blocksFound = true;
                    currPosition += cigItr->Length;
                    blockStart    = currPosition;
                }
            }
            else if (cigItr->Type == 'N') {
                blocks.push_back( BED(chrom, blockStart, currPosition, name, score, strand) );
                blocksFound = true;
                currPosition += cigItr->Length;
                blockStart    = currPosition;
            }
            else if (cigItr->Type == 'S' || cigItr->Type == 'H' || cigItr->Type == 'P' || cigItr->Type == 'I') {
                // do nothing
            }
            else {
                cerr << "Input error: invalid CIGAR type (" << cigItr->Type
                    << ") for: " << bam.Name << endl;
                exit(1);
            }
            prevOp = cigItr->Type;
        }
        // if there were no splits, we just create a block representing the contiguous alignment.
        if (blocksFound == false) {
            blocks.push_back( BED(chrom, bam.Position, currPosition, name, score, strand) );
        }
    }

    void MakeBedFromBam(const BamAlignment &bam, const string &chrom,
                        const bedVector &blocks, BED &bed)
    {
        bed.chrom = chrom;
        bed.start = bam.Position;
        bed.end   = bam.GetEndPosition(false, false);
        // build the name field from the BAM alignment.
        bed.name = bam.Name;
        if (bam.IsFirstMate()) bed.name += "/1";
        else if (bam.IsSecondMate()) bed.name += "/2";
        bed.score  = ToString(bam.MapQuality);
        bed.strand = "+";
        if (bam.IsReverseStrand()) bed.strand = "-";

        bed.fields.push_back(bed.chrom);
        bed.fields.push_back(ToString(bed.start));
        bed.fields.push_back(ToString(bed.end));
        bed.fields.push_back(bed.name);
        bed.fields.push_back(bed.score);
        bed.fields.push_back(bed.strand);
        bed.fields.push_back(ToString(bam.Position));
        bed.fields.push_back(ToString(bed.end));
        bed.fields.push_back("0,0,0");
        bed.fields.push_back(ToString(blocks.size()));

        ostringstream block_lengths, block_starts;
        for (size_t i = 0; i < blocks.size(); ++i) {
            block_lengths << blocks[i].end   - blocks[i].start << ",";
            block_starts  << blocks[i].start - bam.Position << ",";
        }
        bed.fields.push_back(block_lengths.str());
        bed.fields.push_back(block_starts.str());

        // identify which indices relate to the "other"
        // (i,e. non-BED6) fields
        for (size_t i = 5; i <= 11; ++i)
            bed.other_idxs.push_back(i);
    }
}
<commit_msg>remove additional strand from intersect -bed -abam<commit_after>/*****************************************************************************
  bamAncillary.cpp

  (c) 2009 - Aaron Quinlan
  Hall Laboratory
  Department of Biochemistry and Molecular Genetics
  University of Virginia
  aaronquinlan@gmail.com

  Licensed under the GNU General Public License 2.0 license.
******************************************************************************/
#include "BamAncillary.h"
using namespace std;

// 10   15   20      25    30               4000
// acccctttggacct---ataggga.................aaaa
// acccc---ggaccttttataggga.................aaaa
// 5M   3D 6M    2I 7M      20N             4M

namespace BamTools {
    void getBamBlocks(const BamAlignment &bam, const RefVector &refs,
                      vector<BED> &blocks, bool breakOnDeletionOps) {

        CHRPOS currPosition = bam.Position;
        CHRPOS blockStart   = bam.Position;
        string chrom        = refs.at(bam.RefID).RefName;
        string name         = bam.Name;
        string strand       = "+";
        string score        = ToString(bam.MapQuality);
        char  prevOp        = '\0';
        if (bam.IsReverseStrand()) strand = "-";
        bool blocksFound = false;

        vector<CigarOp>::const_iterator cigItr = bam.CigarData.begin();
        vector<CigarOp>::const_iterator cigEnd = bam.CigarData.end();
        for ( ; cigItr != cigEnd; ++cigItr ) {
            if (cigItr->Type == 'M') {
                currPosition += cigItr->Length;
                // we only want to create a new block if the current M op
                // was preceded by an N op or a D op (and we are breaking on D ops)
                if ((prevOp == 'D' && breakOnDeletionOps == true) || (prevOp == 'N')) {
                    blocks.push_back( BED(chrom, blockStart, currPosition, name, score, strand) );
                    blockStart = currPosition;
                }
            }
            else if (cigItr->Type == 'D') {
                if (breakOnDeletionOps == false)
                    currPosition += cigItr->Length;
                else {
                    blocksFound = true;
                    currPosition += cigItr->Length;
                    blockStart    = currPosition;
                }
            }
            else if (cigItr->Type == 'N') {
                blocks.push_back( BED(chrom, blockStart, currPosition, name, score, strand) );
                blocksFound = true;
                currPosition += cigItr->Length;
                blockStart    = currPosition;
            }
            else if (cigItr->Type == 'S' || cigItr->Type == 'H' || cigItr->Type == 'P' || cigItr->Type == 'I') {
                // do nothing
            }
            else {
                cerr << "Input error: invalid CIGAR type (" << cigItr->Type
                    << ") for: " << bam.Name << endl;
                exit(1);
            }
            prevOp = cigItr->Type;
        }
        // if there were no splits, we just create a block representing the contiguous alignment.
        if (blocksFound == false) {
            blocks.push_back( BED(chrom, bam.Position, currPosition, name, score, strand) );
        }
    }

    void MakeBedFromBam(const BamAlignment &bam, const string &chrom,
                        const bedVector &blocks, BED &bed)
    {
        bed.chrom = chrom;
        bed.start = bam.Position;
        bed.end   = bam.GetEndPosition(false, false);
        // build the name field from the BAM alignment.
        bed.name = bam.Name;
        if (bam.IsFirstMate()) bed.name += "/1";
        else if (bam.IsSecondMate()) bed.name += "/2";
        bed.score  = ToString(bam.MapQuality);
        bed.strand = "+";
        if (bam.IsReverseStrand()) bed.strand = "-";

        bed.fields.push_back(bed.chrom);
        bed.fields.push_back(ToString(bed.start));
        bed.fields.push_back(ToString(bed.end));
        bed.fields.push_back(bed.name);
        bed.fields.push_back(bed.score);
        bed.fields.push_back(bed.strand);
        bed.fields.push_back(ToString(bam.Position));
        bed.fields.push_back(ToString(bed.end));
        bed.fields.push_back("0,0,0");
        bed.fields.push_back(ToString(blocks.size()));

        ostringstream block_lengths, block_starts;
        for (size_t i = 0; i < blocks.size(); ++i) {
            block_lengths << blocks[i].end   - blocks[i].start << ",";
            block_starts  << blocks[i].start - bam.Position << ",";
        }
        bed.fields.push_back(block_lengths.str());
        bed.fields.push_back(block_starts.str());

        // identify which indices relate to the "other"
        // (i,e. non-BED6) fields
        for (size_t i = 6; i <= 11; ++i)
            bed.other_idxs.push_back(i);
    }
}
<|endoftext|>


<commit_before>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_debug.h"
#include "sysapi.h"

/*
** Try to determine the swap space available on our own machine.  The answer
** is in kilobytes.
*/

/* If for some reason, the call fails, then -1 is returned */

#if defined(WIN32)

int
sysapi_swap_space_raw()
{
	MEMORYSTATUS status;
	sysapi_internal_reconfig();
	GlobalMemoryStatus(&status);
	return (int) (status.dwAvailPageFile/1024L);

}

#elif defined(LINUX)

int
sysapi_swap_space_raw()
{
	struct sysinfo si;
	double free_swap;

	sysapi_internal_reconfig();

	if (sysinfo(&si) == -1) {
		dprintf(D_ALWAYS,
			"sysapi_swap_space_raw(): error: sysinfo(2) failed: %d(%s)",
			errno, strerror(errno));
		return -1;
	}

	/* On Linux before 2.3.23, mem_unit was not present
		and the pad region of space in this structure appears to
		have been occupying was set to 0; units are bytes */
	if (si.mem_unit == 0) {
		si.mem_unit = 1;
	}

	/* in B */
	free_swap = (double)si.freeswap * (double)si.mem_unit +
			(double)si.totalram * (double)si.mem_unit;

	/* in KB */
	free_swap /= 1024.0;

	if ((int)free_swap > INT_MAX)
	{
		return INT_MAX;
	}

	return (int)free_swap;
}

#elif defined(HPUX)

/* here's the deal:  Using any number in pst_getdynamic seems to be
   *way* to small for our purposes.  Those silly writers of HPUX return
   'free memory paging space' (a small region of physical system memory
   that can be used for paging if all other swap areas are full
   (aka "psuedo-swap")) in the pst_vm field returned in pstat_getdynamic.
   This number is wrong.  What we *really* want is the sum of the free
   space in 'dev' (the swap device) and 'localfs' (any file system
   swapping set up).  So....

   I can use pstat_getswap for this.  It returns a number of structures,
   one for each "swap pool".  These structures will either be
   "Block Device Fields" or "File System Fields" (dev or localfs).  I'll
   sum up their 'pss_nfpgs' fields, multiply by pagesize,  and return.

   On the cae HPs, two swap spaces are returned, one of each type.
   The localfs 'nfpgs' field is 0 on cae machines.  Grrr.  Hopefully, it
   might work somewhere else.  Who knows...

   For more information, see /usr/include/sys/pstat.h and the
   pstat and swapinfo manual pages.

   -Mike Yoder 9-28-98
*/
#include <sys/pstat.h>

int
sysapi_swap_space_raw ()
{
  int pagesize;  /* in kB */
  double virt_mem_size = 0;  /* the so-called virtual memory size we seek */
  struct pst_static s;
  struct pst_swapinfo pss[10];
  int count, i;
  int idx = 0; /* index within the context */

	sysapi_internal_reconfig();
  if (pstat_getstatic(&s, sizeof(s), (size_t)1, 0) != -1) {
    pagesize = s.page_size / 1024;   /* it's right here.... */
  }
  else {
    dprintf ( D_ALWAYS,
		"sysapi_swap_space_raw(): Error getting pagesize. Errno = %d\n",errno);
    return -1;
  }

  /* loop until count == 0, will occur when we've got 'em all */
  while ((count = pstat_getswap(pss, sizeof(pss[0]), 10, idx)) > 0) {
    /* got 'count' entries.  process them. */

    for ( i = 0 ; i < count ; i++ ) {

      /* first ensure that it's enabled */
      if ( (pss[i].pss_flags & 1) == 1 ) {
        /* now make sure it's a SW_BLOCK or FS_BLOCK*/
        /* FS_BLOCK has always returned a 0 for pss_nfpgs on cae hpuxs.
	   Grrr.  It's here in case it works somewhere else. */
	if (((pss[i].pss_flags & 2) == 2) || ((pss[i].pss_flags & 4) == 4)) {
          /* add free pages to total */
          virt_mem_size += (double)pss[i].pss_nfpgs * (double)pagesize;
        }
      }
    }

    idx = pss[count-1].pss_idx+1;
  }

  if (count == -1)
    dprintf ( D_ALWAYS,
		"sysapi_swap_space_raw(): Error in pstat_getswap().  Errno = %d\n",
		errno );

	/* under HP-UX, it is considered an error if virt_mem_size == 0 */
  if ( virt_mem_size != 0 ) {
  	if (virt_mem_size > INT_MAX) {
		return INT_MAX;
	}
    return (int)virt_mem_size;
  } else {
    /* Print an error */
    dprintf ( D_ALWAYS,
		"sysapi_swapspace_raw(): Error virt_mem_size == 0.\n");
    return -1;
  }
}

#elif defined(Solaris)

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/swap.h>

/*
** Try to determine the swap space available on our own machine.  The answer
** is in kilobytes.
*/
int
sysapi_swap_space_raw()
{
	struct anoninfo 	ai;
	double avail;
	int factor;

	sysapi_internal_reconfig();

	factor = sysconf(_SC_PAGESIZE) >> 10;

	memset( &ai, 0, sizeof(ai) );
	if( swapctl(SC_AINFO, &ai) >= 0 ) {
		avail = (double)(ai.ani_max - ai.ani_resv) * (double)factor;
		if (avail > INT_MAX) {
			return INT_MAX;
		}
		return (int)avail;
	} else {
		dprintf( D_FULLDEBUG, "swapctl call failed, errno = %d\n", errno );
		return -1;
	}
}

#elif defined(Darwin) || defined(CONDOR_FREEBSD)
#include <sys/sysctl.h>
int
sysapi_swap_space_raw() {
        int mib[2];
        unsigned int usermem;
        size_t len;
        mib[0] = CTL_HW;
        mib[1] = HW_USERMEM;
        len = sizeof(usermem);
        sysctl(mib, 2, &usermem, &len, NULL, 0);
	return usermem / 1024;
}

#elif defined(AIX)

int
sysapi_swap_space_raw() {
    struct pginfo p;
    int ret;

    CLASS_SYMBOL cuat;
    struct CuAt paging_ent;
    struct CuAt *pret = NULL;
    unsigned long free_swap_space = 0;
	char buf[1024];
	char *path = NULL;

    if (odm_initialize() < 0)
    {
		/* This is quite terrible if it happens */
        dprintf(D_ALWAYS,
			"sysapi_swap_space_raw(): Could not initialize the ODM database: "
			"%d\n", odmerrno);
		return -1;
    }

	/* remember to free this memory just before I leave this function */
    path = odm_set_path("/etc/objrepos");
	if (path == (char*)-1) /* eewww */
	{
        dprintf(D_ALWAYS, "sysapi_swap_space_raw(): Could not set class path! "
			"%d\n", odmerrno);
		return -1;
	}

	/* open up a predefined class symbol found in libcfg.a */
    cuat = odm_open_class(CuAt_CLASS);
    if (cuat == NULL)
    {
        dprintf(D_ALWAYS, "sysapi_swap_space_raw(): Could not open CuAt! %d\n",
			odmerrno);
    	if (odm_terminate() < 0)
    	{
        	dprintf(D_ALWAYS, "Could not terminate using the ODM database: "
				"%d\n", odmerrno);
			free(path);
			return -1;
    	}
		free(path);
		return -1;
    }

    /* odm_get_list() is scary cause I can't tell if it is going to actually
        remove the entries from the ODM when it returns them to me or not.
        So I'm traversing the list in the safe way that I know how */

    /* get me the objects that are paging devices */
    pret = (struct CuAt *)odm_get_obj(cuat, "value='paging'", &paging_ent, ODM_FIRST);
    while(pret != NULL && (int)pret != -1)
    {
		memset(buf, 0, 1024);
		snprintf(buf, 1024, "%s/%s", "/dev", paging_ent.name);

		ret = swapqry(buf, &p);
        if (ret == -1)
        {
			/* XXX when non root, some swap partitions cannot be inspected,
				so skip them. */
        	pret = (struct CuAt *)odm_get_obj(cuat, NULL, &paging_ent, ODM_NEXT);
			continue;
        }

        free_swap_space += p.free;

        pret = (struct CuAt *)odm_get_obj(cuat, NULL, &paging_ent, ODM_NEXT);
    }

    if (odm_close_class(cuat) < 0)
    {
        dprintf(D_ALWAYS, "Could not close CuAt in the ODM database: %d\n",
			odmerrno);
		free(path);
		return -1;
    }

    if (odm_terminate() < 0)
    {
        dprintf(D_ALWAYS, "Could not terminate using the ODM database: %d\n",
			odmerrno);
		free(path);
		return -1;
    }

	free(path);

	/* the free_swap_space unit is in PAGESIZE blocks */
	/* so convert it into bytes, and then convert it into KB units */
    return (free_swap_space * PAGESIZE) / 1024;
}

#else

#error "Please define: sysapi_swap_space_raw()"

#endif /* !defined(WIN32) */

/* the cooked version of the function */
int
sysapi_swap_space(void)
{
	sysapi_internal_reconfig();

	return sysapi_swap_space_raw();
}

<commit_msg>Remove useless cast<commit_after>/***************************************************************
 *
 * Copyright (C) 1990-2007, Condor Team, Computer Sciences Department,
 * University of Wisconsin-Madison, WI.
 *
 * 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.
 *
 ***************************************************************/

#include "condor_common.h"
#include "condor_debug.h"
#include "sysapi.h"

/*
** Try to determine the swap space available on our own machine.  The answer
** is in kilobytes.
*/

/* If for some reason, the call fails, then -1 is returned */

#if defined(WIN32)

int
sysapi_swap_space_raw()
{
	MEMORYSTATUS status;
	sysapi_internal_reconfig();
	GlobalMemoryStatus(&status);
	return (int) (status.dwAvailPageFile/1024L);

}

#elif defined(LINUX)

int
sysapi_swap_space_raw()
{
	struct sysinfo si;
	double free_swap;

	sysapi_internal_reconfig();

	if (sysinfo(&si) == -1) {
		dprintf(D_ALWAYS,
			"sysapi_swap_space_raw(): error: sysinfo(2) failed: %d(%s)",
			errno, strerror(errno));
		return -1;
	}

	/* On Linux before 2.3.23, mem_unit was not present
		and the pad region of space in this structure appears to
		have been occupying was set to 0; units are bytes */
	if (si.mem_unit == 0) {
		si.mem_unit = 1;
	}

	/* in B */
	free_swap = (double)si.freeswap * (double)si.mem_unit +
			(double)si.totalram * (double)si.mem_unit;

	/* in KB */
	free_swap /= 1024.0;

	if (free_swap > INT_MAX)
	{
		return INT_MAX;
	}

	return (int)free_swap;
}

#elif defined(HPUX)

/* here's the deal:  Using any number in pst_getdynamic seems to be
   *way* to small for our purposes.  Those silly writers of HPUX return
   'free memory paging space' (a small region of physical system memory
   that can be used for paging if all other swap areas are full
   (aka "psuedo-swap")) in the pst_vm field returned in pstat_getdynamic.
   This number is wrong.  What we *really* want is the sum of the free
   space in 'dev' (the swap device) and 'localfs' (any file system
   swapping set up).  So....

   I can use pstat_getswap for this.  It returns a number of structures,
   one for each "swap pool".  These structures will either be
   "Block Device Fields" or "File System Fields" (dev or localfs).  I'll
   sum up their 'pss_nfpgs' fields, multiply by pagesize,  and return.

   On the cae HPs, two swap spaces are returned, one of each type.
   The localfs 'nfpgs' field is 0 on cae machines.  Grrr.  Hopefully, it
   might work somewhere else.  Who knows...

   For more information, see /usr/include/sys/pstat.h and the
   pstat and swapinfo manual pages.

   -Mike Yoder 9-28-98
*/
#include <sys/pstat.h>

int
sysapi_swap_space_raw ()
{
  int pagesize;  /* in kB */
  double virt_mem_size = 0;  /* the so-called virtual memory size we seek */
  struct pst_static s;
  struct pst_swapinfo pss[10];
  int count, i;
  int idx = 0; /* index within the context */

	sysapi_internal_reconfig();
  if (pstat_getstatic(&s, sizeof(s), (size_t)1, 0) != -1) {
    pagesize = s.page_size / 1024;   /* it's right here.... */
  }
  else {
    dprintf ( D_ALWAYS,
		"sysapi_swap_space_raw(): Error getting pagesize. Errno = %d\n",errno);
    return -1;
  }

  /* loop until count == 0, will occur when we've got 'em all */
  while ((count = pstat_getswap(pss, sizeof(pss[0]), 10, idx)) > 0) {
    /* got 'count' entries.  process them. */

    for ( i = 0 ; i < count ; i++ ) {

      /* first ensure that it's enabled */
      if ( (pss[i].pss_flags & 1) == 1 ) {
        /* now make sure it's a SW_BLOCK or FS_BLOCK*/
        /* FS_BLOCK has always returned a 0 for pss_nfpgs on cae hpuxs.
	   Grrr.  It's here in case it works somewhere else. */
	if (((pss[i].pss_flags & 2) == 2) || ((pss[i].pss_flags & 4) == 4)) {
          /* add free pages to total */
          virt_mem_size += (double)pss[i].pss_nfpgs * (double)pagesize;
        }
      }
    }

    idx = pss[count-1].pss_idx+1;
  }

  if (count == -1)
    dprintf ( D_ALWAYS,
		"sysapi_swap_space_raw(): Error in pstat_getswap().  Errno = %d\n",
		errno );

	/* under HP-UX, it is considered an error if virt_mem_size == 0 */
  if ( virt_mem_size != 0 ) {
  	if (virt_mem_size > INT_MAX) {
		return INT_MAX;
	}
    return (int)virt_mem_size;
  } else {
    /* Print an error */
    dprintf ( D_ALWAYS,
		"sysapi_swapspace_raw(): Error virt_mem_size == 0.\n");
    return -1;
  }
}

#elif defined(Solaris)

#include <sys/types.h>
#include <sys/stat.h>
#include <sys/swap.h>

/*
** Try to determine the swap space available on our own machine.  The answer
** is in kilobytes.
*/
int
sysapi_swap_space_raw()
{
	struct anoninfo 	ai;
	double avail;
	int factor;

	sysapi_internal_reconfig();

	factor = sysconf(_SC_PAGESIZE) >> 10;

	memset( &ai, 0, sizeof(ai) );
	if( swapctl(SC_AINFO, &ai) >= 0 ) {
		avail = (double)(ai.ani_max - ai.ani_resv) * (double)factor;
		if (avail > INT_MAX) {
			return INT_MAX;
		}
		return (int)avail;
	} else {
		dprintf( D_FULLDEBUG, "swapctl call failed, errno = %d\n", errno );
		return -1;
	}
}

#elif defined(Darwin) || defined(CONDOR_FREEBSD)
#include <sys/sysctl.h>
int
sysapi_swap_space_raw() {
        int mib[2];
        unsigned int usermem;
        size_t len;
        mib[0] = CTL_HW;
        mib[1] = HW_USERMEM;
        len = sizeof(usermem);
        sysctl(mib, 2, &usermem, &len, NULL, 0);
	return usermem / 1024;
}

#elif defined(AIX)

int
sysapi_swap_space_raw() {
    struct pginfo p;
    int ret;

    CLASS_SYMBOL cuat;
    struct CuAt paging_ent;
    struct CuAt *pret = NULL;
    unsigned long free_swap_space = 0;
	char buf[1024];
	char *path = NULL;

    if (odm_initialize() < 0)
    {
		/* This is quite terrible if it happens */
        dprintf(D_ALWAYS,
			"sysapi_swap_space_raw(): Could not initialize the ODM database: "
			"%d\n", odmerrno);
		return -1;
    }

	/* remember to free this memory just before I leave this function */
    path = odm_set_path("/etc/objrepos");
	if (path == (char*)-1) /* eewww */
	{
        dprintf(D_ALWAYS, "sysapi_swap_space_raw(): Could not set class path! "
			"%d\n", odmerrno);
		return -1;
	}

	/* open up a predefined class symbol found in libcfg.a */
    cuat = odm_open_class(CuAt_CLASS);
    if (cuat == NULL)
    {
        dprintf(D_ALWAYS, "sysapi_swap_space_raw(): Could not open CuAt! %d\n",
			odmerrno);
    	if (odm_terminate() < 0)
    	{
        	dprintf(D_ALWAYS, "Could not terminate using the ODM database: "
				"%d\n", odmerrno);
			free(path);
			return -1;
    	}
		free(path);
		return -1;
    }

    /* odm_get_list() is scary cause I can't tell if it is going to actually
        remove the entries from the ODM when it returns them to me or not.
        So I'm traversing the list in the safe way that I know how */

    /* get me the objects that are paging devices */
    pret = (struct CuAt *)odm_get_obj(cuat, "value='paging'", &paging_ent, ODM_FIRST);
    while(pret != NULL && (int)pret != -1)
    {
		memset(buf, 0, 1024);
		snprintf(buf, 1024, "%s/%s", "/dev", paging_ent.name);

		ret = swapqry(buf, &p);
        if (ret == -1)
        {
			/* XXX when non root, some swap partitions cannot be inspected,
				so skip them. */
        	pret = (struct CuAt *)odm_get_obj(cuat, NULL, &paging_ent, ODM_NEXT);
			continue;
        }

        free_swap_space += p.free;

        pret = (struct CuAt *)odm_get_obj(cuat, NULL, &paging_ent, ODM_NEXT);
    }

    if (odm_close_class(cuat) < 0)
    {
        dprintf(D_ALWAYS, "Could not close CuAt in the ODM database: %d\n",
			odmerrno);
		free(path);
		return -1;
    }

    if (odm_terminate() < 0)
    {
        dprintf(D_ALWAYS, "Could not terminate using the ODM database: %d\n",
			odmerrno);
		free(path);
		return -1;
    }

	free(path);

	/* the free_swap_space unit is in PAGESIZE blocks */
	/* so convert it into bytes, and then convert it into KB units */
    return (free_swap_space * PAGESIZE) / 1024;
}

#else

#error "Please define: sysapi_swap_space_raw()"

#endif /* !defined(WIN32) */

/* the cooked version of the function */
int
sysapi_swap_space(void)
{
	sysapi_internal_reconfig();

	return sysapi_swap_space_raw();
}

<|endoftext|>


<commit_before>#pragma once

#include <metaSMT/frontend/Logic.hpp>

using namespace metaSMT;
using namespace metaSMT::solver;
using namespace metaSMT::logic;

namespace metaSMT {

  template<typename Context, typename Boolean>
  typename Context::result_type
  one_hot(Context &ctx, std::vector<Boolean> const &ps) {
    assert(ps.size() > 0 && "One hot encoding requires at least one input variable");

    if (ps.size() == 1) {
      return evaluate(ctx, equal(ps[0], True));
    }

    typename Context::result_type zero_rail = evaluate(ctx, ps[0]);
    typename Context::result_type one_rail = evaluate(ctx, Not(ps[0]));

    for (unsigned u = 1; u < ps.size() - 1; ++u) {
      zero_rail = evaluate(ctx, Ite(ps[u], one_rail, zero_rail));
      one_rail = evaluate(ctx, Ite(ps[u], False, one_rail));
    }

    return evaluate(ctx, Ite(ps[ps.size()-1], one_rail, zero_rail));
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_geq(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Greater equal cardinality constraint requires at least one input variable");

    if (ps.size() < cardinality) {
      return evaluate(ctx, False);
    }

    if (ps.size() == cardinality) {
      typename Context::result_type res = evaluate(ctx, True);
      for (unsigned u = 0; u < ps.size(); ++u)
        res = evaluate(ctx, And(res, ps[u]));
      return res;
    }

    if (cardinality == 0) {
      return evaluate(ctx, True);
    }

    // Now: 0 <= cardinality < ps.size()
    unsigned const rail_size = cardinality;
    std::vector<typename Context::result_type> rails[2];
    rails[0].resize(rail_size);
    rails[1].resize(rail_size);

    // Tableau algorithm - Iteratively calculate all elements
    for (unsigned v = 0; v < ps.size() - cardinality + 1; ++v) {
      for (unsigned u = 0; u < cardinality; ++u) {
        if (u == 0 && v == 0) {
          rails[0][0] = evaluate(ctx, ps[0]);
        } else if (u == 0) {
          rails[v%2][0] = evaluate(ctx, Ite(evaluate(ctx, ps[v]), True, rails[(v-1)%2][0]));
        } else if (v == 0) {
          rails[0][u] = evaluate(ctx, Ite(evaluate(ctx, ps[u]), rails[0][u-1], False));
        } else {
          rails[v%2][u] = evaluate(ctx, Ite(ps[u+v], rails[v%2][u-1], rails[(v-1)%2][u]));
        }
      }
    }
    return rails[(ps.size() - cardinality) % 2][cardinality - 1];
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_lt(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Lower than cardinality constraint requires at least one input variable");
    return evaluate(ctx, Not(cardinality_geq(ctx, ps, cardinality)));
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_leq(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Lower equal cardinality constraint requires at least one input variable");
    return evaluate(ctx, Not(cardinality_geq(ctx, ps, cardinality+1)));
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_gt(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Greater than cardinality constraint requires at least one input variable");
    return evaluate(ctx, Not(cardinality_leq(ctx, ps, cardinality)));
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_eq(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Equality cardinality constraint requires at least one input variable");
    return evaluate(ctx, And(cardinality_geq(ctx, ps, cardinality), cardinality_lt(ctx, ps, cardinality+1)));
  }

} // metaSMT

<commit_msg>generalized cardinality constraint: cardinality_any<commit_after>#pragma once

#include <metaSMT/frontend/Logic.hpp>

using namespace metaSMT;
using namespace metaSMT::solver;
using namespace metaSMT::logic;

namespace metaSMT {

  template<typename Context, typename Boolean>
  typename Context::result_type
  one_hot(Context &ctx, std::vector<Boolean> const &ps) {
    assert(ps.size() > 0 && "One hot encoding requires at least one input variable");

    if (ps.size() == 1) {
      return evaluate(ctx, equal(ps[0], True));
    }

    typename Context::result_type zero_rail = evaluate(ctx, ps[0]);
    typename Context::result_type one_rail = evaluate(ctx, Not(ps[0]));

    for (unsigned u = 1; u < ps.size() - 1; ++u) {
      zero_rail = evaluate(ctx, Ite(ps[u], one_rail, zero_rail));
      one_rail = evaluate(ctx, Ite(ps[u], False, one_rail));
    }

    return evaluate(ctx, Ite(ps[ps.size()-1], one_rail, zero_rail));
  }

  /**
   * Generalized cardinality constraint based on a construction using
   * Binary Decision Diagrams (BDD) by E'{e}n and S\"orensson [1] and
   * Bailleux et al. [2].
   *
   * [1] N. E'{e}n and N. S\"orensson. Translating pseudo-boolean
   * constraints into SAT.  In Journal on Satisfiability, Boolean
   * Modeling and Computation, volume 2, pages 1-26, 2006.
   *
   * [2] O. Bailleux, Y. Boufkhad, and O. Roussel, A Translation of
   * Pseudo-Boolean Constraints to SAT, Journal on Satisfiability,
   * Boolean Modeling and Computation, volume 2, pages 191-200, 2006.
   *
   * The tableau algorithm keeps only two rows of the tableau in
   * memory which we call ``rails''.
   *
   * The construction applies to all operator types (<, <=, =, >=, >).
   * An operator is selected by assigning values to the arguments lt,
   * eq, gt, e.g., the less equal operator corresponds to lt = True,
   * eq = True, gt = False.
   *
   * For instance, the constraint
   *
   *    ps[0] + ps[1] + ps[2] + ps[3] <=> 3 with <=> in {<, >, =, <=, >=}
   *
   * corresponds to the following tableau
   *       RAILS  |   0    1     2     3
   *              |          lt    lt    lt
   *     ---------|------------------------
   *        0     |    eq ps[0] ps[1] ps[2]
   *        1  gt | ps[0] ps[1] ps[2] ps[3]
   *
   * From the bottom right node of the tableau a logic formula is
   * constructed using the ITE-operator where the left neighbor node
   * and the top neighbor node serve as the then and else part,
   * respectively.
   *
   * Moreover, notice that cells with entries lt and gt are not
   * explicitly saved in rails but are directly encoded when the
   * formula is created.
   *
   * Precondition: ps.size > 0 && cardinality > 0 && ps.size() > cardinality
   */
  template <typename Context, typename Boolean, typename LT_Expr, typename EQ_Expr, typename GT_Expr>
  typename Context::result_type
  cardinality_any(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality,
                  LT_Expr lt, EQ_Expr eq, GT_Expr gt) {
    assert(ps.size() > 0 && "Cardinality constraint requires at least one input variable");
    assert(cardinality > 0 && "Unsatisfied precondition for tableau construction");

    assert( ps.size() > cardinality );

    unsigned const rail_size = cardinality+1;
    std::vector<typename Context::result_type> rails[2];
    rails[0].resize(rail_size);
    rails[1].resize(rail_size);

    // Tableau algorithm - Iteratively calculate all elements
    for (unsigned v = 0; v < ps.size() - cardinality + 1; ++v) {
      for (unsigned u = 0; u < cardinality + 1; ++u) {
        if (u == 0 && v == 0) {
          rails[0][0] = evaluate(ctx, eq);
        } else if (u == 0) {
          rails[v%2][0] = evaluate(ctx, Ite(evaluate(ctx, ps[v-1]), gt, rails[(v-1)%2][0]));
        } else if (v == 0) {
          rails[0][u] = evaluate(ctx, Ite(evaluate(ctx, ps[u-1]), rails[0][u-1], lt));
        } else {
          rails[v%2][u] = evaluate(ctx, Ite(ps[u+v-1], rails[v%2][u-1], rails[(v-1)%2][u]));
        }
      }
    }
    return rails[(ps.size() - cardinality)%2][cardinality];
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_eq(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Equality cardinality constraint requires at least one input variable");

    if (cardinality == 0) {
      typename Context::result_type res = evaluate(ctx, True);
      for (unsigned u = 0; u < ps.size(); ++u)
        res = evaluate(ctx, And(res, Not(ps[u])));
      return res;
    }

    if (ps.size() == cardinality) {
      typename Context::result_type res = evaluate(ctx, True);
      for (unsigned u = 0; u < ps.size(); ++u)
        res = evaluate(ctx, And(res, ps[u]));
      return res;
    }

    return cardinality_any(ctx, ps, cardinality, False, True, False);
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_geq(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Greater equal cardinality constraint requires at least one input variable");

    if (ps.size() < cardinality) {
      return evaluate(ctx, False);
    }

    if (cardinality == 0) {
      return evaluate(ctx, True);
    }

    if (ps.size() == cardinality) {
      typename Context::result_type res = evaluate(ctx, True);
      for (unsigned u = 0; u < ps.size(); ++u)
        res = evaluate(ctx, And(res, ps[u]));
      return res;
    }

    return cardinality_any(ctx, ps, cardinality, False, True, True);
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_leq(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Lower equal cardinality constraint requires at least one input variable");

    if (ps.size() < cardinality) {
      return evaluate(ctx, True);
    }

    if (ps.size() == cardinality) {
      return evaluate(ctx, True);
    }

    if (cardinality == 0) {
      typename Context::result_type res = evaluate(ctx, True);
      for (unsigned u = 0; u < ps.size(); ++u)
        res = evaluate(ctx, And(res, Not(ps[u])));
      return res;
    }

    return cardinality_any(ctx, ps, cardinality, True, True, False);
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_gt(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Greater than cardinality constraint requires at least one input variable");
    return evaluate(ctx, Not(cardinality_leq(ctx, ps, cardinality)));
  }

  template <typename Context, typename Boolean>
  typename Context::result_type
  cardinality_lt(Context &ctx, std::vector<Boolean> const &ps, unsigned cardinality) {
    assert(ps.size() > 0 && "Lower than cardinality constraint requires at least one input variable");
    return evaluate(ctx, Not(cardinality_geq(ctx, ps, cardinality)));
  }

} // metaSMT

<|endoftext|>


<commit_before>#include "TocFunction.h"

TocFunction::TocFunction(CodeBlock* body) : Function("toc", NULL, body, NULL) {
}

TocFunction::~TocFunction() {
}

TreeNode::ClassType TocFunction::classType() const {
    return TreeNode::TOC_FUNCTION;
}

llvm::Value* TocFunction::generateCode() {
    llvm::BasicBlock *mainBB = llvm::BasicBlock::Create(IR::Context, "toc", IR::MainFunction);
    IR::Builder.SetInsertPoint(mainBB);

    return mainBB;
}
<commit_msg>Geração de código de toc() corrigida.<commit_after>#include "TocFunction.h"

TocFunction::TocFunction(CodeBlock* body) : Function("toc", NULL, body, NULL) {
}

TocFunction::~TocFunction() {
}

TreeNode::ClassType TocFunction::classType() const {
    return TreeNode::TOC_FUNCTION;
}

llvm::Value* TocFunction::generateCode() {
    llvm::BasicBlock *mainBB = llvm::BasicBlock::Create(IR::Context, "toc", IR::MainFunction);
    IR::Builder.SetInsertPoint(mainBB);

    this->body->generateCode();

    return mainBB;
}
<|endoftext|>


<commit_before>
#include "nucleus/Config.h"
#include "nucleus/Files/FilePath.h"

#if OS(POSIX)
#include <unistd.h>
#endif

namespace nu {

#if OS(POSIX)
FilePath getCurrentWorkingDirectory(Allocator* allocator) {
  char buf[PATH_MAX] = {0};
  const char* result = ::getcwd(buf, PATH_MAX);
  return FilePath{String{result, String::npos, allocator}, allocator};
}
#endif

}  // namespace nu
<commit_msg>Add GetCurrentWorkingDirectory for Windows platform<commit_after>
#include "nucleus/Config.h"
#include "nucleus/Files/FilePath.h"

#if OS(POSIX)
#include <unistd.h>
#elif OS(WIN)
#include "nucleus/Win/WindowsMixin.h"
#endif

namespace nu {

FilePath getCurrentWorkingDirectory(Allocator* allocator) {
#if OS(POSIX)
  char buf[PATH_MAX] = {0};
  const char* result = ::getcwd(buf, PATH_MAX);
  return FilePath{String{result, String::npos, allocator}, allocator};
#elif OS(WIN)
  char buf[MAX_PATH] = {0};
  DWORD result = ::GetCurrentDirectoryA(MAX_PATH, buf);
  return FilePath{String{buf, static_cast<I32>(result), allocator}, allocator};
#endif
}

}  // namespace nu
<|endoftext|>


<commit_before>/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Request.h"

#include "SkPictureRecorder.h"
#include "SkPixelSerializer.h"
#include "SkPM4fPriv.h"
#include "picture_utils.h"

using namespace sk_gpu_test;

static int kDefaultWidth = 1920;
static int kDefaultHeight = 1080;

Request::Request(SkString rootUrl)
    : fUploadContext(nullptr)
    , fUrlDataManager(rootUrl)
    , fGPUEnabled(false)
    , fColorMode(0) {
    // create surface
#if SK_SUPPORT_GPU
    GrContextOptions grContextOpts;
    fContextFactory = new GrContextFactory(grContextOpts);
#else
    fContextFactory = nullptr;
#endif
}

Request::~Request() {
#if SK_SUPPORT_GPU
    if (fContextFactory) {
        delete fContextFactory;
    }
#endif
}

SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) {
    SkBitmap* bmp = new SkBitmap();
    bmp->setInfo(canvas->imageInfo());
    if (!canvas->readPixels(bmp, 0, 0)) {
        fprintf(stderr, "Can't read pixels\n");
        return nullptr;
    }
    return bmp;
}

SkData* Request::writeCanvasToPng(SkCanvas* canvas) {
    // capture pixels
    SkAutoTDelete<SkBitmap> bmp(this->getBitmapFromCanvas(canvas));
    SkASSERT(bmp);

    // Convert to format suitable for PNG output
    sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(*bmp);
    SkASSERT(encodedBitmap.get());

    // write to png
    SkDynamicMemoryWStream buffer;
    SkDrawCommand::WritePNG((const png_bytep) encodedBitmap->writable_data(),
                            bmp->width(), bmp->height(),
                            buffer);
    return buffer.copyToData();
}

SkCanvas* Request::getCanvas() {
#if SK_SUPPORT_GPU
    GrContextFactory* factory = fContextFactory;
    GLTestContext* gl = factory->getContextInfo(GrContextFactory::kNativeGL_ContextType,
                                            GrContextFactory::kNone_ContextOptions).glContext();
    gl->makeCurrent();
#endif
    SkASSERT(fDebugCanvas);

    // create the appropriate surface if necessary
    if (!fSurface) {
        this->enableGPU(fGPUEnabled);
    }
    SkCanvas* target = fSurface->getCanvas();
    return target;
}

void Request::drawToCanvas(int n, int m) {
    SkCanvas* target = this->getCanvas();
    fDebugCanvas->drawTo(target, n, m);
}

SkData* Request::drawToPng(int n, int m) {
    this->drawToCanvas(n, m);
    return writeCanvasToPng(this->getCanvas());
}

SkData* Request::writeOutSkp() {
    // Playback into picture recorder
    SkIRect bounds = this->getBounds();
    SkPictureRecorder recorder;
    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(bounds.width()),
                                               SkIntToScalar(bounds.height()));

    fDebugCanvas->draw(canvas);

    sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());

    SkDynamicMemoryWStream outStream;

    SkAutoTUnref<SkPixelSerializer> serializer(SkImageEncoder::CreatePixelSerializer());
    picture->serialize(&outStream, serializer);

    return outStream.copyToData();
}

GrContext* Request::getContext() {
#if SK_SUPPORT_GPU
  return fContextFactory->get(GrContextFactory::kNativeGL_ContextType,
                              GrContextFactory::kNone_ContextOptions);
#else
  return nullptr;
#endif
}

SkIRect Request::getBounds() {
    SkIRect bounds;
    if (fPicture) {
        bounds = fPicture->cullRect().roundOut();
        if (fGPUEnabled) {
#if SK_SUPPORT_GPU
            int maxRTSize = this->getContext()->caps()->maxRenderTargetSize();
            bounds = SkIRect::MakeWH(SkTMin(bounds.width(), maxRTSize),
                                     SkTMin(bounds.height(), maxRTSize));
#endif
        }
    } else {
        bounds = SkIRect::MakeWH(kDefaultWidth, kDefaultHeight);
    }

    // We clip to kDefaultWidth / kDefaultHeight for performance reasons
    // TODO make this configurable
    bounds = SkIRect::MakeWH(SkTMin(bounds.width(), kDefaultWidth),
                             SkTMin(bounds.height(), kDefaultHeight));
    return bounds;
}

namespace {

struct ColorAndProfile {
    SkColorType fColorType;
    SkColorProfileType fProfileType;
    bool fGammaCorrect;
};

ColorAndProfile ColorModes[] = {
    { kN32_SkColorType, kLinear_SkColorProfileType, false },
    { kN32_SkColorType, kSRGB_SkColorProfileType, true },
    { kRGBA_F16_SkColorType, kLinear_SkColorProfileType, true },
};

}

SkSurface* Request::createCPUSurface() {
    SkIRect bounds = this->getBounds();
    ColorAndProfile cap = ColorModes[fColorMode];
    SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), cap.fColorType,
                                         kPremul_SkAlphaType, cap.fProfileType);
    uint32_t flags = cap.fGammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0;
    SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
    return SkSurface::MakeRaster(info, &props).release();
}

SkSurface* Request::createGPUSurface() {
    GrContext* context = this->getContext();
    SkIRect bounds = this->getBounds();
    ColorAndProfile cap = ColorModes[fColorMode];
    SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), cap.fColorType,
                                         kPremul_SkAlphaType, cap.fProfileType);
    uint32_t flags = cap.fGammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0;
    SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
    SkSurface* surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0,
                                                     &props).release();
    return surface;
}

bool Request::setColorMode(int mode) {
    fColorMode = mode;
    return enableGPU(fGPUEnabled);
}

bool Request::setSRGBMode(bool enable) {
    gTreatSkColorAsSRGB = enable;
    return true;
}

bool Request::enableGPU(bool enable) {
    if (enable) {
        SkSurface* surface = this->createGPUSurface();
        if (surface) {
            fSurface.reset(surface);
            fGPUEnabled = true;

            // When we switch to GPU, there seems to be some mystery draws in the canvas.  So we
            // draw once to flush the pipe
            // TODO understand what is actually happening here
            if (fDebugCanvas) {
                fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
                this->getCanvas()->flush();
            }

            return true;
        }
        return false;
    }
    fSurface.reset(this->createCPUSurface());
    fGPUEnabled = false;
    return true;
}

bool Request::initPictureFromStream(SkStream* stream) {
    // parse picture from stream
    fPicture = SkPicture::MakeFromStream(stream);
    if (!fPicture) {
        fprintf(stderr, "Could not create picture from stream.\n");
        return false;
    }

    // reinitialize canvas with the new picture dimensions
    this->enableGPU(fGPUEnabled);

    // pour picture into debug canvas
    SkIRect bounds = this->getBounds();
    fDebugCanvas.reset(new SkDebugCanvas(bounds.width(), bounds.height()));
    fDebugCanvas->drawPicture(fPicture);

    // for some reason we need to 'flush' the debug canvas by drawing all of the ops
    fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
    this->getCanvas()->flush();
    return true;
}

SkData* Request::getJsonOps(int n) {
    SkCanvas* canvas = this->getCanvas();
    Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas);
    root["mode"] = Json::Value(fGPUEnabled ? "gpu" : "cpu");
    root["drawGpuBatchBounds"] = Json::Value(fDebugCanvas->getDrawGpuBatchBounds());
    root["colorMode"] = Json::Value(fColorMode);
    root["srgbMode"] = Json::Value(gTreatSkColorAsSRGB);
    SkDynamicMemoryWStream stream;
    stream.writeText(Json::FastWriter().write(root).c_str());

    return stream.copyToData();
}

SkData* Request::getJsonBatchList(int n) {
    SkCanvas* canvas = this->getCanvas();
    SkASSERT(fGPUEnabled);

    Json::Value result = fDebugCanvas->toJSONBatchList(n, canvas);

    SkDynamicMemoryWStream stream;
    stream.writeText(Json::FastWriter().write(result).c_str());

    return stream.copyToData();
}

SkData* Request::getJsonInfo(int n) {
    // drawTo
    SkAutoTUnref<SkSurface> surface(this->createCPUSurface());
    SkCanvas* canvas = surface->getCanvas();

    // TODO this is really slow and we should cache the matrix and clip
    fDebugCanvas->drawTo(canvas, n);

    // make some json
    SkMatrix vm = fDebugCanvas->getCurrentMatrix();
    SkIRect clip = fDebugCanvas->getCurrentClip();
    Json::Value info(Json::objectValue);
    info["ViewMatrix"] = SkDrawCommand::MakeJsonMatrix(vm);
    info["ClipRect"] = SkDrawCommand::MakeJsonIRect(clip);

    std::string json = Json::FastWriter().write(info);

    // We don't want the null terminator so strlen is correct
    return SkData::NewWithCopy(json.c_str(), strlen(json.c_str()));
}

SkColor Request::getPixel(int x, int y) {
    SkCanvas* canvas = this->getCanvas();
    canvas->flush();
    SkAutoTDelete<SkBitmap> bitmap(this->getBitmapFromCanvas(canvas));
    SkASSERT(bitmap);

    // Convert to format suitable for inspection
    sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(*bitmap);
    SkASSERT(encodedBitmap.get());

    const uint8_t* start = encodedBitmap->bytes() + ((y * bitmap->width() + x) * 4);
    SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]);
    return result;
}
<commit_msg>skiaserve no longer crashes when no X server is present GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2059263002<commit_after>/*
 * Copyright 2016 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "Request.h"

#include "SkPictureRecorder.h"
#include "SkPixelSerializer.h"
#include "SkPM4fPriv.h"
#include "picture_utils.h"

using namespace sk_gpu_test;

static int kDefaultWidth = 1920;
static int kDefaultHeight = 1080;

Request::Request(SkString rootUrl)
    : fUploadContext(nullptr)
    , fUrlDataManager(rootUrl)
    , fGPUEnabled(false)
    , fColorMode(0) {
    // create surface
#if SK_SUPPORT_GPU
    GrContextOptions grContextOpts;
    fContextFactory = new GrContextFactory(grContextOpts);
#else
    fContextFactory = nullptr;
#endif
}

Request::~Request() {
#if SK_SUPPORT_GPU
    if (fContextFactory) {
        delete fContextFactory;
    }
#endif
}

SkBitmap* Request::getBitmapFromCanvas(SkCanvas* canvas) {
    SkBitmap* bmp = new SkBitmap();
    bmp->setInfo(canvas->imageInfo());
    if (!canvas->readPixels(bmp, 0, 0)) {
        fprintf(stderr, "Can't read pixels\n");
        return nullptr;
    }
    return bmp;
}

SkData* Request::writeCanvasToPng(SkCanvas* canvas) {
    // capture pixels
    SkAutoTDelete<SkBitmap> bmp(this->getBitmapFromCanvas(canvas));
    SkASSERT(bmp);

    // Convert to format suitable for PNG output
    sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(*bmp);
    SkASSERT(encodedBitmap.get());

    // write to png
    SkDynamicMemoryWStream buffer;
    SkDrawCommand::WritePNG((const png_bytep) encodedBitmap->writable_data(),
                            bmp->width(), bmp->height(),
                            buffer);
    return buffer.copyToData();
}

SkCanvas* Request::getCanvas() {
#if SK_SUPPORT_GPU
    GrContextFactory* factory = fContextFactory;
    GLTestContext* gl = factory->getContextInfo(GrContextFactory::kNativeGL_ContextType,
                                                GrContextFactory::kNone_ContextOptions).glContext();
    if (!gl) {
        gl = factory->getContextInfo(GrContextFactory::kMESA_ContextType,
                                     GrContextFactory::kNone_ContextOptions).glContext();
    }
    if (gl) {
        gl->makeCurrent();
    }
#endif
    SkASSERT(fDebugCanvas);

    // create the appropriate surface if necessary
    if (!fSurface) {
        this->enableGPU(fGPUEnabled);
    }
    SkCanvas* target = fSurface->getCanvas();
    return target;
}

void Request::drawToCanvas(int n, int m) {
    SkCanvas* target = this->getCanvas();
    fDebugCanvas->drawTo(target, n, m);
}

SkData* Request::drawToPng(int n, int m) {
    this->drawToCanvas(n, m);
    return writeCanvasToPng(this->getCanvas());
}

SkData* Request::writeOutSkp() {
    // Playback into picture recorder
    SkIRect bounds = this->getBounds();
    SkPictureRecorder recorder;
    SkCanvas* canvas = recorder.beginRecording(SkIntToScalar(bounds.width()),
                                               SkIntToScalar(bounds.height()));

    fDebugCanvas->draw(canvas);

    sk_sp<SkPicture> picture(recorder.finishRecordingAsPicture());

    SkDynamicMemoryWStream outStream;

    SkAutoTUnref<SkPixelSerializer> serializer(SkImageEncoder::CreatePixelSerializer());
    picture->serialize(&outStream, serializer);

    return outStream.copyToData();
}

GrContext* Request::getContext() {
#if SK_SUPPORT_GPU
    GrContext* result = fContextFactory->get(GrContextFactory::kNativeGL_ContextType,
                                             GrContextFactory::kNone_ContextOptions);
    if (!result) {
        result = fContextFactory->get(GrContextFactory::kMESA_ContextType,
                                      GrContextFactory::kNone_ContextOptions);
    }
    return result;
#else
    return nullptr;
#endif
}

SkIRect Request::getBounds() {
    SkIRect bounds;
    if (fPicture) {
        bounds = fPicture->cullRect().roundOut();
        if (fGPUEnabled) {
#if SK_SUPPORT_GPU
            int maxRTSize = this->getContext()->caps()->maxRenderTargetSize();
            bounds = SkIRect::MakeWH(SkTMin(bounds.width(), maxRTSize),
                                     SkTMin(bounds.height(), maxRTSize));
#endif
        }
    } else {
        bounds = SkIRect::MakeWH(kDefaultWidth, kDefaultHeight);
    }

    // We clip to kDefaultWidth / kDefaultHeight for performance reasons
    // TODO make this configurable
    bounds = SkIRect::MakeWH(SkTMin(bounds.width(), kDefaultWidth),
                             SkTMin(bounds.height(), kDefaultHeight));
    return bounds;
}

namespace {

struct ColorAndProfile {
    SkColorType fColorType;
    SkColorProfileType fProfileType;
    bool fGammaCorrect;
};

ColorAndProfile ColorModes[] = {
    { kN32_SkColorType, kLinear_SkColorProfileType, false },
    { kN32_SkColorType, kSRGB_SkColorProfileType, true },
    { kRGBA_F16_SkColorType, kLinear_SkColorProfileType, true },
};

}

SkSurface* Request::createCPUSurface() {
    SkIRect bounds = this->getBounds();
    ColorAndProfile cap = ColorModes[fColorMode];
    SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), cap.fColorType,
                                         kPremul_SkAlphaType, cap.fProfileType);
    uint32_t flags = cap.fGammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0;
    SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
    return SkSurface::MakeRaster(info, &props).release();
}

SkSurface* Request::createGPUSurface() {
    GrContext* context = this->getContext();
    SkIRect bounds = this->getBounds();
    ColorAndProfile cap = ColorModes[fColorMode];
    SkImageInfo info = SkImageInfo::Make(bounds.width(), bounds.height(), cap.fColorType,
                                         kPremul_SkAlphaType, cap.fProfileType);
    uint32_t flags = cap.fGammaCorrect ? SkSurfaceProps::kGammaCorrect_Flag : 0;
    SkSurfaceProps props(flags, SkSurfaceProps::kLegacyFontHost_InitType);
    SkSurface* surface = SkSurface::MakeRenderTarget(context, SkBudgeted::kNo, info, 0,
                                                     &props).release();
    return surface;
}

bool Request::setColorMode(int mode) {
    fColorMode = mode;
    return enableGPU(fGPUEnabled);
}

bool Request::setSRGBMode(bool enable) {
    gTreatSkColorAsSRGB = enable;
    return true;
}

bool Request::enableGPU(bool enable) {
    if (enable) {
        SkSurface* surface = this->createGPUSurface();
        if (surface) {
            fSurface.reset(surface);
            fGPUEnabled = true;

            // When we switch to GPU, there seems to be some mystery draws in the canvas.  So we
            // draw once to flush the pipe
            // TODO understand what is actually happening here
            if (fDebugCanvas) {
                fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
                this->getCanvas()->flush();
            }

            return true;
        }
        return false;
    }
    fSurface.reset(this->createCPUSurface());
    fGPUEnabled = false;
    return true;
}

bool Request::initPictureFromStream(SkStream* stream) {
    // parse picture from stream
    fPicture = SkPicture::MakeFromStream(stream);
    if (!fPicture) {
        fprintf(stderr, "Could not create picture from stream.\n");
        return false;
    }

    // reinitialize canvas with the new picture dimensions
    this->enableGPU(fGPUEnabled);

    // pour picture into debug canvas
    SkIRect bounds = this->getBounds();
    fDebugCanvas.reset(new SkDebugCanvas(bounds.width(), bounds.height()));
    fDebugCanvas->drawPicture(fPicture);

    // for some reason we need to 'flush' the debug canvas by drawing all of the ops
    fDebugCanvas->drawTo(this->getCanvas(), this->getLastOp());
    this->getCanvas()->flush();
    return true;
}

SkData* Request::getJsonOps(int n) {
    SkCanvas* canvas = this->getCanvas();
    Json::Value root = fDebugCanvas->toJSON(fUrlDataManager, n, canvas);
    root["mode"] = Json::Value(fGPUEnabled ? "gpu" : "cpu");
    root["drawGpuBatchBounds"] = Json::Value(fDebugCanvas->getDrawGpuBatchBounds());
    root["colorMode"] = Json::Value(fColorMode);
    root["srgbMode"] = Json::Value(gTreatSkColorAsSRGB);
    SkDynamicMemoryWStream stream;
    stream.writeText(Json::FastWriter().write(root).c_str());

    return stream.copyToData();
}

SkData* Request::getJsonBatchList(int n) {
    SkCanvas* canvas = this->getCanvas();
    SkASSERT(fGPUEnabled);

    Json::Value result = fDebugCanvas->toJSONBatchList(n, canvas);

    SkDynamicMemoryWStream stream;
    stream.writeText(Json::FastWriter().write(result).c_str());

    return stream.copyToData();
}

SkData* Request::getJsonInfo(int n) {
    // drawTo
    SkAutoTUnref<SkSurface> surface(this->createCPUSurface());
    SkCanvas* canvas = surface->getCanvas();

    // TODO this is really slow and we should cache the matrix and clip
    fDebugCanvas->drawTo(canvas, n);

    // make some json
    SkMatrix vm = fDebugCanvas->getCurrentMatrix();
    SkIRect clip = fDebugCanvas->getCurrentClip();
    Json::Value info(Json::objectValue);
    info["ViewMatrix"] = SkDrawCommand::MakeJsonMatrix(vm);
    info["ClipRect"] = SkDrawCommand::MakeJsonIRect(clip);

    std::string json = Json::FastWriter().write(info);

    // We don't want the null terminator so strlen is correct
    return SkData::NewWithCopy(json.c_str(), strlen(json.c_str()));
}

SkColor Request::getPixel(int x, int y) {
    SkCanvas* canvas = this->getCanvas();
    canvas->flush();
    SkAutoTDelete<SkBitmap> bitmap(this->getBitmapFromCanvas(canvas));
    SkASSERT(bitmap);

    // Convert to format suitable for inspection
    sk_sp<SkData> encodedBitmap = sk_tools::encode_bitmap_for_png(*bitmap);
    SkASSERT(encodedBitmap.get());

    const uint8_t* start = encodedBitmap->bytes() + ((y * bitmap->width() + x) * 4);
    SkColor result = SkColorSetARGB(start[3], start[0], start[1], start[2]);
    return result;
}
<|endoftext|>


<commit_before>#ifndef _H_XML_NODE
#define _H_XML_NODE

#include <iostream>
#include <list>
#include <string>

namespace Xml
{

    class Element;

    /**
     * Defines the abstract class of a node for interface purpose
     */
    class Node
    {
    public:

        /*
         * Gets all children nodes
         *
         * @return A list of all children nodes (obviously...)
         */
        virtual
        std::list<Node *>
        childrenNodes() = 0;

        virtual
        std::list<Node const *> const
        childrenNodes() const = 0;

        /*
         * Implements standart stream operator
         */
        virtual
        std::ostream &
        operator >> (std::ostream & stream) const = 0;

        /*
         * Destructor
         */
        virtual
        ~Node()
        {

        }

    };

    /*
     * Defines a sexier standart stream operator
     */
    inline
    std::ostream &
    operator << (std::ostream & stream, Node const & node)
    {
        node >> stream;
        return stream;
    }

}

#endif //_H_XML_NODE
<commit_msg>Removes forward declaration of Xml::Element in src/Xml/XmlNode.hpp<commit_after>#ifndef _H_XML_NODE
#define _H_XML_NODE

#include <iostream>
#include <list>
#include <string>

namespace Xml
{

    /**
     * Defines the abstract class of a node for interface purpose
     */
    class Node
    {
    public:

        /*
         * Gets all children nodes
         *
         * @return A list of all children nodes (obviously...)
         */
        virtual
        std::list<Node *>
        childrenNodes() = 0;

        virtual
        std::list<Node const *> const
        childrenNodes() const = 0;

        /*
         * Implements standart stream operator
         */
        virtual
        std::ostream &
        operator >> (std::ostream & stream) const = 0;

        /*
         * Destructor
         */
        virtual
        ~Node()
        {

        }

    };

    /*
     * Defines a sexier standart stream operator
     */
    inline
    std::ostream &
    operator << (std::ostream & stream, Node const & node)
    {
        node >> stream;
        return stream;
    }

}

#endif //_H_XML_NODE
<|endoftext|>