<commit_before>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C $ */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2002,2013              */
/*                                                                        */
/* p1                                                                     */
/*                                                                        */
/* Object Code Only (OCO) source materials                                */
/* Licensed Internal Code Source Materials                                */
/* IBM HostBoot Licensed Internal Code                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* Origin: 30                                                             */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

/**
  @file prdfHomRegisterAccess.C
  @brief definition of HomRegisterAccess
*/
//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define prdfHomRegisterAccess_C

#ifdef __HOSTBOOT_MODULE
  #include <ecmdDataBufferBase.H>
  #include <fapi.H>
  #include <errlmanager.H>
  #include <devicefw/userif.H>
  #include <targeting/common/targetservice.H>
#else
  #include <ecmdDataBuffer.H>
  #include <hwsvScanScom.H>
  #include <chicservlib.H>
  #include <hwsvExecutionService.H>
#endif

#include <prdfHomRegisterAccess.H>
#include <prdf_service_codes.H>
#include <iipbits.h>
#include <iipglobl.h>
#include <prdfMain.H>
#include <prdfPlatServices.H>

#undef prdfHomRegisterAccess_C

namespace PRDF
{

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//------------------------------------------------------------------------------
// Member Function Specifications
//------------------------------------------------------------------------------

ScomService& getScomService()
{
    return PRDF_GET_SINGLETON(theScomService);
}

ScomService::ScomService() :
    iv_ScomAccessor(NULL)
{
    PRDF_DTRAC("ScomService() initializing default iv_ScomAccessor");
    iv_ScomAccessor = new ScomAccessor();
}

ScomService::~ScomService()
{
    if(NULL != iv_ScomAccessor)
    {
        PRDF_DTRAC("~ScomService() deleting iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }
}

void ScomService::setScomAccessor(ScomAccessor & i_ScomAccessor)
{
    PRDF_DTRAC("ScomService::setScomAccessor() setting new scom accessor");

    if(NULL != iv_ScomAccessor)
    {
        PRDF_TRAC("ScomService::setScomAccessor() deleting old iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }

    iv_ScomAccessor = &i_ScomAccessor;
}

uint32_t ScomService::Access(TARGETING::TargetHandle_t i_target,
                                 BIT_STRING_CLASS & bs,
                                 uint64_t registerId,
                                 MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomService::Access()");

    uint32_t rc = iv_ScomAccessor->Access(i_target,
                                          bs,
                                          registerId,
                                          operation);

    PRDF_DEXIT("ScomService::Access(): rc=%d", rc);

    return rc;
}

uint32_t ScomAccessor::Access(TARGETING::TargetHandle_t i_target,
                                  BIT_STRING_CLASS & bs,
                                  uint64_t registerId,
                                  MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomAccessor::Access()");

    uint32_t rc = SUCCESS;
    errlHndl_t errH = NULL;
    uint32_t bsize = bs.GetLength();
    uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;

    if(i_target != NULL)
    {
        #ifdef __HOSTBOOT_MODULE

        ecmdDataBufferBase buffer(bsize);
        uint64_t l_data = 0;
        size_t l_size = sizeof(uint64_t);

        #else

        ecmdDataBuffer buffer(bsize);

        #endif

        switch (operation)
        {
            case MopRegisterAccess::WRITE:
                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(bs.IsSet(i)) buffer.setBit(i);
                }

                // FIXME: If register is in a EX chiplet, need to also update
                //        PORE image ????

                #ifdef __HOSTBOOT_MODULE

                l_data = buffer.getDoubleWord(0);
                errH = deviceWrite( i_target,
                                    &l_data,
                                    l_size,
                                    DEVICE_SCOM_ADDRESS(registerId));

                #else

                errH = HWSV::hwsvPutScom(i_target, registerId, buffer);

                #endif

                break;

            case MopRegisterAccess::READ:
                bs.Pattern(0x00000000); // clear all bits

                #ifdef __HOSTBOOT_MODULE

                errH = deviceRead( i_target, &l_data, l_size,
                                   DEVICE_SCOM_ADDRESS(registerId) );
                l_ecmdRc = buffer.setDoubleWord(0, l_data);

                #else

                errH = HWSV::hwsvGetScom(i_target, registerId, buffer);

                #endif

                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(buffer.isBitSet(i)) bs.Set(i);
                }

                break;

            default:
                PRDF_ERR("ScomAccessor::Access() unsuppported scom op: 0x%08X", operation);
                break;

        } // end switch operation

    }
    else // Invalid target
    {
        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_CODE_FAIL
         * @moduleid   PRDF_HOM_SCOM
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The invalid ID causing the fail
         * @devdesc    Access SCOM failed due to NULL target handle
         * @procedure  EPUB_PRC_SP_CODE
         */

        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,        // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCOM,              // module id
                         FSP_DEFAULT_REFCODE,        // refcode What do we use???
                         PRDF_CODE_FAIL,             // Reason code
                         SCR_ACCESS_FAILED,          // user data word 1
                         PlatServices::getHuid(i_target),   // user data word 2
                         0x0000,                     // user data word 3
                         0x0000                      // user data word 4
                         );
    }

    if(errH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errH, rc, PRDF_HOM_SCOM, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);
        }
        else
        {
            delete errH;
            errH = NULL;
        }
    }
    if (l_ecmdRc != ECMD_DBUF_SUCCESS)
    {
        PRDF_ERR( "ScomAccessor::Access ecmdDataBuffer "
                  "operation failed with ecmd_rc = 0x%.8X", l_ecmdRc );
        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_ECMD_DATA_BUFFER_FAIL
         * @moduleid   PRDF_HOM_SCOM
         * @userdata1  ecmdDataBuffer return code
         * @userdata2  Chip HUID
         * @userdata3  unused
         * @userdata4  unused
         * @devdesc    Low-level data buffer support returned a failure. Probable firmware error.
         * @procedure  EPUB_PRC_SP_CODE
         */
        errlHndl_t ecmd_rc_errl = NULL;
        PRDF_CREATE_ERRL(ecmd_rc_errl,
                         ERRL_SEV_PREDICTIVE,                // error on diagnosticERRL_ETYPE_NOT_APPLICABLE
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,                    // B1xx src
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCOM,                      // module id
                         FSP_DEFAULT_REFCODE,                // refcode
                         PRDF_ECMD_DATA_BUFFER_FAIL,         // Reason code - see prdf_service_codes.H
                         l_ecmdRc,                           // user data word 1
                         PlatServices::getHuid(i_target),    // user data word 2
                         0,                                  // user data word 3
                         0                                   // user data word 4
                         );

        PRDF_ADD_PROCEDURE_CALLOUT(ecmd_rc_errl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);
        PRDF_COMMIT_ERRL(ecmd_rc_errl, ERRL_ACTION_REPORT);

        rc = FAIL;
    }

    PRDF_DEXIT("ScomAccessor::Access(): rc=%d", rc);

    return rc;
}

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

uint32_t HomRegisterAccessScom::Access( BIT_STRING_CLASS & bs,
                                        uint64_t registerId,
                                        Operation operation) const
{
    PRDF_DENTER("HomRegisterAccessScom::Access()");

    uint32_t rc = getScomService().Access(iv_ptargetHandle,
                                           bs,
                                           registerId,
                                           operation);

    PRDF_DEXIT("HomRegisterAccessScom::Access() rc=%d", rc);

    return rc;
}

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

HomRegisterAccessScan::HomRegisterAccessScan(
                                    TARGETING::TargetHandle_t i_ptargetHandle,
                                    ScanRingField * start, ScanRingField * end )
: MopRegisterAccess(), iv_punitHandle(i_ptargetHandle)
{
    iv_aliasIds.reserve(end-start);
    while(start != end)
    {
        iv_aliasIds.push_back(*start);
        ++start;
    }
}

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

uint32_t HomRegisterAccessScan::Access(BIT_STRING_CLASS & bs,
                                   uint64_t registerId,
                                   Operation operation) const
{

    uint32_t rc = SUCCESS;
    errlHndl_t errH = NULL;
    HUID l_chipHUID = PlatServices::getHuid(iv_punitHandle);
    if(operation == MopRegisterAccess::READ)
    {
        if(iv_punitHandle != NULL)
        {
            #ifdef __HOSTBOOT_MODULE
            ecmdDataBufferBase buf(bs.GetLength());
            #else
            ecmdDataBuffer buf(bs.GetLength());
            #endif

            uint32_t curbit = 0;
            bs.Pattern(0x00000000); // clear desination bit string
            for(AliasIdList::const_iterator i = iv_aliasIds.begin(); i != iv_aliasIds.end(); ++i)
            {
                for(uint32_t j = 0; j != i->length; ++j)
                {
                    if(buf.isBitSet(j)) bs.Set(j+curbit);
                }
                curbit += i->length;
            }
        }
        else
        {

            /*@
             * @errortype
             * @subsys     EPUB_FIRMWARE_SP
             * @reasoncode PRDF_CODE_FAIL
             * @moduleid   PRDF_HOM_SCAN
             * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
             * @userdata2  The invalid ID causing the fail
             * @userdata3  Code location = 0x0001
             * @devdesc Access Scan failed due to an invalid function unit
             * @procedure EPUB_PRC_SP_CODE
             */
            // create an error log
            PRDF_CREATE_ERRL(errH,
                             ERRL_SEV_PREDICTIVE,       // error on diagnostic
                             ERRL_ETYPE_NOT_APPLICABLE,
                             SRCI_MACH_CHECK,
                             SRCI_NO_ATTR,
                             PRDF_HOM_SCAN,             // module id
                             FSP_DEFAULT_REFCODE,       // refcode What do we use???
                             PRDF_CODE_FAIL,            // Reason code
                             SCR_ACCESS_FAILED,         // user data word 1
                             l_chipHUID,                // user data word 2
                             0x0001,                    // user data word 3
                             0x0000                     // user data word 4
                             );
        }
    }
    // PRD does not ever expect to write scan rings - create an error log
    else
    {
        PRDF_ERR( "HomRegisterAccessScan::Access "
                  "only scan read is supported.  Invalid Scan Op: 0x%.8X", operation );

        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_UNSUPPORTED_SCAN_WRITE
         * @moduleid   PRDF_HOM_SCAN
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The ID for the scan
         * @userdata3  Code location = 0x0002
         * @devdesc Access Scan failed. PRD does not ever expect to write scan rings.
         * @procedure EPUB_PRC_SP_CODE
         */
        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,       // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCAN,             // module id
                         FSP_DEFAULT_REFCODE,       // refcode What do we use???
                         PRDF_UNSUPPORTED_SCAN_WRITE, // Reason code
                         SCR_ACCESS_FAILED,         // user data word 1
                         l_chipHUID,                // user data word 2
                         0x0002,                    // user data word 3
                         0x0000                     // user data word 4
                         );
    }
    if(errH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errH, rc, PRDF_HOM_SCAN, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);

        }
        else
        {
            delete errH;
            errH = NULL;
        }
    }

    return rc;
}

} // End namespace PRDF
<commit_msg>PRD: changed include for HWSV SCOM code<commit_after>/* IBM_PROLOG_BEGIN_TAG                                                   */
/* This is an automatically generated prolog.                             */
/*                                                                        */
/* $Source: src/usr/diag/prdf/common/framework/register/prdfHomRegisterAccess.C $ */
/*                                                                        */
/* IBM CONFIDENTIAL                                                       */
/*                                                                        */
/* COPYRIGHT International Business Machines Corp. 2002,2013              */
/*                                                                        */
/* p1                                                                     */
/*                                                                        */
/* Object Code Only (OCO) source materials                                */
/* Licensed Internal Code Source Materials                                */
/* IBM HostBoot Licensed Internal Code                                    */
/*                                                                        */
/* The source code for this program is not published or otherwise         */
/* divested of its trade secrets, irrespective of what has been           */
/* deposited with the U.S. Copyright Office.                              */
/*                                                                        */
/* Origin: 30                                                             */
/*                                                                        */
/* IBM_PROLOG_END_TAG                                                     */

/**
  @file prdfHomRegisterAccess.C
  @brief definition of HomRegisterAccess
*/
//----------------------------------------------------------------------
//  Includes
//----------------------------------------------------------------------
#define prdfHomRegisterAccess_C

#ifdef __HOSTBOOT_MODULE
  #include <ecmdDataBufferBase.H>
  #include <fapi.H>
  #include <errlmanager.H>
  #include <devicefw/userif.H>
  #include <targeting/common/targetservice.H>
#else
  #include <ecmdDataBuffer.H>
  #include <hwcoScanScom.H>
  #include <chicservlib.H>
  #include <hwsvExecutionService.H>
#endif

#include <prdfHomRegisterAccess.H>
#include <prdf_service_codes.H>
#include <iipbits.h>
#include <iipglobl.h>
#include <prdfMain.H>
#include <prdfPlatServices.H>

#undef prdfHomRegisterAccess_C

namespace PRDF
{

//----------------------------------------------------------------------
//  User Types
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Constants
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Macros
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Internal Function Prototypes
//----------------------------------------------------------------------

//----------------------------------------------------------------------
//  Global Variables
//----------------------------------------------------------------------

//------------------------------------------------------------------------------
// Member Function Specifications
//------------------------------------------------------------------------------

ScomService& getScomService()
{
    return PRDF_GET_SINGLETON(theScomService);
}

ScomService::ScomService() :
    iv_ScomAccessor(NULL)
{
    PRDF_DTRAC("ScomService() initializing default iv_ScomAccessor");
    iv_ScomAccessor = new ScomAccessor();
}

ScomService::~ScomService()
{
    if(NULL != iv_ScomAccessor)
    {
        PRDF_DTRAC("~ScomService() deleting iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }
}

void ScomService::setScomAccessor(ScomAccessor & i_ScomAccessor)
{
    PRDF_DTRAC("ScomService::setScomAccessor() setting new scom accessor");

    if(NULL != iv_ScomAccessor)
    {
        PRDF_TRAC("ScomService::setScomAccessor() deleting old iv_ScomAccessor");
        delete iv_ScomAccessor;
        iv_ScomAccessor = NULL;
    }

    iv_ScomAccessor = &i_ScomAccessor;
}

uint32_t ScomService::Access(TARGETING::TargetHandle_t i_target,
                                 BIT_STRING_CLASS & bs,
                                 uint64_t registerId,
                                 MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomService::Access()");

    uint32_t rc = iv_ScomAccessor->Access(i_target,
                                          bs,
                                          registerId,
                                          operation);

    PRDF_DEXIT("ScomService::Access(): rc=%d", rc);

    return rc;
}

uint32_t ScomAccessor::Access(TARGETING::TargetHandle_t i_target,
                                  BIT_STRING_CLASS & bs,
                                  uint64_t registerId,
                                  MopRegisterAccess::Operation operation) const
{
    PRDF_DENTER("ScomAccessor::Access()");

    uint32_t rc = SUCCESS;
    errlHndl_t errH = NULL;
    uint32_t bsize = bs.GetLength();
    uint32_t l_ecmdRc = ECMD_DBUF_SUCCESS;

    if(i_target != NULL)
    {
        #ifdef __HOSTBOOT_MODULE

        ecmdDataBufferBase buffer(bsize);
        uint64_t l_data = 0;
        size_t l_size = sizeof(uint64_t);

        #else

        ecmdDataBuffer buffer(bsize);

        #endif

        switch (operation)
        {
            case MopRegisterAccess::WRITE:
                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(bs.IsSet(i)) buffer.setBit(i);
                }

                // FIXME: If register is in a EX chiplet, need to also update
                //        PORE image ????

                #ifdef __HOSTBOOT_MODULE

                l_data = buffer.getDoubleWord(0);
                errH = deviceWrite( i_target,
                                    &l_data,
                                    l_size,
                                    DEVICE_SCOM_ADDRESS(registerId));

                #else

                errH = HWSV::hwsvPutScom(i_target, registerId, buffer);

                #endif

                break;

            case MopRegisterAccess::READ:
                bs.Pattern(0x00000000); // clear all bits

                #ifdef __HOSTBOOT_MODULE

                errH = deviceRead( i_target, &l_data, l_size,
                                   DEVICE_SCOM_ADDRESS(registerId) );
                l_ecmdRc = buffer.setDoubleWord(0, l_data);

                #else

                errH = HWSV::hwsvGetScom(i_target, registerId, buffer);

                #endif

                for(unsigned int i = 0; i < bsize; ++i)
                {
                    if(buffer.isBitSet(i)) bs.Set(i);
                }

                break;

            default:
                PRDF_ERR("ScomAccessor::Access() unsuppported scom op: 0x%08X", operation);
                break;

        } // end switch operation

    }
    else // Invalid target
    {
        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_CODE_FAIL
         * @moduleid   PRDF_HOM_SCOM
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The invalid ID causing the fail
         * @devdesc    Access SCOM failed due to NULL target handle
         * @procedure  EPUB_PRC_SP_CODE
         */

        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,        // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCOM,              // module id
                         FSP_DEFAULT_REFCODE,        // refcode What do we use???
                         PRDF_CODE_FAIL,             // Reason code
                         SCR_ACCESS_FAILED,          // user data word 1
                         PlatServices::getHuid(i_target),   // user data word 2
                         0x0000,                     // user data word 3
                         0x0000                      // user data word 4
                         );
    }

    if(errH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errH, rc, PRDF_HOM_SCOM, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);
        }
        else
        {
            delete errH;
            errH = NULL;
        }
    }
    if (l_ecmdRc != ECMD_DBUF_SUCCESS)
    {
        PRDF_ERR( "ScomAccessor::Access ecmdDataBuffer "
                  "operation failed with ecmd_rc = 0x%.8X", l_ecmdRc );
        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_ECMD_DATA_BUFFER_FAIL
         * @moduleid   PRDF_HOM_SCOM
         * @userdata1  ecmdDataBuffer return code
         * @userdata2  Chip HUID
         * @userdata3  unused
         * @userdata4  unused
         * @devdesc    Low-level data buffer support returned a failure. Probable firmware error.
         * @procedure  EPUB_PRC_SP_CODE
         */
        errlHndl_t ecmd_rc_errl = NULL;
        PRDF_CREATE_ERRL(ecmd_rc_errl,
                         ERRL_SEV_PREDICTIVE,                // error on diagnosticERRL_ETYPE_NOT_APPLICABLE
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,                    // B1xx src
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCOM,                      // module id
                         FSP_DEFAULT_REFCODE,                // refcode
                         PRDF_ECMD_DATA_BUFFER_FAIL,         // Reason code - see prdf_service_codes.H
                         l_ecmdRc,                           // user data word 1
                         PlatServices::getHuid(i_target),    // user data word 2
                         0,                                  // user data word 3
                         0                                   // user data word 4
                         );

        PRDF_ADD_PROCEDURE_CALLOUT(ecmd_rc_errl, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);
        PRDF_COMMIT_ERRL(ecmd_rc_errl, ERRL_ACTION_REPORT);

        rc = FAIL;
    }

    PRDF_DEXIT("ScomAccessor::Access(): rc=%d", rc);

    return rc;
}

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

uint32_t HomRegisterAccessScom::Access( BIT_STRING_CLASS & bs,
                                        uint64_t registerId,
                                        Operation operation) const
{
    PRDF_DENTER("HomRegisterAccessScom::Access()");

    uint32_t rc = getScomService().Access(iv_ptargetHandle,
                                           bs,
                                           registerId,
                                           operation);

    PRDF_DEXIT("HomRegisterAccessScom::Access() rc=%d", rc);

    return rc;
}

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

HomRegisterAccessScan::HomRegisterAccessScan(
                                    TARGETING::TargetHandle_t i_ptargetHandle,
                                    ScanRingField * start, ScanRingField * end )
: MopRegisterAccess(), iv_punitHandle(i_ptargetHandle)
{
    iv_aliasIds.reserve(end-start);
    while(start != end)
    {
        iv_aliasIds.push_back(*start);
        ++start;
    }
}

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

uint32_t HomRegisterAccessScan::Access(BIT_STRING_CLASS & bs,
                                   uint64_t registerId,
                                   Operation operation) const
{

    uint32_t rc = SUCCESS;
    errlHndl_t errH = NULL;
    HUID l_chipHUID = PlatServices::getHuid(iv_punitHandle);
    if(operation == MopRegisterAccess::READ)
    {
        if(iv_punitHandle != NULL)
        {
            #ifdef __HOSTBOOT_MODULE
            ecmdDataBufferBase buf(bs.GetLength());
            #else
            ecmdDataBuffer buf(bs.GetLength());
            #endif

            uint32_t curbit = 0;
            bs.Pattern(0x00000000); // clear desination bit string
            for(AliasIdList::const_iterator i = iv_aliasIds.begin(); i != iv_aliasIds.end(); ++i)
            {
                for(uint32_t j = 0; j != i->length; ++j)
                {
                    if(buf.isBitSet(j)) bs.Set(j+curbit);
                }
                curbit += i->length;
            }
        }
        else
        {

            /*@
             * @errortype
             * @subsys     EPUB_FIRMWARE_SP
             * @reasoncode PRDF_CODE_FAIL
             * @moduleid   PRDF_HOM_SCAN
             * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
             * @userdata2  The invalid ID causing the fail
             * @userdata3  Code location = 0x0001
             * @devdesc Access Scan failed due to an invalid function unit
             * @procedure EPUB_PRC_SP_CODE
             */
            // create an error log
            PRDF_CREATE_ERRL(errH,
                             ERRL_SEV_PREDICTIVE,       // error on diagnostic
                             ERRL_ETYPE_NOT_APPLICABLE,
                             SRCI_MACH_CHECK,
                             SRCI_NO_ATTR,
                             PRDF_HOM_SCAN,             // module id
                             FSP_DEFAULT_REFCODE,       // refcode What do we use???
                             PRDF_CODE_FAIL,            // Reason code
                             SCR_ACCESS_FAILED,         // user data word 1
                             l_chipHUID,                // user data word 2
                             0x0001,                    // user data word 3
                             0x0000                     // user data word 4
                             );
        }
    }
    // PRD does not ever expect to write scan rings - create an error log
    else
    {
        PRDF_ERR( "HomRegisterAccessScan::Access "
                  "only scan read is supported.  Invalid Scan Op: 0x%.8X", operation );

        /*@
         * @errortype
         * @subsys     EPUB_FIRMWARE_SP
         * @reasoncode PRDF_UNSUPPORTED_SCAN_WRITE
         * @moduleid   PRDF_HOM_SCAN
         * @userdata1  PRD Return code =  SCR_ACCESS_FAILED
         * @userdata2  The ID for the scan
         * @userdata3  Code location = 0x0002
         * @devdesc Access Scan failed. PRD does not ever expect to write scan rings.
         * @procedure EPUB_PRC_SP_CODE
         */
        // create an error log
        PRDF_CREATE_ERRL(errH,
                         ERRL_SEV_PREDICTIVE,       // error on diagnostic
                         ERRL_ETYPE_NOT_APPLICABLE,
                         SRCI_MACH_CHECK,
                         SRCI_NO_ATTR,
                         PRDF_HOM_SCAN,             // module id
                         FSP_DEFAULT_REFCODE,       // refcode What do we use???
                         PRDF_UNSUPPORTED_SCAN_WRITE, // Reason code
                         SCR_ACCESS_FAILED,         // user data word 1
                         l_chipHUID,                // user data word 2
                         0x0002,                    // user data word 3
                         0x0000                     // user data word 4
                         );
    }
    if(errH)
    {
        rc = PRD_SCANCOM_FAILURE;
        PRDF_ADD_SW_ERR(errH, rc, PRDF_HOM_SCAN, __LINE__);
        PRDF_ADD_PROCEDURE_CALLOUT(errH, SRCI_PRIORITY_MED, EPUB_PRC_SP_CODE);

        bool l_isAbort = false;
        PRDF_ABORTING(l_isAbort);
        if (!l_isAbort)
        {
            PRDF_COMMIT_ERRL(errH, ERRL_ACTION_SA|ERRL_ACTION_REPORT);

        }
        else
        {
            delete errH;
            errH = NULL;
        }
    }

    return rc;
}

} // End namespace PRDF
<|endoftext|>


<commit_before>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        record_property_tests.cpp
 * @brief       iutest RecordProperty 対応テスト
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2013-2018, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================

//======================================================================
// include
#include "iutest.hpp"
#include "../include/iutest_spi.hpp"

#if !IUTEST_HAS_ASSERTION_RETURN
void CheckProperty_(const ::iutest::TestResult* tr, const char* key, const char* value)
{
    if( tr != NULL )
    {
        IUTEST_ASSERT_EQ(1, tr->test_property_count());
        IUTEST_EXPECT_STREQ(key, tr->GetTestProperty(0).key());
        IUTEST_EXPECT_STREQ(value, tr->GetTestProperty(0).value());
    }
}
#endif

bool CheckProperty(const ::iutest::TestResult* tr, const char* key, const char* value)
{
#if IUTEST_USE_THROW_ON_ASSERTION_FAILURE
    try {
#endif

#if IUTEST_HAS_ASSERTION_RETURN
    if( tr != NULL )
    {
        IUTEST_ASSERT_EQ(1, tr->test_property_count()) << ::iutest::AssertionReturn<bool>(false);
        IUTEST_EXPECT_STREQ(key, tr->GetTestProperty(0).key()) << ::iutest::AssertionReturn<bool>(false);
        IUTEST_EXPECT_STREQ(value, tr->GetTestProperty(0).value()) << ::iutest::AssertionReturn<bool>(false);
    }
#else
    CheckProperty_(tr, key, value);
#endif

#if IUTEST_USE_THROW_ON_ASSERTION_FAILURE
    } catch(...) {}
#endif
    return ::iutest::UnitTest::GetInstance()->Passed();
}

class RecordTest : public ::iutest::Test
{
public:
    static void SetUpTestCase()
    {
        RecordProperty("foo", "A");
#if !defined(IUTEST_USE_GTEST)
        // ban list
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("name"     , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("tests"    , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("failures" , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("disabled" , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("skip"     , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("errors"   , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("time"     , "A"), "Reserved key");
#endif
        CheckProperty(::iuutil::GetCurrentTestCaseAdHocResult(), "foo", "A");
    }
};

IUTEST_F(RecordTest, A)
{
    RecordProperty("hoge", "B");
#if !defined(IUTEST_USE_GTEST)
    // ban list
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("name"       , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("status"     , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("time"       , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("classname"  , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("type_param" , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("value_param", "B"), "Reserved key");
#endif
    CheckProperty(::iuutil::GetCurrentTestResult(), "hoge", "B");

    // overwrite
    RecordProperty("hoge", "b");
    CheckProperty(::iuutil::GetCurrentTestResult(), "hoge", "b");
}

#ifdef UNICODE
int wmain(int argc, wchar_t* argv[])
#else
int main(int argc, char* argv[])
#endif
{
    IUTEST_INIT(&argc, argv);
    ::iutest::Test::RecordProperty("bar", "C");
#if !defined(IUTEST_USE_GTEST)
        // ban list
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("name"       , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("tests"      , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("failures"   , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("disabled"   , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("skip"       , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("errors"     , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("time"       , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("timestamp"  , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("random_seed", "C"), "Reserved key");
#endif

    {
        const int ret = IUTEST_RUN_ALL_TESTS();
        if( ret != 0 ) return 1;
#if !defined(IUTEST_NO_RECORDPROPERTY_OUTSIDE_TESTMETHOD_LIFESPAN)
        if( !CheckProperty(iuutil::GetAdHocTestResult(), "bar", "C") )
        {
            printf("ad hoc test result is not recorded");
            return 1;
        }
#endif
    }
#if !defined(IUTEST_NO_RECORDPROPERTY_OUTSIDE_TESTMETHOD_LIFESPAN)
    {
        const int ret = IUTEST_RUN_ALL_TESTS();
        if( ret != 0 ) return 1;
        if( !CheckProperty(iuutil::GetAdHocTestResult(), "bar", "C") )
        {
            printf("ad hoc test result is cleared?");
            return 1;
        }
    }
    {
        IUTEST_INIT(&argc, argv);
        const int ret = IUTEST_RUN_ALL_TESTS();
        if( ret != 0 ) return 1;
        if( CheckProperty(iuutil::GetAdHocTestResult(), "bar", "C") )
        {
            printf("ad hoc test result is not cleared?");
            return 1;
        }
    }
#endif
    printf("*** Successful ***\n");
    return 0;
}
<commit_msg>fix test #56<commit_after>//======================================================================
//-----------------------------------------------------------------------
/**
 * @file        record_property_tests.cpp
 * @brief       iutest RecordProperty 対応テスト
 *
 * @author      t.shirayanagi
 * @par         copyright
 * Copyright (C) 2013-2018, Takazumi Shirayanagi\n
 * This software is released under the new BSD License,
 * see LICENSE
*/
//-----------------------------------------------------------------------
//======================================================================

//======================================================================
// include
#include "iutest.hpp"
#include "../include/iutest_spi.hpp"

#if !IUTEST_HAS_ASSERTION_RETURN
void CheckProperty_(const ::iutest::TestResult* tr, const char* key, const char* value)
{
    if( tr != NULL )
    {
        IUTEST_ASSERT_EQ(1, tr->test_property_count());
        IUTEST_EXPECT_STREQ(key, tr->GetTestProperty(0).key());
        IUTEST_EXPECT_STREQ(value, tr->GetTestProperty(0).value());
    }
}
#endif

bool CheckProperty(const ::iutest::TestResult* tr, const char* key, const char* value)
{
#if IUTEST_USE_THROW_ON_ASSERTION_FAILURE
    try {
#endif

#if IUTEST_HAS_ASSERTION_RETURN
    if( tr != NULL )
    {
        IUTEST_ASSERT_EQ(1, tr->test_property_count()) << ::iutest::AssertionReturn<bool>(false);
        IUTEST_EXPECT_STREQ(key, tr->GetTestProperty(0).key()) << ::iutest::AssertionReturn<bool>(false);
        IUTEST_EXPECT_STREQ(value, tr->GetTestProperty(0).value()) << ::iutest::AssertionReturn<bool>(false);
    }
#else
    CheckProperty_(tr, key, value);
#endif

#if IUTEST_USE_THROW_ON_ASSERTION_FAILURE
    } catch(...) {}
#endif
    return ::iutest::UnitTest::GetInstance()->Passed();
}

class RecordTest : public ::iutest::Test
{
public:
    static void SetUpTestCase()
    {
        RecordProperty("foo", "A");
#if !defined(IUTEST_USE_GTEST)
        // ban list
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("name"     , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("tests"    , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("failures" , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("disabled" , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("skip"     , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("errors"   , "A"), "Reserved key");
        IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("time"     , "A"), "Reserved key");
#endif
        CheckProperty(::iuutil::GetCurrentTestCaseAdHocResult(), "foo", "A");
    }
};

IUTEST_F(RecordTest, A)
{
    RecordProperty("hoge", "B");
#if !defined(IUTEST_USE_GTEST)
    // ban list
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("name"       , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("status"     , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("time"       , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("classname"  , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("type_param" , "B"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( RecordProperty("value_param", "B"), "Reserved key");
#endif
    CheckProperty(::iuutil::GetCurrentTestResult(), "hoge", "B");

    // overwrite
    RecordProperty("hoge", "b");
    CheckProperty(::iuutil::GetCurrentTestResult(), "hoge", "b");
}

#ifdef UNICODE
int wmain(int argc, wchar_t* argv[])
#else
int main(int argc, char* argv[])
#endif
{
    IUTEST_INIT(&argc, argv);
    ::iutest::Test::RecordProperty("bar", "C");
#if !defined(IUTEST_USE_GTEST)
        // ban list
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("name"       , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("tests"      , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("failures"   , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("disabled"   , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("skip"       , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("errors"     , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("time"       , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("timestamp"  , "C"), "Reserved key");
    IUTEST_EXPECT_NONFATAL_FAILURE( ::iutest::Test::RecordProperty("random_seed", "C"), "Reserved key");
#endif

    {
        const int ret = IUTEST_RUN_ALL_TESTS();
        if( ret != 0 ) return 1;
#if !defined(IUTEST_NO_RECORDPROPERTY_OUTSIDE_TESTMETHOD_LIFESPAN)
        if( !CheckProperty(iuutil::GetAdHocTestResult(), "bar", "C") )
        {
            printf("ad hoc test result is not recorded\n");
            return 1;
        }
#endif
    }
#if !defined(IUTEST_NO_RECORDPROPERTY_OUTSIDE_TESTMETHOD_LIFESPAN)
    {
        const int ret = IUTEST_RUN_ALL_TESTS();
        if( ret != 0 ) return 1;
        if( !CheckProperty(iuutil::GetAdHocTestResult(), "bar", "C") )
        {
            printf("ad hoc test result is cleared?\n");
            return 1;
        }
    }
    {
        IUTEST_INIT(&argc, argv);
        const int ret = IUTEST_RUN_ALL_TESTS();
        if( ret != 0 ) return 1;
#if !defined(IUTEST_USE_GTEST)
        if( CheckProperty(iuutil::GetAdHocTestResult(), "bar", "C") )
        {
            printf("ad hoc test result is not cleared?\n");
            return 1;
        }
#else
        if( !CheckProperty(iuutil::GetAdHocTestResult(), "bar", "C") )
        {
            printf("ad hoc test result is cleared? (iutest expect)\n");
            return 1;
        }
#endif
    }
#endif
    printf("*** Successful ***\n");
    return 0;
}
<|endoftext|>


<commit_before>#include <unistd.h>

#include <process.hpp>

#include <iostream>
#include <climits>
#include <cstdlib>
#include <stdexcept>

#include <glog/logging.h>

#include <boost/lexical_cast.hpp>

#include "fatal.hpp"
#include "master_detector.hpp"
#include "messages.hpp"

using namespace nexus;
using namespace nexus::internal;

using boost::lexical_cast;

MasterDetector::MasterDetector(const string &_servers, const string &_znode,
			       const PID &_pid, bool _contend)
  : servers(_servers), znode(_znode), pid(_pid), contend(_contend)
{
  zk = new ZooKeeper(servers, 10000, this);
}

MasterDetector::~MasterDetector()
{
  if (zk != NULL)
    delete zk;
}

void MasterDetector::process(ZooKeeper *zk, int type, int state,
			     const string &path)
{
  int ret;
  string result;

  static const string delimiter = "/";

  if ((state == ZOO_CONNECTED_STATE) && (type == ZOO_SESSION_EVENT)) {
    // Create directory path znodes as necessary.
    size_t index = znode.find(delimiter, 0);
    while (index < string::npos) {
      index = znode.find(delimiter, index+1);
      string prefix = znode.substr(0, index);
      ret = zk->create(prefix, "", ZOO_OPEN_ACL_UNSAFE, // ZOO_CREATOR_ALL_ACL, // needs authentication
		       0, &result);
      if (ret != ZOK && ret != ZNODEEXISTS)
	fatal("failed to create ZooKeeper znode! (%s)", zk->error(ret));
    }

    // Wierdness in ZooKeeper timing, let's check that everything is created.
    ret = zk->get(znode, false, &result, NULL);

    if (ret != ZOK)
      fatal("ZooKeeper not responding correctly (%s). "
	    "Make sure ZooKeeper is running on: %s",
	    zk->error(ret), servers.c_str());

    if (contend) {
      // We use the contend with the pid given in constructor.
      ret = zk->create(znode, pid, ZOO_OPEN_ACL_UNSAFE, // ZOO_CREATOR_ALL_ACL, // needs authentication
		       ZOO_SEQUENCE | ZOO_EPHEMERAL, &result);

      if (ret != ZOK)
	fatal("ZooKeeper not responding correctly (%s). "
	      "Make sure ZooKeeper is running on: %s",
	      zk->error(ret), servers.c_str());

      setMySeq(result);
      LOG(INFO) << "Created ephemeral/sequence:" << getMySeq();

      const string &s =
	Tuple<Process>::tupleToString(Tuple<Process>::pack<GOT_MASTER_SEQ>(getMySeq()));
      Process::post(pid, GOT_MASTER_SEQ, s.data(), s.size());
    }

    detectMaster();
  } else if ((state == ZOO_CONNECTED_STATE) && (type == ZOO_CHILD_EVENT)) {
    detectMaster();
  } else {
    LOG(INFO) << "Unimplemented watch event: (state is "
	      << state << " and type is " << type << ")";
  }
}

void MasterDetector::detectMaster()
{
  vector<string> results;

  int ret = zk->getChildren(znode, true, &results);

  if (ret != ZOK)
    LOG(ERROR) << "failed to get masters: " << zk->error(ret);
  else
    LOG(INFO) << "found " << results.size() << " registered masters";

  string masterSeq;
  long min = LONG_MAX;
  foreach (const string &result, results) {
    int i = lexical_cast<int>(result);
    if (i < min) {
      min = i;
      masterSeq = result;
    }
  }

  // No master present (lost or possibly hasn't come up yet).
  if (masterSeq.empty()) {
    const string &s =
      Tuple<Process>::tupleToString(Tuple<Process>::pack<NO_MASTER_DETECTED>());
    Process::post(pid, NO_MASTER_DETECTED, s.data(), s.size());
  } else if (masterSeq != currentMasterSeq) {
    currentMasterSeq = masterSeq;
    currentMasterPID = lookupMasterPID(masterSeq);

    // While trying to get the master PID, master might have crashed,
    // so PID might be empty.
    if (currentMasterPID == PID()) {
      const string &s =
	Tuple<Process>::tupleToString(Tuple<Process>::pack<NO_MASTER_DETECTED>());
      Process::post(pid, NO_MASTER_DETECTED, s.data(), s.size());
    } else {
      const string &s =
	Tuple<Process>::tupleToString(Tuple<Process>::pack<NEW_MASTER_DETECTED>(currentMasterSeq, currentMasterPID));
      Process::post(pid, NEW_MASTER_DETECTED, s.data(), s.size());
    }
  }
}

PID MasterDetector::lookupMasterPID(const string &seq) const
{
  CHECK(!seq.empty());

  int ret;
  string result;

  ret = zk->get(znode + seq, false, &result, NULL);

  if (ret != ZOK)
    LOG(ERROR) << "failed to fetch new master pid: " << zk->error(ret);
  else
    LOG(INFO) << "got new master pid: " << result;

  // TODO(benh): Automatic cast!
  return make_pid(result.c_str());
}

string MasterDetector::getCurrentMasterSeq() const {
  return currentMasterSeq;
}

PID MasterDetector::getCurrentMasterPID() const {
  return currentMasterPID;
}
<commit_msg>Another bug in the new FT port. Slash was missing after the /nxmaster znode making the master id parser go nuts.<commit_after>#include <unistd.h>

#include <process.hpp>

#include <iostream>
#include <climits>
#include <cstdlib>
#include <stdexcept>

#include <glog/logging.h>

#include <boost/lexical_cast.hpp>

#include "fatal.hpp"
#include "master_detector.hpp"
#include "messages.hpp"

using namespace nexus;
using namespace nexus::internal;

using boost::lexical_cast;

MasterDetector::MasterDetector(const string &_servers, const string &_znode,
			       const PID &_pid, bool _contend)
  : servers(_servers), znode(_znode), pid(_pid), contend(_contend)
{
  zk = new ZooKeeper(servers, 10000, this);
}

MasterDetector::~MasterDetector()
{
  if (zk != NULL)
    delete zk;
}

void MasterDetector::process(ZooKeeper *zk, int type, int state,
			     const string &path)
{
  int ret;
  string result;

  static const string delimiter = "/";

  if ((state == ZOO_CONNECTED_STATE) && (type == ZOO_SESSION_EVENT)) {
    // Create directory path znodes as necessary.
    size_t index = znode.find(delimiter, 0);
    while (index < string::npos) {
      index = znode.find(delimiter, index+1);
      string prefix = znode.substr(0, index);
      ret = zk->create(prefix, "", ZOO_OPEN_ACL_UNSAFE, // ZOO_CREATOR_ALL_ACL, // needs authentication
		       0, &result);
      if (ret != ZOK && ret != ZNODEEXISTS)
	fatal("failed to create ZooKeeper znode! (%s)", zk->error(ret));
    }

    // Wierdness in ZooKeeper timing, let's check that everything is created.
    ret = zk->get(znode, false, &result, NULL);

    if (ret != ZOK)
      fatal("ZooKeeper not responding correctly (%s). "
	    "Make sure ZooKeeper is running on: %s",
	    zk->error(ret), servers.c_str());

    if (contend) {
      // We use the contend with the pid given in constructor.
      ret = zk->create(znode, pid, ZOO_OPEN_ACL_UNSAFE, // ZOO_CREATOR_ALL_ACL, // needs authentication
		       ZOO_SEQUENCE | ZOO_EPHEMERAL, &result);

      if (ret != ZOK)
	fatal("ZooKeeper not responding correctly (%s). "
	      "Make sure ZooKeeper is running on: %s",
	      zk->error(ret), servers.c_str());

      setMySeq(result);
      LOG(INFO) << "Created ephemeral/sequence:" << getMySeq();

      const string &s =
	Tuple<Process>::tupleToString(Tuple<Process>::pack<GOT_MASTER_SEQ>(getMySeq()));
      Process::post(pid, GOT_MASTER_SEQ, s.data(), s.size());
    }

    detectMaster();
  } else if ((state == ZOO_CONNECTED_STATE) && (type == ZOO_CHILD_EVENT)) {
    detectMaster();
  } else {
    LOG(INFO) << "Unimplemented watch event: (state is "
	      << state << " and type is " << type << ")";
  }
}

void MasterDetector::detectMaster()
{
  vector<string> results;

  int ret = zk->getChildren(znode, true, &results);

  if (ret != ZOK)
    LOG(ERROR) << "failed to get masters: " << zk->error(ret);
  else
    LOG(INFO) << "found " << results.size() << " registered masters";

  string masterSeq;
  long min = LONG_MAX;
  foreach (const string &result, results) {
    int i = lexical_cast<int>(result);
    if (i < min) {
      min = i;
      masterSeq = result;
    }
  }

  // No master present (lost or possibly hasn't come up yet).
  if (masterSeq.empty()) {
    const string &s =
      Tuple<Process>::tupleToString(Tuple<Process>::pack<NO_MASTER_DETECTED>());
    Process::post(pid, NO_MASTER_DETECTED, s.data(), s.size());
  } else if (masterSeq != currentMasterSeq) {
    currentMasterSeq = masterSeq;
    currentMasterPID = lookupMasterPID(masterSeq);

    // While trying to get the master PID, master might have crashed,
    // so PID might be empty.
    if (currentMasterPID == PID()) {
      const string &s =
	Tuple<Process>::tupleToString(Tuple<Process>::pack<NO_MASTER_DETECTED>());
      Process::post(pid, NO_MASTER_DETECTED, s.data(), s.size());
    } else {
      const string &s =
	Tuple<Process>::tupleToString(Tuple<Process>::pack<NEW_MASTER_DETECTED>(currentMasterSeq, currentMasterPID));
      Process::post(pid, NEW_MASTER_DETECTED, s.data(), s.size());
    }
  }
}

PID MasterDetector::lookupMasterPID(const string &seq) const
{
  CHECK(!seq.empty());

  int ret;
  string result;

  ret = zk->get(znode + "/" + seq, false, &result, NULL);

  if (ret != ZOK)
    LOG(ERROR) << "failed to fetch new master pid: " << zk->error(ret);
  else
    LOG(INFO) << "got new master pid: " << result;

  // TODO(benh): Automatic cast!
  return make_pid(result.c_str());
}

string MasterDetector::getCurrentMasterSeq() const {
  return currentMasterSeq;
}

PID MasterDetector::getCurrentMasterPID() const {
  return currentMasterPID;
}
<|endoftext|>


<commit_before>//
//  Z80AllRAM.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 16/05/2017.
//  Copyright © 2017 Thomas Harte. All rights reserved.
//

#include "Z80AllRAM.hpp"
#include <algorithm>

using namespace CPU::Z80;

AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {}

int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
	switch(cycle->operation) {
		case BusOperation::ReadOpcode:
			printf("! ");
			check_address_for_trap(*cycle->address);
		case BusOperation::Read:
			printf("r %04x [%02x] AF:%04x BC:%04x DE:%04x HL:%04x SP:%04x\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::AF), get_value_of_register(CPU::Z80::Register::BC), get_value_of_register(CPU::Z80::Register::DE), get_value_of_register(CPU::Z80::Register::HL), get_value_of_register(CPU::Z80::Register::StackPointer));
			*cycle->value = memory_[*cycle->address];
		break;
		case BusOperation::Write:
			printf("w %04x\n", *cycle->address);
			memory_[*cycle->address] = *cycle->value;
		break;

		case BusOperation::Internal:
		break;

		default:
			printf("???\n");
		break;
	}
	return 0;
}
<commit_msg>This logging has outlived its usefulness for now.<commit_after>//
//  Z80AllRAM.cpp
//  Clock Signal
//
//  Created by Thomas Harte on 16/05/2017.
//  Copyright © 2017 Thomas Harte. All rights reserved.
//

#include "Z80AllRAM.hpp"
#include <algorithm>

using namespace CPU::Z80;

AllRAMProcessor::AllRAMProcessor() : ::CPU::AllRAMProcessor(65536) {}

int AllRAMProcessor::perform_machine_cycle(const MachineCycle *cycle) {
	switch(cycle->operation) {
		case BusOperation::ReadOpcode:
//			printf("! ");
			check_address_for_trap(*cycle->address);
		case BusOperation::Read:
//			printf("r %04x [%02x] AF:%04x BC:%04x DE:%04x HL:%04x SP:%04x\n", *cycle->address, memory_[*cycle->address], get_value_of_register(CPU::Z80::Register::AF), get_value_of_register(CPU::Z80::Register::BC), get_value_of_register(CPU::Z80::Register::DE), get_value_of_register(CPU::Z80::Register::HL), get_value_of_register(CPU::Z80::Register::StackPointer));
			*cycle->value = memory_[*cycle->address];
		break;
		case BusOperation::Write:
//			printf("w %04x\n", *cycle->address);
			memory_[*cycle->address] = *cycle->value;
		break;

		case BusOperation::Internal:
		break;

		default:
			printf("???\n");
		break;
	}
	return 0;
}
<|endoftext|>


<commit_before>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2021 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#ifndef __YLIKUUTIO_ONTOLOGY_FRAMEBUFFER_MODULE_HPP_INCLUDED
#define __YLIKUUTIO_ONTOLOGY_FRAMEBUFFER_MODULE_HPP_INCLUDED

#include "code/ylikuutio/opengl/ylikuutio_glew.hpp" // GLfloat, GLuint etc.

// Include standard headers
#include <stdint.h> // uint32_t etc.

namespace yli::ontology
{
    struct FramebufferModuleStruct;

    class FramebufferModule
    {
        public:
            // constructor.
            FramebufferModule(const yli::ontology::FramebufferModuleStruct& framebuffer_module_struct);

            FramebufferModule(const FramebufferModule&) = delete;            // Delete copy constructor.
            FramebufferModule &operator=(const FramebufferModule&) = delete; // Delete copy assignment.

            // destructor.
            ~FramebufferModule();

            void create_framebuffer_object();
            void bind() const;
            bool get_is_initialized() const;
            void initialize(const float red, const float green, const float blue, const float alpha);

            // This method returns current `texture_width`.
            uint32_t get_texture_width() const;

            // This method sets `texture_width`.
            void set_texture_width(const uint32_t texture_width);

            // This method returns current `texture_height`.
            uint32_t get_texture_height() const;

            // This method sets `texture_height`.
            void set_texture_height(const uint32_t texture_height);

            bool get_in_use() const;

        private:
            uint32_t texture_width;
            uint32_t texture_height;

            GLuint framebuffer  { 0 };
            GLuint texture      { 0 };
            GLuint renderbuffer { 0 };

            bool in_use;
            bool is_initialized { false };
    };
}

#endif
<commit_msg>`FramebufferModule`: make 1 parameter constructor `explicit`.<commit_after>// Ylikuutio - A 3D game and simulation engine.
//
// Copyright (C) 2015-2021 Antti Nuortimo.
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as
// published by the Free Software Foundation, either version 3 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program.  If not, see <https://www.gnu.org/licenses/>.

#ifndef __YLIKUUTIO_ONTOLOGY_FRAMEBUFFER_MODULE_HPP_INCLUDED
#define __YLIKUUTIO_ONTOLOGY_FRAMEBUFFER_MODULE_HPP_INCLUDED

#include "code/ylikuutio/opengl/ylikuutio_glew.hpp" // GLfloat, GLuint etc.

// Include standard headers
#include <stdint.h> // uint32_t etc.

namespace yli::ontology
{
    struct FramebufferModuleStruct;

    class FramebufferModule
    {
        public:
            // constructor.
            explicit FramebufferModule(const yli::ontology::FramebufferModuleStruct& framebuffer_module_struct);

            FramebufferModule(const FramebufferModule&) = delete;            // Delete copy constructor.
            FramebufferModule &operator=(const FramebufferModule&) = delete; // Delete copy assignment.

            // destructor.
            ~FramebufferModule();

            void create_framebuffer_object();
            void bind() const;
            bool get_is_initialized() const;
            void initialize(const float red, const float green, const float blue, const float alpha);

            // This method returns current `texture_width`.
            uint32_t get_texture_width() const;

            // This method sets `texture_width`.
            void set_texture_width(const uint32_t texture_width);

            // This method returns current `texture_height`.
            uint32_t get_texture_height() const;

            // This method sets `texture_height`.
            void set_texture_height(const uint32_t texture_height);

            bool get_in_use() const;

        private:
            uint32_t texture_width;
            uint32_t texture_height;

            GLuint framebuffer  { 0 };
            GLuint texture      { 0 };
            GLuint renderbuffer { 0 };

            bool in_use;
            bool is_initialized { false };
    };
}

#endif
<|endoftext|>


<commit_before>#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/time.h>

#include <util.h>

#include <FtdiLink.hh>
#include <Proto.hh>

class Handler : public ProtoHandler {
private:
	uint8_t status;
	bool done;
public:
	virtual ~Handler() {}

	void resetDone(void) {
		done = false;
	}

	bool isDone(void) {
		return done;
	}

	uint8_t getStatus(void) {
		return status;
	}

	virtual void relay(uint8_t idx, uint8_t state) {
	}

	virtual void light(uint8_t idx, uint8_t val) {
	}

	virtual void dpot(uint8_t idx, uint8_t val) {
	}

	virtual void resp(struct proto_packet *pkt) {
		switch (pkt->cmd) {
		case PROTO_CMD_GET_STATUS:
		case PROTO_CMD_SWITCH_QUERY:
		case PROTO_CMD_ADC_QUERY_LO:
		case PROTO_CMD_ADC_QUERY_HI:
			status = pkt->val;
			done = true;
			break;
		}
	}
 };

 void usage(void)
 {
   fprintf(stderr,
	   "usage: sender (<command> <args>*)*\n"
	   "\n"
	   "commands:\n"
	   "    get_status <addr>\n"
	   "    get_switch <addr>\n"
	   "    get_adc <addr> <idx>\n"
	   "    set_relay <addr> <val>\n"
	   "    clear_relay <addr> <val>\n"
	   "    set_dpot <addr> <idx> <val>\n"
	   "    set_addr <addr> <new_addr>\n");
 }

bool get_uint8(char *s, uint8_t *val)
{
	char *endp;
	long v;

	v = strtol(s, &endp, 0);
	if (endp == NULL || endp == s)
		 return false;
	if (v < 0 || v > 0xff)
		 return false;

	*val = v & 0xff;
	return true;
}

void do_read(Proto *p, Handler *h, uint8_t addr)
{
	printf("do_read(0x%02x) =", addr);
	h->resetDone();
	p->getStatus(addr);
	p->flush();
	while (!h->isDone()) {
		p->waitForMsg(100);
	}
	printf("0x%02x\n", h->getStatus());
}

void do_write(Proto *p, uint8_t addr)
{
	printf("do_write(0x%02x)\n", addr);
	p->setRelay(addr, 0x0);
}

static uint8_t addrs[] = {
	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99,
};

#define SEEEP 100000
int main(int argc, char *argv[])
{
	FtdiLink link(0x0403, 0x6010, INTERFACE_A);
	Handler h;
	Proto p(&link, &h, NULL, 0, 0, true);
	unsigned int i;

	while (1) {
		for (i = 0; i < ARRAY_SIZE(addrs); i++) {
			p.updateRelay(addrs[i], 0x1);
			p.flush();
			usleep(100000);
			p.updateRelay(addrs[i], 0x2);
			p.flush();
			usleep(100000);
			if (addrs[i] == 0x99)
				continue;
			p.updateRelay(addrs[i], 0x4);
			p.flush();
			usleep(100000);
		}
	}

	return 0;
}
<commit_msg>take sprakle poofers out of poofertest.cc and add define for delay<commit_after>#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

#include <sys/time.h>

#include <util.h>

#include <FtdiLink.hh>
#include <Proto.hh>

class Handler : public ProtoHandler {
private:
	uint8_t status;
	bool done;
public:
	virtual ~Handler() {}

	void resetDone(void) {
		done = false;
	}

	bool isDone(void) {
		return done;
	}

	uint8_t getStatus(void) {
		return status;
	}

	virtual void relay(uint8_t idx, uint8_t state) {
	}

	virtual void light(uint8_t idx, uint8_t val) {
	}

	virtual void dpot(uint8_t idx, uint8_t val) {
	}

	virtual void resp(struct proto_packet *pkt) {
		switch (pkt->cmd) {
		case PROTO_CMD_GET_STATUS:
		case PROTO_CMD_SWITCH_QUERY:
		case PROTO_CMD_ADC_QUERY_LO:
		case PROTO_CMD_ADC_QUERY_HI:
			status = pkt->val;
			done = true;
			break;
		}
	}
 };

 void usage(void)
 {
   fprintf(stderr,
	   "usage: sender (<command> <args>*)*\n"
	   "\n"
	   "commands:\n"
	   "    get_status <addr>\n"
	   "    get_switch <addr>\n"
	   "    get_adc <addr> <idx>\n"
	   "    set_relay <addr> <val>\n"
	   "    clear_relay <addr> <val>\n"
	   "    set_dpot <addr> <idx> <val>\n"
	   "    set_addr <addr> <new_addr>\n");
 }

bool get_uint8(char *s, uint8_t *val)
{
	char *endp;
	long v;

	v = strtol(s, &endp, 0);
	if (endp == NULL || endp == s)
		 return false;
	if (v < 0 || v > 0xff)
		 return false;

	*val = v & 0xff;
	return true;
}

void do_read(Proto *p, Handler *h, uint8_t addr)
{
	printf("do_read(0x%02x) =", addr);
	h->resetDone();
	p->getStatus(addr);
	p->flush();
	while (!h->isDone()) {
		p->waitForMsg(100);
	}
	printf("0x%02x\n", h->getStatus());
}

void do_write(Proto *p, uint8_t addr)
{
	printf("do_write(0x%02x)\n", addr);
	p->setRelay(addr, 0x0);
}

static uint8_t addrs[] = {
	0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,// 0x98, 0x99,
};

#define SLEEP 100000
int main(int argc, char *argv[])
{
	FtdiLink link(0x0403, 0x6010, INTERFACE_A);
	Handler h;
	Proto p(&link, &h, NULL, 0, 0, true);
	unsigned int i;

	while (1) {
		for (i = 0; i < ARRAY_SIZE(addrs); i++) {
			p.updateRelay(addrs[i], 0x1);
			p.flush();
			usleep(SLEEP);
			p.updateRelay(addrs[i], 0x2);
			p.flush();
			usleep(SLEEP);
			if (addrs[i] == 0x99)
				continue;
			p.updateRelay(addrs[i], 0x4);
			p.flush();
			usleep(SLEEP);
		}
	}

	return 0;
}
<|endoftext|>


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

#include <xeumeuleu/xml.hpp>
#ifdef _MSC_VER
#   pragma warning( push, 0 )
#endif
#include <boost/date_time/posix_time/posix_time.hpp>
#ifdef _MSC_VER
#   pragma warning( pop )
#endif
#include <iostream>

using namespace boost::posix_time;

namespace
{
//    const int FILES = 100000;
//    const int NODES = 1;
    const int FILES = 1;
    const int NODES = 1000000;
}

int main()
{
    const ptime start = microsec_clock::local_time();
    for( int file = 0; file < FILES; ++file )
    {
        xml::xofstream xos( "bench.xml" );
        xos << xml::start( "root" );
        for( int node = 0; node < NODES; ++node )
            xos << xml::start( "element" )
                    << 12.f
                    << xml::attribute( "id", 27.f )
                << xml::end;
    }
    const time_duration duration = microsec_clock::local_time() - start;
    std::cout << "duration : " << duration << std::endl;
    return EXIT_SUCCESS;
}
<commit_msg>Updated benchmark to also compute reads<commit_after>/*
 *   Copyright (c) 2007, Mathieu Champlon
 *   All rights reserved.
 *
 *   Redistribution  and use  in source  and binary  forms, with  or without
 *   modification, are permitted provided  that the following conditions are
 *   met :
 *
 *   . Redistributions  of  source  code  must  retain  the  above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   . Redistributions in  binary form  must reproduce  the above  copyright
 *     notice, this list of conditions  and the following disclaimer in  the
 *     documentation and/or other materials provided with the distribution.
 *
 *   . Neither  the name  of  the  copyright  holders  nor the names  of the
 *     contributors may be used to endorse  or promote products derived from
 *     this software without specific prior written permission.
 *
 *   THIS SOFTWARE  IS  PROVIDED  BY THE  COPYRIGHT HOLDERS  AND CONTRIBUTORS
 *   ``AS IS''  AND ANY  EXPRESS OR  IMPLIED WARRANTIES,  INCLUDING,  BUT NOT
 *   LIMITED TO, THE IMPLIED  WARRANTIES  OF MERCHANTABILITY AND  FITNESS FOR
 *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE THE COPYRIGHT
 *   OWNERS OR CONTRIBUTORS  BE LIABLE FOR ANY  DIRECT, INDIRECT, INCIDENTAL,
 *   SPECIAL,  EXEMPLARY,  OR  CONSEQUENTIAL   DAMAGES  (INCLUDING,  BUT  NOT
 *   LIMITED TO,  PROCUREMENT OF SUBSTITUTE  GOODS OR SERVICES;  LOSS OF USE,
 *   DATA, OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED  AND ON  ANY
 *   THEORY  OF  LIABILITY,  WHETHER IN  CONTRACT,  STRICT LIABILITY, OR TORT
 *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY  WAY  OUT OF  THE USE
 *   OF THIS SOFTWARE, EVEN  IF  ADVISED OF  THE POSSIBILITY  OF SUCH DAMAGE.
 */

#include <xeumeuleu/xml.hpp>
#ifdef _MSC_VER
#   pragma warning( push, 0 )
#endif
#include <boost/date_time/posix_time/posix_time.hpp>
#ifdef _MSC_VER
#   pragma warning( pop )
#endif
#include <iostream>

using namespace boost::posix_time;

namespace
{
//    const int FILES = 100000;
//    const int NODES = 1;
    const int FILES = 1;
    const int NODES = 1000000;
}

int main()
{
    const ptime start = microsec_clock::local_time();
    for( int file = 0; file < FILES; ++file )
    {
        {
            xml::xofstream xos( "bench.xml" );
            xos << xml::start( "root" );
            for( int node = 0; node < NODES; ++node )
                xos << xml::start( "element" )
                        << 12.f
                        << xml::attribute( "id", 27.f )
                    << xml::end;
        }
        {
            xml::xifstream xis( "bench.xml" );
            xis >> xml::start( "root" );
            float value;
            for( int node = 0; node < NODES; ++node )
                xis >> xml::start( "element" )
                        >> value
                        >> xml::attribute( "id", value )
                    >> xml::end;
        }
    }
    const time_duration duration = microsec_clock::local_time() - start;
    std::cout << "duration : " << duration << std::endl;
    return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// RUN: clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s

// CHECK1: error: error reading '{{.*}}.nonexistent.cpp' [clang-diagnostic-error]
// CHECK2: error: unknown argument: '-fan-unknown-option' [clang-diagnostic-error]
// CHECK3: error: unknown argument: '-fan-unknown-option' [clang-diagnostic-error]

// CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion]
// CHECK3: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' changes value
int a = 1.5;

// CHECK2: :[[@LINE+2]]:11: warning: single-argument constructors must be marked explicit
// CHECK3: :[[@LINE+1]]:11: warning: single-argument constructors must be marked explicit
class A { A(int) {} };

#define MACRO_FROM_COMMAND_LINE
// CHECK4: :[[@LINE-1]]:9: warning: 'MACRO_FROM_COMMAND_LINE' macro redefined
<commit_msg>Modify test so that it looks for patterns in stderr as well<commit_after>// RUN: clang-tidy -checks='-*,modernize-use-override' %s.nonexistent.cpp -- | FileCheck -check-prefix=CHECK1 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,clang-diagnostic-*,google-explicit-constructor' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK2 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,google-explicit-constructor,clang-diagnostic-literal-conversion' %s -- -fan-unknown-option 2>&1 | FileCheck -check-prefix=CHECK3 -implicit-check-not='{{warning:|error:}}' %s
// RUN: clang-tidy -checks='-*,modernize-use-override,clang-diagnostic-macro-redefined' %s -- -DMACRO_FROM_COMMAND_LINE | FileCheck -check-prefix=CHECK4 -implicit-check-not='{{warning:|error:}}' %s

// CHECK1: error: error reading '{{.*}}.nonexistent.cpp' [clang-diagnostic-error]
// CHECK2: error: unknown argument: '-fan-unknown-option'
// CHECK3: error: unknown argument: '-fan-unknown-option'

// CHECK2: :[[@LINE+2]]:9: warning: implicit conversion from 'double' to 'int' changes value from 1.5 to 1 [clang-diagnostic-literal-conversion]
// CHECK3: :[[@LINE+1]]:9: warning: implicit conversion from 'double' to 'int' changes value
int a = 1.5;

// CHECK2: :[[@LINE+2]]:11: warning: single-argument constructors must be marked explicit
// CHECK3: :[[@LINE+1]]:11: warning: single-argument constructors must be marked explicit
class A { A(int) {} };

#define MACRO_FROM_COMMAND_LINE
// CHECK4: :[[@LINE-1]]:9: warning: 'MACRO_FROM_COMMAND_LINE' macro redefined
<|endoftext|>


<commit_before>class Solution {
public:
    /**
     * @param s: a string
     * @return: an integer
     */
    std::map<char, int> mapCtoSub;
    int lengthOfLongestSubstring(string s) {
        // write your code here
        int i,j,k;

    }
};<commit_msg>solving 384<commit_after>class Solution {
public:
    /**
     * @param s: a string
     * @return: an integer
     */
    std::map<char, int> mapCtoSub;
    int lengthOfLongestSubstring(string s) {
        // write your code here
        int i,j,k,l_s=s.size();
        int max_len=0;
        for (char c='a';c<='z';c++)
        	mapCtoSub[c]=-1;

        for (i=0,j=0;j++;j<=){
        	if (mapCtoSub[s[j]]>-1) i=max(i,mapCtoSub[s[j]]);
        	int tmp_len=j-i;

        }

    }
};<|endoftext|>


<commit_before>#include "keyconmode_select.h"

void Keyconmode_select::Change_to_keyconmode() {
	if (*menue_var == this_menue_var && (CheckHitKey(KEY_INPUT_Z) || CheckHitKey(KEY_INPUT_RETURN) || CheckHitKey(KEY_INPUT_SPACE) || *p_push_joyshot_flag == true)) {
		*p_system_var = 1;
	}
}

void Keyconmode_select::Getinput_param() {
	input_pad = GetJoypadInputState(DX_INPUT_PAD1);
}

void Keyconmode_select::Judgeinput_param() {
	for (int i = 4; i < 32; i++) {
		if ((input_pad & (1 << i)) != 0) {
			str_directinput_pad[keycon_select_var] = input_pad;
			str_input_pad[keycon_select_var] = i;
			break;
		}
	}
}

void Keyconmode_select::Check_push_bottan() {
	if (CheckHitKey(KEY_INPUT_UP) == 0 && CheckHitKey(KEY_INPUT_DOWN) == 0 && *p_push_joyup_flag == false && *p_push_joydown_flag == false) {
		input_flag = false;
	}
}

void Keyconmode_select::Keycon_select() {
	if ((CheckHitKey(KEY_INPUT_DOWN) || *p_push_joydown_flag) && input_flag == false) {
		keycon_select_var++;
		input_flag = true;
	}
	if ((CheckHitKey(KEY_INPUT_UP) || *p_push_joyup_flag) && input_flag == false) {
		keycon_select_var--;
		input_flag = true;
	}

	if (keycon_select_var < 0) {
		keycon_select_var = KEYCON_MODE_NUM;
	}
	else if (keycon_select_var > KEYCON_MODE_NUM) {
		keycon_select_var = 0;
	}
}

void Keyconmode_select::Keycon_mode() {
	DrawRotaGraph2(0, 0, 0, 0, *p_define_srsize, 0, *keycon_backgr, true, false);
	for (int i = 0; i < KEYCON_MODE_NUM + 1; i++) {
		if (i < KEYCON_MODE_NUM) {
			if (keycon_select_var == i) {
				DrawRectGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, 100 * str_input_pad[i], 0, 100, 100, *keycon_numgr, true, false);
			}
			else {
				SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
				DrawRectGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, 100 * str_input_pad[i], 0, 100, 100, *keycon_numgr, true, false);
				SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
			}
		}
		else {
			if (keycon_select_var == i) {
				DrawGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, *keycon_exitgr, true);
			}
			else {
				SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
				DrawGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, *keycon_exitgr, true);
				SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
			}
		}
	}
}

void Keyconmode_select::Exit() {
	if (keycon_select_var == KEYCON_MODE_NUM) {

	}
}

void Keyconmode_select::Run() {
	Getinput_param();
	Judgeinput_param();
	Keycon_select();
	Keycon_mode();
	Check_push_bottan();
}<commit_msg>keyconfigからtitleに移動できる<commit_after>#include "keyconmode_select.h"

void Keyconmode_select::Change_to_keyconmode() {
	if (*menue_var == this_menue_var && (CheckHitKey(KEY_INPUT_Z) || CheckHitKey(KEY_INPUT_RETURN) || CheckHitKey(KEY_INPUT_SPACE) || *p_push_joyshot_flag == true)) {
		*p_system_var = 1;
	}
}

void Keyconmode_select::Getinput_param() {
	input_pad = GetJoypadInputState(DX_INPUT_PAD1);
}

void Keyconmode_select::Judgeinput_param() {
	for (int i = 4; i < 32; i++) {
		if ((input_pad & (1 << i)) != 0) {
			str_directinput_pad[keycon_select_var] = input_pad;
			str_input_pad[keycon_select_var] = i;
			break;
		}
	}
}

void Keyconmode_select::Check_push_bottan() {
	if (CheckHitKey(KEY_INPUT_UP) == 0 && CheckHitKey(KEY_INPUT_DOWN) == 0 && *p_push_joyup_flag == false && *p_push_joydown_flag == false) {
		input_flag = false;
	}
}

void Keyconmode_select::Keycon_select() {
	if ((CheckHitKey(KEY_INPUT_DOWN) || *p_push_joydown_flag) && input_flag == false) {
		keycon_select_var++;
		input_flag = true;
	}
	if ((CheckHitKey(KEY_INPUT_UP) || *p_push_joyup_flag) && input_flag == false) {
		keycon_select_var--;
		input_flag = true;
	}

	if (keycon_select_var < 0) {
		keycon_select_var = KEYCON_MODE_NUM;
	}
	else if (keycon_select_var > KEYCON_MODE_NUM) {
		keycon_select_var = 0;
	}
}

void Keyconmode_select::Keycon_mode() {
	DrawRotaGraph2(0, 0, 0, 0, *p_define_srsize, 0, *keycon_backgr, true, false);
	for (int i = 0; i < KEYCON_MODE_NUM + 1; i++) {
		if (i < KEYCON_MODE_NUM) {
			if (keycon_select_var == i) {
				DrawRectGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, 100 * str_input_pad[i], 0, 100, 100, *keycon_numgr, true, false);
			}
			else {
				SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
				DrawRectGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, 100 * str_input_pad[i], 0, 100, 100, *keycon_numgr, true, false);
				SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
			}
		}
		else {
			if (keycon_select_var == i) {
				DrawGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, *keycon_exitgr, true);
			}
			else {
				SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
				DrawGraph(KEYCON_MODE_DRAW_X, KEYCON_MODE_DRAW_Y + KEYCON_MDDE_MOVE_DIST * i, *keycon_exitgr, true);
				SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
			}
		}
	}
}

void Keyconmode_select::Exit() {
	if (keycon_select_var == KEYCON_MODE_NUM && (CheckHitKey(KEY_INPUT_Z) || CheckHitKey(KEY_INPUT_RETURN) || CheckHitKey(KEY_INPUT_SPACE) || *p_push_joyshot_flag == true)) {
		*p_system_var = 0;
	}
}

void Keyconmode_select::Run() {
	Getinput_param();
	Judgeinput_param();
	Keycon_select();
	Exit();
	Keycon_mode();
	Check_push_bottan();
}<|endoftext|>


<commit_before>#include "FAP.h"

#include "Util.h"

namespace Neolib {

	FastAPproximation::FastAPproximation() {

	}

	void FastAPproximation::addUnitPlayer1(FAPUnit fu) {
		player1.push_back(fu);
	}

	void FastAPproximation::addUnitPlayer2(FAPUnit fu) {
		player2.push_back(fu);
	}

	void FastAPproximation::simulate(int nFrames) {
		while (nFrames--) {
			if (!player1.size() || !player2.size())
				break;

			didSomething = false;

			isimulate();

			if (!didSomething)
				break;
		}
	}

	int FastAPproximation::getStatus() {
		int score = 0;

		for (auto & u : player1)
			if (u.health && u.maxHealth)
				score += (u.score * u.health) / u.maxHealth;

		for (auto & u : player2)
			if (u.health && u.maxHealth)
				score -= (u.score * u.health) / u.maxHealth;

		return score;
	}

	std::pair<std::vector<FastAPproximation::FAPUnit>*, std::vector<FastAPproximation::FAPUnit>*> FastAPproximation::getState() {
		return { &player1, &player2 };
	}

	void FastAPproximation::clearState() {
		player1.clear(), player2.clear();
	}

	void FastAPproximation::dealDamage(const FastAPproximation::FAPUnit &fu, int damage, BWAPI::DamageType damageType) const {
		if (fu.shields >= damage - fu.shieldArmor) {
			fu.shields -= damage - fu.shieldArmor;
			return;
		}
		else if(fu.shields) {
			damage -= (fu.shields + fu.shieldArmor);
			fu.shields = 0;
		}

		if (!damage)
			return;

		switch (damageType) {
			case BWAPI::DamageTypes::Concussive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Large:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;

			case BWAPI::DamageTypes::Explosive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Small:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;
		}

		fu.health -= MAX(1, damage - fu.armor);
	}

	int FastAPproximation::dist(const FastAPproximation::FAPUnit &u1, const FastAPproximation::FAPUnit &u2) const {
		return (int)sqrt((u1.x - u2.x)*(u1.x - u2.x) + (u1.y - u2.y)*(u1.y - u2.y));
	}

	void FastAPproximation::unitsim(const FastAPproximation::FAPUnit &fu, std::vector <FastAPproximation::FAPUnit> &enemyUnits) {
		if (fu.attackCooldownRemaining) {
			didSomething = true;
			return;
		}

		auto closestEnemy = enemyUnits.end();
		int closestDist;

		for (auto enemyIt = enemyUnits.begin(); enemyIt != enemyUnits.end(); ++ enemyIt) {
			if (enemyIt->flying) {
				if (fu.airDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.airMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
			else {
				if (fu.groundDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.groundMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
		}

		if (closestEnemy != enemyUnits.end() && closestDist < fu.speed && !(fu.x == closestEnemy->x && fu.y == closestEnemy->y)) {
			fu.x = closestEnemy->x;
			fu.y = closestEnemy->y;
			closestDist = 0;

			didSomething = true;
		}

		if (closestEnemy != enemyUnits.end() && closestDist <= (closestEnemy->flying ? fu.groundMaxRange : fu.airMinRange)) {
			if (closestEnemy->flying)
				dealDamage(*closestEnemy, fu.airDamage, fu.airDamageType), fu.attackCooldownRemaining = fu.airCooldown;
			else
				dealDamage(*closestEnemy, fu.groundDamage, fu.groundDamageType), fu.attackCooldownRemaining = fu.groundCooldown;

			if (closestEnemy->health < 1) {
				*closestEnemy = enemyUnits.back();
				enemyUnits.pop_back();
			}

			didSomething = true;
			return;
		}
		else if(closestEnemy != enemyUnits.end()) {
			int dx = closestEnemy->x - fu.x, dy = closestEnemy->y - fu.y;
			if (dx || dy) {
				fu.x += (int)(((float)dx / sqrt(dx*dx + dy*dy)) * fu.speed);
				fu.y += (int)(((float)dy / sqrt(dx*dx + dy*dy)) * fu.speed);

				didSomething = true;
				return;
			}
		}
	}

	void FastAPproximation::isimulate() {
		for (auto &fu : player1)
			unitsim(fu, player2);

		for (auto &fu : player2)
			unitsim(fu, player1);

		for (auto &fu : player1)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;

		for (auto &fu : player2)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;
	}

	FastAPproximation::FAPUnit::FAPUnit(BWAPI::Unit u): FAPUnit(EnemyData(u)) {

	}

	FastAPproximation::FAPUnit::FAPUnit(EnemyData ed) :
		x(ed.lastPosition.x),
		y(ed.lastPosition.y),

		speed((int)ed.lastPlayer->topSpeed(ed.lastType)),

		health(ed.expectedHealth()),
		maxHealth(ed.lastType.maxHitPoints()),

		shields(ed.expectedShields()),
		shieldArmor(ed.lastPlayer->getUpgradeLevel(BWAPI::UpgradeTypes::Protoss_Plasma_Shields)),
		maxShields(ed.lastType.maxShields()),
		armor(ed.lastPlayer->armor(ed.lastType)),
		flying(ed.lastType.isFlyer()),

		groundDamage(ed.lastPlayer->damage(ed.lastType.groundWeapon())),
		groundCooldown(ed.lastType.groundWeapon().damageFactor() && ed.lastType.maxGroundHits() ? ed.lastPlayer->weaponDamageCooldown(ed.lastType) / (ed.lastType.groundWeapon().damageFactor() * ed.lastType.maxGroundHits()) : 0),
		//groundInnerRadius(ed.lastType.groundWeapon().innerSplashRadius()),
		//groundOuterRadius(ed.lastType.groundWeapon().outerSplashRadius()),
		groundMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.groundWeapon())),
		groundMinRange(ed.lastType.groundWeapon().minRange()),
		groundDamageType(ed.lastType.groundWeapon().damageType()),

		airDamage(ed.lastPlayer->damage(ed.lastType.airWeapon())),
		airCooldown(ed.lastType.airWeapon().damageFactor() && ed.lastType.maxAirHits() ? ed.lastType.airWeapon().damageCooldown() / (ed.lastType.airWeapon().damageFactor() * ed.lastType.maxAirHits()) : 0),
		//airInnerRadius(ed.lastType.airWeapon().innerSplashRadius()),
		//airOuterRadius(ed.lastType.airWeapon().outerSplashRadius()),
		airMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.airWeapon())),
		airMinRange(ed.lastType.airWeapon().minRange()),
		airDamageType(ed.lastType.airWeapon().damageType()),

		score(ed.lastType.destroyScore()) {

		static int nextId = 0;
		id = nextId++;

		switch (ed.lastType) {
			case BWAPI::UnitTypes::Protoss_Carrier:
				groundDamage = ed.lastPlayer->damage(BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon());
				groundCooldown = BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon().damageCooldown() / 8;
				groundMaxRange = 32 * 8;

				airDamage = groundDamage;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Terran_Bunker:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Gauss_Rifle);
				groundCooldown = BWAPI::UnitTypes::Terran_Marine.groundWeapon().damageCooldown() / 4;
				groundMaxRange = ed.lastPlayer->weaponMaxRange(BWAPI::UnitTypes::Terran_Marine.groundWeapon()) + 32;

				airDamage = groundDamage;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Protoss_Reaver:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Scarab);
				break;

			default:
				break;
		}

		groundDamage *= 2;
		airDamage *= 2;

		shieldArmor *= 2;
		armor *= 2;

		health *= 2;
		shields *= 2;
	}

	FastAPproximation::FAPUnit &FastAPproximation::FAPUnit::operator=(const FAPUnit & other) {
		x = other.x, y = other.y;
		health = other.health, maxHealth = other.maxHealth;
		shields = other.shields, maxShields = other.maxShields;
		speed = other.speed, armor = other.armor, flying = other.flying, unitSize = other.unitSize;
		groundDamage = other.groundDamage, groundCooldown = other.groundCooldown, groundMaxRange = other.groundMaxRange, groundMinRange = other.groundMinRange, groundDamageType = other.groundDamageType;
		airDamage = other.airDamage, airCooldown = other.airCooldown, airMaxRange = other.airMaxRange, airMinRange = other.airMinRange, airDamageType = other.airDamageType;
		score = other.score;
		attackCooldownRemaining = other.attackCooldownRemaining;

		return *this;
	}

	bool FastAPproximation::FAPUnit::operator<(const FAPUnit & other) const {
		return id < other.id;
	}

}
<commit_msg>Fix for infinite loop<commit_after>#include "FAP.h"

#include "Util.h"

namespace Neolib {

	FastAPproximation::FastAPproximation() {

	}

	void FastAPproximation::addUnitPlayer1(FAPUnit fu) {
		player1.push_back(fu);
	}

	void FastAPproximation::addUnitPlayer2(FAPUnit fu) {
		player2.push_back(fu);
	}

	void FastAPproximation::simulate(int nFrames) {
		while (nFrames--) {
			if (!player1.size() || !player2.size())
				break;

			didSomething = false;

			isimulate();

			if (!didSomething)
				break;
		}
	}

	int FastAPproximation::getStatus() {
		int score = 0;

		for (auto & u : player1)
			if (u.health && u.maxHealth)
				score += (u.score * u.health) / u.maxHealth;

		for (auto & u : player2)
			if (u.health && u.maxHealth)
				score -= (u.score * u.health) / u.maxHealth;

		return score;
	}

	std::pair<std::vector<FastAPproximation::FAPUnit>*, std::vector<FastAPproximation::FAPUnit>*> FastAPproximation::getState() {
		return { &player1, &player2 };
	}

	void FastAPproximation::clearState() {
		player1.clear(), player2.clear();
	}

	void FastAPproximation::dealDamage(const FastAPproximation::FAPUnit &fu, int damage, BWAPI::DamageType damageType) const {
		if (fu.shields >= damage - fu.shieldArmor) {
			fu.shields -= damage - fu.shieldArmor;
			return;
		}
		else if(fu.shields) {
			damage -= (fu.shields + fu.shieldArmor);
			fu.shields = 0;
		}

		if (!damage)
			return;

		switch (damageType) {
			case BWAPI::DamageTypes::Concussive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Large:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;

			case BWAPI::DamageTypes::Explosive:
				switch (fu.unitSize) {
					case BWAPI::UnitSizeTypes::Small:
						damage = damage / 2;
						break;
					case BWAPI::UnitSizeTypes::Medium:
						damage = (damage * 3) / 4;
						break;
				}
				break;
		}

		fu.health -= MAX(1, damage - fu.armor);
	}

	int FastAPproximation::dist(const FastAPproximation::FAPUnit &u1, const FastAPproximation::FAPUnit &u2) const {
		return (int)sqrt((u1.x - u2.x)*(u1.x - u2.x) + (u1.y - u2.y)*(u1.y - u2.y));
	}

	void FastAPproximation::unitsim(const FastAPproximation::FAPUnit &fu, std::vector <FastAPproximation::FAPUnit> &enemyUnits) {
		if (fu.attackCooldownRemaining) {
			didSomething = true;
			return;
		}

		auto closestEnemy = enemyUnits.end();
		int closestDist;

		for (auto enemyIt = enemyUnits.begin(); enemyIt != enemyUnits.end(); ++ enemyIt) {
			if (enemyIt->flying) {
				if (fu.airDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.airMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
			else {
				if (fu.groundDamage) {
					int d = dist(fu, *enemyIt);
					if ((closestEnemy == enemyUnits.end() || d < closestDist) && d >= fu.groundMinRange) {
						closestDist = d;
						closestEnemy = enemyIt;
					}
				}
			}
		}

		if (closestEnemy != enemyUnits.end() && closestDist <= fu.speed && !(fu.x == closestEnemy->x && fu.y == closestEnemy->y)) {
			fu.x = closestEnemy->x;
			fu.y = closestEnemy->y;
			closestDist = 0;

			didSomething = true;
		}

		if (closestEnemy != enemyUnits.end() && closestDist <= (closestEnemy->flying ? fu.groundMaxRange : fu.airMinRange)) {
			if (closestEnemy->flying)
				dealDamage(*closestEnemy, fu.airDamage, fu.airDamageType), fu.attackCooldownRemaining = fu.airCooldown;
			else
				dealDamage(*closestEnemy, fu.groundDamage, fu.groundDamageType), fu.attackCooldownRemaining = fu.groundCooldown;

			if (closestEnemy->health < 1) {
				*closestEnemy = enemyUnits.back();
				enemyUnits.pop_back();
			}

			didSomething = true;
			return;
		}
		else if(closestEnemy != enemyUnits.end() && closestDist > fu.speed) {
			int dx = closestEnemy->x - fu.x, dy = closestEnemy->y - fu.y;
			if (dx || dy) {
				fu.x += (int)(((float)dx / sqrt(dx*dx + dy*dy)) * fu.speed);
				fu.y += (int)(((float)dy / sqrt(dx*dx + dy*dy)) * fu.speed);

				didSomething = true;
				return;
			}
		}
	}

	void FastAPproximation::isimulate() {
		for (auto &fu : player1)
			unitsim(fu, player2);

		for (auto &fu : player2)
			unitsim(fu, player1);

		for (auto &fu : player1)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;

		for (auto &fu : player2)
			if (fu.attackCooldownRemaining)
				--fu.attackCooldownRemaining;
	}

	FastAPproximation::FAPUnit::FAPUnit(BWAPI::Unit u): FAPUnit(EnemyData(u)) {

	}

	FastAPproximation::FAPUnit::FAPUnit(EnemyData ed) :
		x(ed.lastPosition.x),
		y(ed.lastPosition.y),

		speed((int)ed.lastPlayer->topSpeed(ed.lastType)),

		health(ed.expectedHealth()),
		maxHealth(ed.lastType.maxHitPoints()),

		shields(ed.expectedShields()),
		shieldArmor(ed.lastPlayer->getUpgradeLevel(BWAPI::UpgradeTypes::Protoss_Plasma_Shields)),
		maxShields(ed.lastType.maxShields()),
		armor(ed.lastPlayer->armor(ed.lastType)),
		flying(ed.lastType.isFlyer()),

		groundDamage(ed.lastPlayer->damage(ed.lastType.groundWeapon())),
		groundCooldown(ed.lastType.groundWeapon().damageFactor() && ed.lastType.maxGroundHits() ? ed.lastPlayer->weaponDamageCooldown(ed.lastType) / (ed.lastType.groundWeapon().damageFactor() * ed.lastType.maxGroundHits()) : 0),
		//groundInnerRadius(ed.lastType.groundWeapon().innerSplashRadius()),
		//groundOuterRadius(ed.lastType.groundWeapon().outerSplashRadius()),
		groundMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.groundWeapon())),
		groundMinRange(ed.lastType.groundWeapon().minRange()),
		groundDamageType(ed.lastType.groundWeapon().damageType()),

		airDamage(ed.lastPlayer->damage(ed.lastType.airWeapon())),
		airCooldown(ed.lastType.airWeapon().damageFactor() && ed.lastType.maxAirHits() ? ed.lastType.airWeapon().damageCooldown() / (ed.lastType.airWeapon().damageFactor() * ed.lastType.maxAirHits()) : 0),
		//airInnerRadius(ed.lastType.airWeapon().innerSplashRadius()),
		//airOuterRadius(ed.lastType.airWeapon().outerSplashRadius()),
		airMaxRange(ed.lastPlayer->weaponMaxRange(ed.lastType.airWeapon())),
		airMinRange(ed.lastType.airWeapon().minRange()),
		airDamageType(ed.lastType.airWeapon().damageType()),

		score(ed.lastType.destroyScore()) {

		static int nextId = 0;
		id = nextId++;

		switch (ed.lastType) {
			case BWAPI::UnitTypes::Protoss_Carrier:
				groundDamage = ed.lastPlayer->damage(BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon());
				groundCooldown = BWAPI::UnitTypes::Protoss_Interceptor.groundWeapon().damageCooldown() / 8;
				groundMaxRange = 32 * 8;

				airDamage = groundDamage;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Terran_Bunker:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Gauss_Rifle);
				groundCooldown = BWAPI::UnitTypes::Terran_Marine.groundWeapon().damageCooldown() / 4;
				groundMaxRange = ed.lastPlayer->weaponMaxRange(BWAPI::UnitTypes::Terran_Marine.groundWeapon()) + 32;

				airDamage = groundDamage;
				airCooldown = groundCooldown;
				airMaxRange = groundMaxRange;
				break;

			case BWAPI::UnitTypes::Protoss_Reaver:
				groundDamage = ed.lastPlayer->damage(BWAPI::WeaponTypes::Scarab);
				break;

			default:
				break;
		}

		groundDamage *= 2;
		airDamage *= 2;

		shieldArmor *= 2;
		armor *= 2;

		health *= 2;
		shields *= 2;
	}

	FastAPproximation::FAPUnit &FastAPproximation::FAPUnit::operator=(const FAPUnit & other) {
		x = other.x, y = other.y;
		health = other.health, maxHealth = other.maxHealth;
		shields = other.shields, maxShields = other.maxShields;
		speed = other.speed, armor = other.armor, flying = other.flying, unitSize = other.unitSize;
		groundDamage = other.groundDamage, groundCooldown = other.groundCooldown, groundMaxRange = other.groundMaxRange, groundMinRange = other.groundMinRange, groundDamageType = other.groundDamageType;
		airDamage = other.airDamage, airCooldown = other.airCooldown, airMaxRange = other.airMaxRange, airMinRange = other.airMinRange, airDamageType = other.airDamageType;
		score = other.score;
		attackCooldownRemaining = other.attackCooldownRemaining;

		return *this;
	}

	bool FastAPproximation::FAPUnit::operator<(const FAPUnit & other) const {
		return id < other.id;
	}

}
<|endoftext|>