Home

Resume

Blog

Teikitu


// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
//  »Project«   Teikitu Gaming System (TgS) (∂)
//  »File«      TgS (WIN) Common - Base Platform API.inl
//  »Author«    Andrew Aye (EMail: mailto:andrew.aye@gmail.com, Web: http://www.andrewaye.com)
//  »Version«   4.0
// ------------------------------------------------------------------------------------------------------------------------------ //
//  Copyright: © 2002-2010, Andrew Aye.  All Rights Reserved.
//  This software is free for non-commercial use. 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 this copyright notice, this list of conditions and the following disclaimers. 
//    Redistributions in binary form must reproduce this copyright notice, this list of conditions and the following
//      disclaimers in the documentation and other materials provided with the distribution. 
//  Neither the names of the copyright owner nor the names of its contributors may be used to endorse or promote products derived
//  from this software without specific prior written permission. 
//  The intellectual property rights of the algorithms used reside with Andrew Aye.  You may not use this software, in whole or
//  in part, in support of any commercial product without the express written consent of the author.
//  There is no warranty or other guarantee of fitness of this software for any purpose. It is provided solely "as is".
// =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= //
#if !defined(_TGS_WIN_COMMON_BASEAPI_INL_)
#define _TGS_WIN_COMMON_BASEAPI_INL_
#pragma once


// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. //
//  Public Functions
// -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. //

TgINLINE TgVOID tgPM_Break()
{
    TgBREAK_INLINE;
}


TgINLINE TgVOID tgPM_Abort()
{
    abort();
}


TgINLINE TgSINT32 tgPM_BSR_U08( C_TgUINT08 uiVal )
{
    unsigned long iResult;
    return ((0 != _BitScanReverse( &iResult, uiVal )) ? iResult : -1);
}


TgINLINE TgSINT32 tgPM_BSR_U16( C_TgUINT16 uiVal )
{
    unsigned long iResult;
    return ((0 != _BitScanReverse( &iResult, uiVal )) ? iResult : -1);
}


TgINLINE TgSINT32 tgPM_BSR_U32( C_TgUINT32 uiVal )
{
    unsigned long iResult;
    return ((0 != _BitScanReverse( &iResult, uiVal )) ? iResult : -1);
}


TgINLINE TgSINT32 tgPM_BSR_U64( C_TgUINT64 uiVal )
{
#if defined(_WIN64)
    unsigned long iResult;
    return ((0 != _BitScanReverse64( &iResult, uiVal )) ? iResult : -1);
#else
    TgSINT32 iResult = tgPM_BSR_U32( (uiVal) & KTgMAX_U32 );
    if (iResult < 0)
    {
        iResult = tgPM_BSR_U32( (uiVal) >> 32 );

        if (iResult >= 0)
        {
            iResult += 32;
        };
    };

    return (iResult);
#endif
}


TgINLINE TgSINT08 tgPM_ABS_S08( C_TgSINT08 iA )
{
    return ((TgSINT08)abs(iA));
}


TgINLINE TgSINT16 tgPM_ABS_S16( C_TgSINT16 iA )
{
    return ((TgSINT16)abs(iA));
}


TgINLINE TgSINT32 tgPM_ABS_S32( C_TgSINT32 iA )
{
    return (abs(iA));
}


TgINLINE TgSINT64 tgPM_ABS_S64( C_TgSINT64 iA )
{
    return (_abs64(iA));
}


TgINLINE TgSINT32 tgPM_RAND_S_S32()
{
    TgUINT                                  uiRand;

    if (0 == rand_s( (unsigned int*)&uiRand ))
    {
        return (uiRand - (UINT32_MAX  >> 1));
    }
    else
    {
        return (tgCM_RND_S32());
    };
}


TgINLINE TgUINT32 tgPM_RAND_S_U32()
{
    TgUINT                                  uiRand;

    if (0 == rand_s( &uiRand ))
    {
        return (uiRand);
    }
    else
    {
        return (tgCM_RND_U32());
    };
}


TgINLINE TgFLOAT32 tgPM_CEIL_F32( C_TgFLOAT32 fA )
{
    return (ceilf(fA));
}


TgINLINE TgFLOAT32 tgPM_FLOOR_F32( C_TgFLOAT32 fA )
{
    return (floorf(fA));
}


TgINLINE TgFLOAT32 tgPM_SIN_F32( C_TgFLOAT32 fA )
{
    return (sinf(fA));
}


TgINLINE TgFLOAT32 tgPM_COS_F32( C_TgFLOAT32 fA )
{
    return (cosf(fA));
}


TgINLINE TgVOID tgPM_SINCOS_F32( PCU_TgFLOAT32 pfS, PCU_TgFLOAT32 pfC, C_TgFLOAT32 fA )
{
    TgASSERT(0 != pfS && 0 != pfC );
    *pfS = tgPM_SIN_F32(fA);
    *pfC = tgPM_COS_F32(fA);
}


TgINLINE TgFLOAT32 tgPM_TAN_F32( C_TgFLOAT32 fA )
{
    return (tanf(fA));
}


TgINLINE TgFLOAT32 tgPM_ASIN_F32( C_TgFLOAT32 fA )
{
    return (asinf(fA));
}


TgINLINE TgFLOAT32 tgPM_ACOS_F32( C_TgFLOAT32 fA )
{
    return (acosf(fA));
}


TgINLINE TgFLOAT32 tgPM_ATAN_F32( C_TgFLOAT32 fA )
{
    return (atanf(fA));
}


TgINLINE TgFLOAT32 tgPM_ATAN2_F32( C_TgFLOAT32 fY, C_TgFLOAT32 fX )
{
    return (atan2f(fY,fX));
}


TgINLINE TgFLOAT32 tgPM_ABS_F32( C_TgFLOAT32 fA )
{
    return (fabsf(fA));
}


TgINLINE TgFLOAT32 tgPM_POW_F32( C_TgFLOAT32 kBase, C_TgFLOAT32 kExponent )
{
    return (powf(kBase,kExponent));
}


TgINLINE TgFLOAT32 tgPM_SQRT_F32( C_TgFLOAT32 fA )
{
    return (sqrtf(fA));
}


TgINLINE TgFLOAT32 tgPM_EXP_F32( C_TgFLOAT32 tyX )
{
    return (expf( tyX ));
}


TgINLINE TgFLOAT32 tgPM_LN_F32( C_TgFLOAT32 tyX )
{
    return (logf( tyX ));
}


TgINLINE TgFLOAT32 tgPM_LOG_F32( C_TgFLOAT32 tyX )
{
    return (log10f( tyX ));
}


TgINLINE TgFLOAT32 tgPM_SQR_F32( C_TgFLOAT32 fA )
{
    return (fA*fA);
}


TgINLINE TgFLOAT32 tgPM_FMOD_F32( C_TgFLOAT32 fX, C_TgFLOAT32 fY )
{
    return (fmodf( fX, fY ));
}


TgINLINE TgFLOAT32 tgPM_FSEL_F32( C_TgFLOAT32 tyA, C_TgFLOAT32 tyB, C_TgFLOAT32 tyC )
{
    return ((tyA >= 0.0F) ? tyB : tyC);
}


TgINLINE TgFLOAT32 tgPM_COPY_SIGN_F32( C_TgFLOAT32 fA, C_TgFLOAT32 fB )
{
    return ((TgFLOAT32)_copysign( fA, fB ));
}


TgINLINE TgFLOAT64 tgPM_CEIL_F64( C_TgFLOAT64 fA )
{
    return (ceil(fA));
}


TgINLINE TgFLOAT64 tgPM_FLOOR_F64( C_TgFLOAT64 fA )
{
    return (floor(fA));
}


TgINLINE TgFLOAT64 tgPM_SIN_F64( C_TgFLOAT64 fA )
{
    return (sin(fA));
}


TgINLINE TgFLOAT64 tgPM_COS_F64( C_TgFLOAT64 fA )
{
    return (cos(fA));
}


TgINLINE TgVOID tgPM_SINCOS_F64( PCU_TgFLOAT64 pfS, PCU_TgFLOAT64 pfC, C_TgFLOAT64 fA )
{
    TgASSERT(0 != pfS && 0 != pfC );
    *pfS = tgPM_SIN_F64(fA);
    *pfC = tgPM_COS_F64(fA);
}


TgINLINE TgFLOAT64 tgPM_TAN_F64( C_TgFLOAT64 fA )
{
    return (tan(fA));
}


TgINLINE TgFLOAT64 tgPM_ASIN_F64( C_TgFLOAT64 fA )
{
    return (asin(fA));
}


TgINLINE TgFLOAT64 tgPM_ACOS_F64( C_TgFLOAT64 fA )
{
    return (acos(fA));
}


TgINLINE TgFLOAT64 tgPM_ATAN_F64( C_TgFLOAT64 fA )
{
    return (atan(fA));
}


TgINLINE TgFLOAT64 tgPM_ATAN2_F64( C_TgFLOAT64 fY, C_TgFLOAT64 fX )
{
    return (atan2(fY,fX));
}


TgINLINE TgFLOAT64 tgPM_ABS_F64( C_TgFLOAT64 fA )
{
    return (fabs(fA));
}


TgINLINE TgFLOAT64 tgPM_POW_F64( C_TgFLOAT64 kBase, C_TgFLOAT64 kExponent )
{
    return (pow(kBase,kExponent));
}


TgINLINE TgFLOAT64 tgPM_SQRT_F64( C_TgFLOAT64 fA )
{
    return (sqrt(fA));
}


TgINLINE TgFLOAT64 tgPM_EXP_F64( C_TgFLOAT64 tyX )
{
    return (exp( tyX ));
}


TgINLINE TgFLOAT64 tgPM_LN_F64( C_TgFLOAT64 tyX )
{
    return (log( tyX ));
}


TgINLINE TgFLOAT64 tgPM_LOG_F64( C_TgFLOAT64 tyX )
{
    return (log10( tyX ));
}


TgINLINE TgFLOAT64 tgPM_SQR_F64( C_TgFLOAT64 fA )
{
    return (fA*fA);
}


TgINLINE TgFLOAT64 tgPM_FMOD_F64( C_TgFLOAT64 fX, C_TgFLOAT64 fY )
{
    return (fmod( fX, fY ));
}


TgINLINE TgFLOAT64 tgPM_FSEL_F64( C_TgFLOAT64 tyA, C_TgFLOAT64 tyB, C_TgFLOAT64 tyC )
{
    return ((tyA >= 0.0) ? tyB : tyC);
}


TgINLINE TgFLOAT64 tgPM_COPY_SIGN_F64( C_TgFLOAT64 fA, C_TgFLOAT64 fB )
{
    return (_copysign( fA, fB ));
}


// START THREAD ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

TgINLINE TgVOID tgTR_Yield()
{
    g_pfnSwitchToThread();
}


TgINLINE TgVOID tgTR_Pause()
{
    _mm_pause();
}


// START ATOMIC ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

TgINLINE TgVOID tgAM_WRITE_FENCE()
{
    _WriteBarrier();
}


TgINLINE TgVOID tgAM_READ_FENCE()
{
    _ReadBarrier();
}


TgINLINE TgVOID tgAM_FULL_FENCE()
{
    _ReadWriteBarrier();
}


// ---- Atomic Pointer Functions ------------------------------------------------------------------------------------------------ //

TgINLINE P_TgVOID tgAMPT_READ( volatile TgATOMIC_PVOID *piTarget )
{
    return (*piTarget);
}


TgINLINE TgVOID tgAMPT_WRITE( volatile TgATOMIC_PVOID *piTarget, PC_TgVOID pVal )
{
    tgInterlockedExchangePointer( piTarget, pVal );
}


TgINLINE P_TgVOID tgAMPT_XCHG( volatile TgATOMIC_PVOID *piTarget, PC_TgVOID pVal )
{
    return (tgInterlockedExchangePointer( piTarget, pVal ));
}


TgINLINE P_TgVOID tgAMPT_XCMP( volatile TgATOMIC_PVOID *piTarget, PC_TgVOID pVal, PC_TgVOID pCmp )
{
    return (tgInterlockedCompareExchangePointer( piTarget, pVal, pCmp ));
}




// ---- Atomic 16bit Functions -------------------------------------------------------------------------------------------------- //
#if TgCOMPILE_16BIT_ATOMIC

TgINLINE TgSINT16 tgAM16_AND( volatile TgATOMIC_INT16 *piTarget, C_TgSINT16 iVal )
{
    return (tgInterlockedAnd16( piTarget, iVal ));
}


TgINLINE TgSINT16 tgAM16_OR( volatile TgATOMIC_INT16 *piTarget, C_TgSINT16 iVal )
{
    return (tgInterlockedOr16( piTarget, iVal ));
}


TgINLINE TgSINT16 tgAM16_INC( volatile TgATOMIC_INT16 *piTarget )
{
    return (tgInterlockedIncrement16( piTarget ));
}


TgINLINE TgSINT16 tgAM16_DEC( volatile TgATOMIC_INT16 *piTarget )
{
    return (tgInterlockedDecrement16( piTarget ));
}


TgINLINE TgSINT16 tgAM16_READ( volatile TgATOMIC_INT16 *piTarget )
{
    return (*piTarget);
}

#endif




// ---- Atomic 32bit Functions -------------------------------------------------------------------------------------------------- //

TgINLINE TgSINT32 tgAM32_XADD( volatile TgATOMIC_INT32 *piTarget, C_TgSINT32 iVal )
{
    return (tgInterlockedExchangeAdd( piTarget, iVal ));
}


TgINLINE TgSINT32 tgAM32_XSUB( volatile TgATOMIC_INT32 *piTarget, C_TgSINT32 iVal )
{
    return (tgInterlockedExchangeAdd( piTarget, -iVal ));
}


TgINLINE TgSINT32 tgAM32_AND( volatile TgATOMIC_INT32 *piTarget, C_TgSINT32 iVal )
{
    return (tgInterlockedAnd( piTarget, iVal ));
}


TgINLINE TgSINT32 tgAM32_OR( volatile TgATOMIC_INT32 *piTarget, C_TgSINT32 iVal )
{
    return (tgInterlockedOr( piTarget, iVal ));
}


TgINLINE TgSINT32 tgAM32_INC( volatile TgATOMIC_INT32 *piTarget )
{
    return (tgInterlockedIncrement( piTarget ));
}


TgINLINE TgSINT32 tgAM32_DEC( volatile TgATOMIC_INT32 *piTarget )
{
    return (tgInterlockedDecrement( piTarget ));
}


TgINLINE TgSINT32 tgAM32_READ( volatile TgATOMIC_INT32 *piTarget )
{
    return (*piTarget);
}


TgINLINE TgVOID tgAM32_WRITE( volatile TgATOMIC_INT32 *piTarget, C_TgSINT32 iVal )
{
    tgInterlockedExchange( piTarget, iVal );
}


TgINLINE TgSINT32 tgAM32_XCHG( volatile TgATOMIC_INT32 *piTarget, C_TgSINT32 iVal )
{
    return (tgInterlockedExchange( piTarget, iVal ));
}


TgINLINE TgSINT32 tgAM32_XCMP( volatile TgATOMIC_INT32 *piTarget, C_TgSINT32 iVal, C_TgSINT32 iCmp )
{
    return (tgInterlockedCompareExchange( piTarget, iVal, iCmp ));
}




// ---- Atomic 64bit Functions -------------------------------------------------------------------------------------------------- //
#if TgCOMPILE_64BIT_ATOMIC

TgINLINE TgSINT64 tgAM64_XADD( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iVal )
{
    return (tgInterlockedExchangeAdd64( piTarget, iVal ));
}


TgINLINE TgSINT64 tgAM64_XSUB( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iVal )
{
    return (tgInterlockedExchangeAdd64( piTarget, -iVal ));
}


TgINLINE TgSINT64 tgAM64_AND( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iVal )
{
    return (tgInterlockedAnd64( piTarget, iVal ));
}


TgINLINE TgSINT64 tgAM64_OR( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iVal )
{
    return (tgInterlockedOr64( piTarget, iVal ));
}


TgINLINE TgSINT64 tgAM64_INC( volatile TgATOMIC_INT64 *piTarget )
{
    return (tgInterlockedIncrement64( piTarget ));
}


TgINLINE TgSINT64 tgAM64_DEC( volatile TgATOMIC_INT64 *piTarget )
{
    return (tgInterlockedDecrement64( piTarget ));
}


TgINLINE TgSINT64 tgAM64_READ( volatile TgATOMIC_INT64 *piTarget )
{
    return (*piTarget);
}


TgINLINE TgVOID tgAM64_WRITE( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iVal )
{
    tgInterlockedExchange64( piTarget, iVal );
}


TgINLINE TgSINT64 tgAM64_XCHG( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iVal )
{
    return (tgInterlockedExchange64( piTarget, iVal ));
}


TgINLINE TgBOOL tgAM64_XCMP2( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iHigh, C_TgSINT64 iLow, PC_TgSINT64 piCmpResult )
{
    return (tgInterlockedCompareExchange128( piTarget, iHigh, iLow, piCmpResult ));
}

#endif // TgCOMPILE_64BIT_ATOMIC

TgINLINE TgSINT64 tgAM64_XCMP( volatile TgATOMIC_INT64 *piTarget, C_TgSINT64 iVal, C_TgSINT64 iCmp )
{
    return (tgInterlockedCompareExchange64( piTarget, iVal, iCmp ));
}

#endif //  END  ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////