📄 bf_util.c
字号:
{
UINT16 iMappingEntry;
void *pBufferData;
volatile BF_ActiveEntryType *psActiveEntry;
volatile bf_AppDataAreaType *psAppDataArea;
volatile bf_MappingEntryType *psMappingEntry;
GS_UseCritical();
/*
** See if there is a mapping entry associated with the transport ID.
*/
GS_EnterCritical();
{
iMappingEntry = bf_s.aiMappingByTransport[ iTransportId ];
if( iMappingEntry == BF_NO_MAPPING )
{
GS_ExitCritical();
return FALSE;
}
/*
** Look up the main mapping entry,
** then look up the active list entry via the main entry.
*/
psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];
psActiveEntry = &bf_s.asActiveEntries[ psMappingEntry->iActiveEntry ];
/*
** Calculate the pointer to the data portion of the buffer.
** This is what actually gets loaded into the active entry.
** (There may be status ahead of the data in the buffer...)
** Bottom line here is if we're passed a null buffer pointer,
** keep it null in all cases.
*/
if( pTranBuf == NULL )
{
pBufferData = NULL;
}
else
{
pBufferData = (UINT8*)pTranBuf + psActiveEntry->iTranBufOffset;
}
/*
** Move the resultant pointer to the data into the appropriate
** pointer in the active list entry.
*/
psAppDataArea = &bf_s.asAppDataAreas[ psMappingEntry->eAppDataAreaId ];
if( psMappingEntry->fCon )
{
psActiveEntry->pSource = pBufferData;
/*
** New data to be written into the application data area.
** Notify the app data area handler as requested.
*/
if( psAppDataArea->xSNotifySemaphore != GS_NO_SEMAPHORE )
{
GS_SetSemaphore( psAppDataArea->xSNotifySemaphore );
}
else
{
if( psAppDataArea->xSNotifyQueue != GS_NO_QUEUE )
{
GS_PutMsgQueueBits( psAppDataArea->xSNotifyQueue, psAppDataArea->iSNotifyBitMsg );
}
}
}
else
{
/*
** New data being read from the application data area.
*/
psActiveEntry->pDestination = pBufferData;
}
}
GS_ExitCritical();
return TRUE;
} /* end of BF_UpdateMapping() */
/****************************************************************************
*****************************************************************************
**
** Private Services
**
*****************************************************************************
****************************************************************************/
/*---------------------------------------------------------------------------
** bf_AccessMapping()
**---------------------------------------------------------------------------
*/
void bf_AccessMapping( BF_AccessTrrblType *pTrrbl )
{
UINT16 iMappingEntry;
volatile bf_AppDataAreaType *psAppDataArea;
volatile bf_MappingEntryType *psMappingEntry;
/*
** Make sure we have a valid mapping entry first.
** Get a convenience pointer to it if it exists.
*/
iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );
if( iMappingEntry == BF_NO_MAPPING )
{
pTrrbl->eStatus = BF_NO_SUCH_MAPPING;
GS_ReturnTrrbl( pTrrbl );
return;
}
psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];
/*
** Look up the application memory area this mapping entry uses.
** Save it in the access request tribble.
*/
psAppDataArea = &bf_s.asAppDataAreas[ psMappingEntry->eAppDataAreaId ];
pTrrbl->eAppDataAreaId = psMappingEntry->eAppDataAreaId;
pTrrbl->iAppDataAreaOffset = psMappingEntry->iAppDataAreaOffset;
/*
** Calculate the cpu time for this request.
** Saves us from doing it when we're crunched for time trying to
** process as many as possible. Also keeps us from having to
** recalculate the cpu time for the first one multiple times if we
** just have a little time left to process and skip it several times.
*/
pTrrbl->lCpuTime = psAppDataArea->lCpuTimePerMessage +
psAppDataArea->lCpuTimePerEntry +
( psAppDataArea->lCpuTimePerByte * pTrrbl->iSize );
/*
** If we're supposed to forward the access tribble, do it now.
*/
if( ( psAppDataArea->xMNotifyQueue != GS_NO_QUEUE ) &&
( psAppDataArea->iMNotifyBitMsg == 0 ) )
{
GS_PutTrrbl( psAppDataArea->xMNotifyQueue, pTrrbl );
return;
}
/*
** No immediate forwarding requested.
** Put the request tribble on the access request linked list.
*/
LL_PutSingleLinkList( (void *)&psAppDataArea->sAccessRequestList, pTrrbl );
/*
** Notify the app data area handler if and as requested.
*/
if( psAppDataArea->xMNotifySemaphore != GS_NO_SEMAPHORE )
{
GS_SetSemaphore( psAppDataArea->xMNotifySemaphore );
}
if( psAppDataArea->xMNotifyQueue != GS_NO_QUEUE )
{
GS_PutMsgQueueBits( psAppDataArea->xMNotifyQueue, psAppDataArea->iMNotifyBitMsg );
}
} /* end of bf_AccessMapping() */
/*---------------------------------------------------------------------------
** bf_ActivateMapping()
**---------------------------------------------------------------------------
*/
void bf_ActivateMapping( BF_ActivateTrrblType *pTrrbl )
{
UINT16 iActiveEntry;
UINT16 iAppDataAreaId;
UINT16 iAppDataAreaIdTemp;
UINT16 iMappingEntry;
UINT16 iSubList;
UINT16 iSubListTemp;
UINT32 lCpuTime;
volatile BF_ActiveEntryType *psActiveEntry;
volatile bf_ActiveSubListType *psActiveSubList;
volatile bf_ActiveSubListType *psActiveSubListTemp;
volatile bf_AppDataAreaType *psAppDataArea;
volatile bf_AppDataAreaType *psAppDataAreaTemp;
volatile bf_MappingEntryType *psMappingEntry;
GS_UseCritical();
/*
** Make sure we have a valid mapping entry first.
** Get a convenience pointer to it if it exists.
*/
iMappingEntry = bf_FindMapping( pTrrbl->iClass, pTrrbl->iInstance, pTrrbl->fCon );
if( iMappingEntry == BF_NO_MAPPING )
{
return;
}
psMappingEntry = &bf_s.asMappingEntries[ iMappingEntry ];
/*
** Bail if no reservation has been made.
*/
if( psMappingEntry->iActiveUsers == 0 )
{
return;
}
/*
** We're done if there's an active entry already in place.
*/
if( psMappingEntry->iActiveEntry != BF_NO_MAPPING )
{
/*
** start edits: October,28th 2005, H.F.
**
** Problem: iTransportId is NOT unique for a Consumer Assembly.
** If there are 3 class 1 connections to the same Consumer
** Connection Point, there will also be 3 iTransportIds.
** However, it is used for mapping entries. So it can happen
** that the iTransportId, that is currently used for mapping
** a Consumer Assembly is now used in conjunction with another
** Consumer Assembly, as the associated connection to the
** first Consumer Assembly was closed and so the iTransportId
** was released and is now used by another connection to the
** second Consumer Assembly. The mapping of the first Consumer
** Assembly has been overwritten by the mapping of the second
** Consumer Assembly, then. And this can result in an Access
** Violation when closing the connection to the first Consumer
** Assembly.
**
** Workaround: Map the Consumer Connection Point to all of its iTransportIds
** If the currently actually used iTransportId is released, another
** iTransportId can then be selected to be used for the actual
** mapping.
*/
if( psMappingEntry->fCon )
bf_s.aiMappingByTransport[ pTrrbl->iTransportId ] = iMappingEntry;
/*
** end edits: October,28th 2005, H.F.
*/
return;
}
/*
** Pull out the application memory area info.
** Compute the copy time for this entry.
*/
iAppDataAreaId = psMappingEntry->eAppDataAreaId;
psAppDataArea = &bf_s.asAppDataAreas[ iAppDataAreaId ];
lCpuTime = psAppDataArea->lCpuTimePerEntry + ( psAppDataArea->lCpuTimePerByte * pTrrbl->iResyncSize );
/*
** Find the first available sub-list that has room,
** that is, the penalty is not exceeded.
*/
iSubList = pTrrbl->fCon ? ( BF_NUM_SUB_LISTS / 2 ) : 0;
iSubListTemp = BF_NUM_SUB_LISTS / 2;
while( iSubListTemp &&
( ( psAppDataArea->asActiveSubList[ iSubList ].lCpuTimeAreaSubList + lCpuTime ) > psAppDataArea->lCpuTimeMaxResync ) )
{
iSubList++;
iSubListTemp--;
}
GS_LogEventIf( iSubListTemp == 0, BF_CPU_TIME_EXCEEDED, iAppDataAreaId, pTrrbl, FATAL );
psActiveSubList = &psAppDataArea->asActiveSubList[ iSubList ];
/*
** Slide the entries in the active list up to make room.
** Start with the highest app mem area and work our way down.
** Within each app mem area, handle each active entry sub list separately.
*/
iAppDataAreaIdTemp = AD_NUM_APP_DATA_AREAS - 1;
iActiveEntry = bf_s.iActiveEntries;
while( iAppDataAreaIdTemp > iAppDataAreaId )
{
psAppDataAreaTemp = &bf_s.asAppDataAreas[ iAppDataAreaIdTemp ];
for( iSubListTemp = BF_NUM_SUB_LISTS; iSubListTemp > 0 ; iSubListTemp-- )
{
psActiveSubListTemp = &psAppDataAreaTemp->asActiveSubList[ iSubListTemp - 1 ];
if( psActiveSubListTemp->iActiveEntries )
{
/*
** This active sub list has entries.
** Move the first entry in this list to
** one past the end of this list.
** Adjust the starting point of the list.
*/
GS_EnterCritical();
{
bf_MoveActiveEntry( psActiveSubListTemp->iActiveEntry1 + psActiveSubListTemp->iActiveEntries, psActiveSubListTemp->iActiveEntry1 );
iActiveEntry = psActiveSubListTemp->iActiveEntry1;
psActiveSubListTemp->iActiveEntry1++;
}
GS_ExitCritical();
}
}
iAppDataAreaIdTemp--;
}
/*
** Room has been made for the newly activated entry.
** If this is the first entry for this sub list,
** note where the sub list starts.
*/
if( psActiveSubList->iActiveEntries == 0 )
{
psActiveSubList->iActiveEntry1 = iActiveEntry;
}
/*
** New entry goes in one place past the current end of this
** active sub list's entries in the active entry list.
*/
psActiveEntry = &bf_s.asActiveEntries[ iActiveEntry ];
psActiveEntry->pSource = pTrrbl->fCon ? (UINT8*)pTrrbl->pTranBuf + pTrrbl->iTranBufOffset : (UINT8*)psAppDataArea->pBaseAddress + psMappingEntry->iAppDataAreaOffset;
psActiveEntry->pDestination = !pTrrbl->fCon ? (UINT8*)pTrrbl->pTranBuf + pTrrbl->iTranBufOffset : (UINT8*)psAppDataArea->pBaseAddress + psMappingEntry->iAppDataAreaOffset;
psActiveEntry->iResyncSize = pTrrbl->iResyncSize;
psActiveEntry->iTranBufOffset = pTrrbl->iTranBufOffset;
psActiveEntry->pAddStatus = pTrrbl->pAddStatus;
psActiveEntry->iTransportId = pTrrbl->iTransportId;
psActiveEntry->iPort = pTrrbl->iPort;
/*
** Connect the main entry to the transport ID sorted entry.
** Connect the main entry to the active entry.
** Connect the main entry to the sub-list.
** Connect the transport ID sorted entry to the main entry.
*/
psMappingEntry->iActiveEntry = iActiveEntry;
psMappingEntry->iTransportId = pTrrbl->iTransportId;
psMappingEntry->iActiveSubList = iSubList;
bf_s.aiMappingByTransport[ pTrrbl->iTransportId ] = iMappingEntry;
/*
** Bump the total active entry count for the app memory area.
** Add to the active sub-list penalty.
*/
bf_s.iActiveEntries++;
psActiveSubList->lCpuTimeAreaSubList += lCpuTime;
GS_EnterCritical();
{
psActiveSubList->iActiveEntries++;
}
GS_ExitCritical();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -