Home

Resume

Blog

Teikitu


/* =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= */
/*  »Project«   Teikitu Gaming System (TgS) (∂)
    »File«      TgS Common - Util MP - Reader Writer Lock.h
    »Author«    Andrew Aye (EMail: mailto:andrew.aye@gmail.com, Web: http://www.andrewaye.com)
    »Version«   4.51 / »GUID« A9981407-3EC9-42AF-8B6F-8BE6DD919615                                                                                                        */
/*   -------------------------------------------------------------------------------------------------------------------------------------------------------------------- */
/*  Copyright: © 2002-2017, 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:
        Redistribution of source code must retain this copyright notice, this list of conditions and the following disclaimers.
        Redistribution 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.
    The name of the author may not 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_COMMON_UTIL_MP_RW_H)
#define TGS_COMMON_UTIL_MP_RW_H
#pragma once


/* == Common ============================================================================================================================================================ */

/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  Public Constants                                                                                                                                                      */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

TgCOMPILER_ASSERT( 4 == sizeof( TgATOMIC_SINT32 ), 0 );

typedef enum
{
    ETgUTM_RW_STATE__Waiting,
    ETgUTM_RW_STATE__Reading,
    ETgUTM_RW_STATE__Writing,
} ETgUTM_RW_STATE;
TgTYPE_PREFIX( ETgUTM_RW_STATE );

enum { KTgMP_MAX_READ_WRITER_LOCK           = 32 };


/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */
/*  Public Types                                                                                                                                                          */
/* -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-. */

TgTYPE_UNION_ALIGN(STg2_UTM_AM_RW,4,)
{
    struct
    {
    #if TgCOMPILE_LITTLE_ENDIAN
        volatile TgUINT08                           iWrite;
        volatile TgUINT08                           iRead;
        volatile TgUINT08                           iRequest;
        volatile TgUINT08                           iPad;
    #else
        volatile TgUINT08                           iPad;
        volatile TgUINT08                           iRequest;
        volatile TgUINT08                           iRead;
        volatile TgUINT08                           iWrite;
    #endif
    }                                           m;
    struct
    {
    #if TgCOMPILE_LITTLE_ENDIAN
        volatile TgUINT16                           iWrite_Read;
        volatile TgUINT16                           iRequest_Pad;
    #else
        volatile TgUINT16                           iRequest_Pad;
        volatile TgUINT16                           iWrite_Read;
    #endif
    }                                           u;
    volatile TgATOMIC_SINT32                    m_iData;
};
TgCOMPILER_ASSERT( 4 == sizeof( STg2_UTM_AM_RW ), 0 );

TgTYPE_STRUCT_ALIGN(STg2_UTM_AM_RW_ISO,TgCOMPILE_CACHE_LINE_SIZE,)
{
    STg2_UTM_AM_RW                              m_sLock;
#if TgCOMPILE_CACHE_LINE_SIZE > 4
    TgUINT08                                    m_uiPad[TgCOMPILE_CACHE_LINE_SIZE - 4];
#endif
};

TgTYPE_STRUCT(STg2_UTM_INT_RW,)
{
    ETgUTM_RW_STATE                             m_enState;
    TgUINT32                                    m_nuiReader;
    TgUINT32                                    m_uiIndex;
    TgUINT32                                    m_nuiThread;
    TgTHREAD_ID                                 m_atiThread[KTgMP_MAX_READ_WRITER_LOCK];
    TgBOOL                                      m_abReader[KTgMP_MAX_READ_WRITER_LOCK];
    P_STg1_MP_SM                                m_psExecute[KTgMP_MAX_READ_WRITER_LOCK];
};

TgTYPE_STRUCT(STg2_UTM_SN_RW,)
{
    STg2_UTM_SN_ISO                             m_sLock;
    STg2_UTM_INT_RW                             m_sData;
#if TgCOMPILE_CACHE_LINE_SIZE > 16
    TgUINT08                                    m_uiPad[TgCOMPILE_CACHE_LINE_SIZE - 16];
#endif
};

TgTYPE_STRUCT(STg2_UTM_RW,)
{
    STg1_MP_CS                                  m_sLock;
    STg2_UTM_INT_RW                             m_sData;
};


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

/* ---- FIFO Atomic Reader-Writer Lock ------------------------------------------------------------------------------------------------------------------------------------ */

TgINLINE TgRESULT                           tgCM_UTM_AM_RW_Init( PCU_STg2_UTM_AM_RW );
TgINLINE TgVOID                             tgCM_UTM_AM_RW_Free( PCU_STg2_UTM_AM_RW );

TgINLINE TgVOID                             tgCM_UTM_AM_RW_Enter_Read_Wait_Yield( PCU_STg2_UTM_AM_RW );
TgINLINE TgVOID                             tgCM_UTM_AM_RW_Enter_Read_Wait_Spin( PCU_STg2_UTM_AM_RW );
TgINLINE TgRESULT                           tgCM_UTM_AM_RW_Enter_Read( PCU_STg2_UTM_AM_RW );

TgINLINE TgVOID                             tgCM_UTM_AM_RW_Exit_Read( PCU_STg2_UTM_AM_RW );

TgINLINE TgVOID                             tgCM_UTM_AM_RW_Enter_Write_Wait_Yield( PCU_STg2_UTM_AM_RW );
TgINLINE TgVOID                             tgCM_UTM_AM_RW_Enter_Write_Wait_Spin( PCU_STg2_UTM_AM_RW );
TgINLINE TgRESULT                           tgCM_UTM_AM_RW_Enter_Write( PCU_STg2_UTM_AM_RW );

TgINLINE TgVOID                             tgCM_UTM_AM_RW_Exit_Write( PCU_STg2_UTM_AM_RW );

/* ---- FIFO Spin Lock Reader Writer Queuing Lock ------------------------------------------------------------------------------------------------------------------------- */

#if TgCOMPILE_THREAD

TgINLINE TgRESULT                           tgCM_UTM_SN_RW_Init( PCU_STg2_UTM_SN_RW );
TgINLINE TgVOID                             tgCM_UTM_SN_RW_Free( PCU_STg2_UTM_SN_RW );

TgINLINE TgVOID                             tgCM_UTM_SN_RW_Enter_Read_Yield_Block( PCU_STg2_UTM_SN_RW );
TgINLINE TgVOID                             tgCM_UTM_SN_RW_Enter_Read_Spin_Block( PCU_STg2_UTM_SN_RW );
TgINLINE TgRESULT                           tgCM_UTM_SN_RW_Enter_Read_Yield( PCU_STg2_UTM_SN_RW );
TgINLINE TgRESULT                           tgCM_UTM_SN_RW_Enter_Read_Spin( PCU_STg2_UTM_SN_RW );

TgINLINE TgVOID                             tgCM_UTM_SN_RW_Exit_Read_Yield( PCU_STg2_UTM_SN_RW );
TgINLINE TgVOID                             tgCM_UTM_SN_RW_Exit_Read_Spin( PCU_STg2_UTM_SN_RW );

TgINLINE TgVOID                             tgCM_UTM_SN_RW_Enter_Write_Yield_Block( PCU_STg2_UTM_SN_RW );
TgINLINE TgVOID                             tgCM_UTM_SN_RW_Enter_Write_Spin_Block( PCU_STg2_UTM_SN_RW );
TgINLINE TgRESULT                           tgCM_UTM_SN_RW_Enter_Write_Yield( PCU_STg2_UTM_SN_RW );
TgINLINE TgRESULT                           tgCM_UTM_SN_RW_Enter_Write_Spin( PCU_STg2_UTM_SN_RW );

TgINLINE TgVOID                             tgCM_UTM_SN_RW_Exit_Write_Yield( PCU_STg2_UTM_SN_RW );
TgINLINE TgVOID                             tgCM_UTM_SN_RW_Exit_Write_Spin( PCU_STg2_UTM_SN_RW );

/*# TgCOMPILE_THREAD */
#endif

/* ---- FIFO Critical Section Reader Writer Queuing Lock ------------------------------------------------------------------------------------------------------------------ */

#if TgCOMPILE_THREAD

TgINLINE TgRESULT                           tgCM_UTM_RW_Init( PCU_STg2_UTM_RW );
TgINLINE TgVOID                             tgCM_UTM_RW_Free( PCU_STg2_UTM_RW );

TgINLINE TgVOID                             tgCM_UTM_RW_Enter_Read_Block( PCU_STg2_UTM_RW );
TgINLINE TgRESULT                           tgCM_UTM_RW_Enter_Read( PCU_STg2_UTM_RW );

TgINLINE TgVOID                             tgCM_UTM_RW_Exit_Read( PCU_STg2_UTM_RW );

TgINLINE TgVOID                             tgCM_UTM_RW_Enter_Write_Block( PCU_STg2_UTM_RW );
TgINLINE TgRESULT                           tgCM_UTM_RW_Enter_Write( PCU_STg2_UTM_RW );

TgINLINE TgVOID                             tgCM_UTM_RW_Exit_Write( PCU_STg2_UTM_RW );

/*# TgCOMPILE_THREAD */
#endif

/* ====================================================================================================================================================================== */
#endif