📄 id1_buffer.c
字号:
pstBlock = pstTemp;
if ( !BADNESS(pstTemp) )
break;
}
//repeat until we find something good
}while ( (pstTemp=pstTemp->pstNextFree) != g_pstFreeList );
//POSITION();
if (!pstBlock) {
//如果所有的缓冲都被使用(引用计数>0),睡眠,等待
vMtsTaskSleep(&g_pstBufferWaitTask);
goto lbl_Repeat;
}
//POSITION();
Id1WaitOnBuffer(pstBlock); //如果上锁则等...
if (pstBlock->ucRefers) //如果这时又被其他任务使用,则再重复上述过程。
goto lbl_Repeat;
while (pstBlock->ucDirty) {
//如果该缓冲区已经修改,则将数据写盘,并再次等待缓冲区解锁。
iId1SyncDeviceBuffer(pstBlock->uiDevice);
Id1WaitOnBuffer(pstBlock);
if (pstBlock->ucRefers)
goto lbl_Repeat;
}
//POSITION();
/* NOTE!! While we slept waiting for this block, somebody else might */
/* already have added "this" block to the cache. check it */
if ( pstId1FindBuffer(iDevice, iBlock) )
goto lbl_Repeat;
/* OK, FINALLY we know that this buffer is the only one of it's kind, */
/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
pstBlock->ucRefers = 1;
pstBlock->ucDirty = 0;
pstBlock->ucUpToDate = 0;
Id1RemoveFromQueue(pstBlock);
pstBlock->uiDevice = (unsigned short)iDevice;
pstBlock->ulBlockNr = (unsigned short)iBlock;
//POSITION();
Id1InsertToQueue(pstBlock);
return pstBlock;
}
/************************************************************
*************************************************************
** Function Name: pstId1GetHashTable
** Author: x.cheng
**
** Comment:
** Why like this, I hear you say... The reason is race-conditions.
** As we don't lock buffers (unless we are readint them, that is),
** something might happen to it while we sleep (ie a read-error
** will force it bad). This shouldn't really happen currently, but
** the code is ready.
**
** List of parameters:
** iDevice - which device.
** iBlock - which block.
**
** Return value:
**
** Revisions:
**
*************************************************************
*************************************************************/
ts_BufferBlock* pstId1GetHashTable(int iDevice, int iBlock)
{
ts_BufferBlock* pstBlock;
for(;;) {
if ( !(pstBlock=pstId1FindBuffer(iDevice, iBlock)) )
return NULL;
pstBlock->ucRefers ++;
Id1WaitOnBuffer(pstBlock);
if (pstBlock->uiDevice == (unsigned short)iDevice &&
pstBlock->ulBlockNr == (unsigned short)iBlock)
return pstBlock;
pstBlock->ucRefers -- ;
}
}
/************************************************************
*************************************************************
** Function Name: iId1SyncDeviceBuffer
** Author: x.cheng
**
** Comment:
** 对指定的设备进行缓冲和设备上数据的同步。
**
** List of parameters:
** iDevice - which device.
**
** Return value:
**
** Revisions:
**
*************************************************************
*************************************************************/
int iId1SyncDeviceBuffer(int iDevice)
{
int i;
ts_BufferBlock* pstBlock;
pstBlock = (ts_BufferBlock *)&KernelEnd_;
for( i=0; i<(int)g_ulNrOfBlocks; i++, pstBlock++ ) {
if (pstBlock->uiDevice != (unsigned short)iDevice)
continue;
Id1WaitOnBuffer(pstBlock);
if ( pstBlock->uiDevice==(unsigned short)iDevice && pstBlock->ucDirty ) {
//write to device...
}
}
//write inode...
return 1;
}
//----------------------------------------------------------------------------------
//==============================local function======================================
//----------------------------------------------------------------------------------
/************************************************************
*************************************************************
** Function Name: Id1WaitOnBuffer
** Author: x.cheng
**
** Comment:
**
** List of parameters:
** pucBlock - address.
**
** Return value:
** none
**
** Revisions:
**
*************************************************************
*************************************************************/
static void Id1WaitOnBuffer(ts_BufferBlock* pstBlock)
{
// vCLI();
while ( pstBlock->ucLocked )
vMtsTaskSleep( &pstBlock->pstWaitTask );
// vSTI();
}
/************************************************************
*************************************************************
** Function Name: pstId1FindBuffer
** Author: x.cheng
**
** Comment:
**
** List of parameters:
** iDevice - which device.
** iBlock - which block.
**
** Return value:
** none
**
** Revisions:
**
*************************************************************
*************************************************************/
static ts_BufferBlock* pstId1FindBuffer(int iDevice, int iBlock)
{
ts_BufferBlock* pstTemp;
for ( pstTemp=pstHash(iDevice, iBlock); pstTemp!=NULL; pstTemp=pstTemp->pstNext ) {
if ( pstTemp->uiDevice==(unsigned short)iDevice && pstTemp->ulBlockNr==(unsigned short)iBlock)
return pstTemp;
}
return NULL;
}
/************************************************************
*************************************************************
** Function Name: Id1RemoveFromQueue
** Author: x.cheng
**
** Comment:
**
** List of parameters:
**
** Return value:
** none
**
** Revisions:
**
*************************************************************
*************************************************************/
static inline void Id1RemoveFromQueue( ts_BufferBlock *pstBlock)
{
/* remove from hash-queue */
if ( pstBlock->pstNext )
pstBlock->pstNext->pstPrev = pstBlock->pstPrev;
if ( pstBlock->pstPrev )
pstBlock->pstPrev->pstNext = pstBlock->pstNext;
if ( pstHash(pstBlock->uiDevice, pstBlock->ulBlockNr) == pstBlock )
pstHash(pstBlock->uiDevice, pstBlock->ulBlockNr) = pstBlock->pstNext;
/* remove from free list */
if ( !(pstBlock->pstPrevFree) || !(pstBlock->pstNextFree) )
PANIC1("Free block list corrupted\n");
pstBlock->pstPrevFree->pstNextFree = pstBlock->pstNextFree;
pstBlock->pstNextFree->pstPrevFree = pstBlock->pstPrevFree;
if (g_pstFreeList == pstBlock)
g_pstFreeList = pstBlock->pstNextFree;
}
/************************************************************
*************************************************************
** Function Name: Id1InsertToQueue
** Author: x.cheng
**
** Comment:
**
** List of parameters:
**
** Return value:
** none
**
** Revisions:
**
*************************************************************
*************************************************************/
static inline void Id1InsertToQueue( ts_BufferBlock *pstBlock)
{
/* put at end of free list */
pstBlock->pstNextFree = g_pstFreeList;
pstBlock->pstPrevFree = g_pstFreeList->pstPrevFree;
g_pstFreeList->pstPrevFree->pstNextFree = pstBlock;
g_pstFreeList->pstPrevFree = pstBlock;
/* put the buffer in new hash-queue if it has a device */
pstBlock->pstPrev = NULL;
pstBlock->pstNext = NULL;
if ( !pstBlock->uiDevice )
return;
pstBlock->pstNext = pstHash(pstBlock->uiDevice, pstBlock->ulBlockNr);
pstHash(pstBlock->uiDevice, pstBlock->ulBlockNr) = pstBlock;
pstBlock->pstNext->pstPrev = pstBlock;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -