⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 id1_buffer.c

📁 小型操作系统,以VC为开发环境,需要boachs调试
💻 C
📖 第 1 页 / 共 2 页
字号:
/***************************************************************************
**     File name   : id1_buffer.c
**     Author      : x.cheng
**     Create date :
**
**	   Comment:
**       this file implements the buffer-cache functions. 
**		 Race-conditions have been avoided by NEVER letting a interrupt change 
**		a buffer (except for the data, of course), but instead letting the 
**		caller do it. 
**		 NOTE! As interrupts can wake up a caller, some cli-sti sequences 
**		are needed to check for sleep-on-calls. 
**		 These should be extremely quick, though (I hope).
**
**     Revisions: 
**     $Log: id1_buffer.c,v $
**     Revision 1.4  2005/08/19 14:56:43  x.cheng
**     bug fixe, buffer range changed
**
**     Revision 1.3  2005/08/02 15:37:43  x.cheng
**     bug fixing~~~~~~~~~~~~~~~~~~~~
**
**     Revision 1.2  2005/07/27 16:00:37  x.cheng
**     change include path to newer....
**
**     Revision 1.1.1.1  2005/07/27 06:53:15  x.cheng
**     add into repositories
**
**
***************************************************************************/
#include "const.h"
#include "type.h"
#include "stdarg.h"
 
#include "..\..\Inc\i386\io.h"
#include "..\..\Inc\i386\system.h"
#include "..\..\Inc\i386\x86.h"
#include "..\..\Inc\i386\map.h"

#include "..\..\inc\ide.h"
#include "..\..\inc\dma.h"
#include "..\..\inc\mts.h"
#include "..\..\inc\tui.h"

#include "..\..\inc\debug.h"

#include "..\inc\def_ide.h"

/* debug preprocessor instrument
	#ifdef _DEBUG__
	#ifdef _DEBUG_IDE__
				
	#endif
	#endif	
***************************/

/***********extern variable***************/

/***********global variable***************/
unsigned long g_ulNrOfBlocks = 0;
ts_BufferBlock* g_apstHashTable[NR_HASH];	//NR_HASH = 307项
	//local...
static ts_BufferBlock* g_pstFreeList;
static ts_Task* g_pstBufferWaitTask;

/************local function prototype**************/
	//hash函数
#define _iHashFunction(iDevice, iBlock)	\
	( ((unsigned)(iDevice^iBlock)) % NR_HASH )
	//hash表项的计算宏定义。
#define pstHash(iDevice, iBlock)	\
	g_apstHashTable[_iHashFunction(iDevice, iBlock)]

static void Id1WaitOnBuffer(ts_BufferBlock* pstBlock);
static ts_BufferBlock* pstId1FindBuffer(int iDevice, int iBlock);
static inline void Id1RemoveFromQueue( ts_BufferBlock *pstBlock);
static inline void Id1InsertToQueue( ts_BufferBlock *pstBlock);

/************************************************************
*************************************************************
**      Function Name:			Id1BufferInitialize
**      Author:                 x.cheng
**
**      Comment:
**			初始化缓冲区,缓冲区范围:KernelEnd_ -- DMA_MEMORY_END
**		  从KernelEnd_开始,利用ts_BufferBlock结构管理整个缓冲区。
**
**      List of parameters:
**			no
**
**      Return value:   
**          no
**
**      Revisions:
**
*************************************************************
*************************************************************/
extern unsigned long KernelEnd_;
void Id1BufferInitialize(void)
{
	ts_BufferBlock *pstBlock = (ts_BufferBlock *)KERNEL_FREE_MEMORY_START;
	unsigned char *pucAddress = (unsigned char*)(DMA_MEMORY_END);
	int i;

	#ifdef _DEBUG__
	#ifdef _DEBUG_IDE__
		kprintf("\nBuffer from [%p] to [%p]\n", pstBlock, pucAddress);	
	#endif
	#endif	

	while ( (pucAddress -= BUFFER_BLOCK_SIZE) >= ((unsigned char*)(pstBlock+1)) ) {
		// refer to drv/inc/def_ide.h for detail comment.
		pstBlock->uiDevice = 0;
		pstBlock->ucDirty  = 0;
		pstBlock->ucRefers = 0;
		pstBlock->ucLocked = 0;
		pstBlock->ucUpToDate = 0;
		pstBlock->pstWaitTask	= NULL;
		pstBlock->pstPrev		= NULL;
		pstBlock->pstNext		= NULL;
		pstBlock->pucBlock		= pucAddress;
		pstBlock->pstPrevFree	= pstBlock-1;	//(1)some bug...
		pstBlock->pstNextFree	= pstBlock+1;
		pstBlock ++;
		g_ulNrOfBlocks ++;
	}
	pstBlock --;

	g_pstFreeList = (ts_BufferBlock *)KERNEL_FREE_MEMORY_START;
	g_pstFreeList->pstPrevFree = pstBlock;	//这里纠正了(1)处产生的bug
	pstBlock->pstNextFree = g_pstFreeList;
	#ifdef _DEBUG__
	#ifdef _DEBUG_IDE__
		kprintf("number of bufferblock= %ld, freelist from [%p] to [%p]\n", g_ulNrOfBlocks, g_pstFreeList, pstBlock);	
	#endif
	#endif	

	for(i=0; i<NR_HASH; i++) {
		g_apstHashTable[i] = NULL;
	}
}

/************************************************************
*************************************************************
**      Function Name:			Id1BufferRead
**      Author:                 x.cheng
**
**      Comment:
**			reads a specified block and returns the buffer 
**		  that contains it. It returns NULL if the block was unreadable.
**
**      List of parameters:
**			iDevice - which device.
**			iBlock - which block.
**
**      Return value:   
**          ts_BufferBlock* 
**
**      Revisions:
**
*************************************************************
*************************************************************/
ts_BufferBlock* pstId1BufferRead(int iDevice, int iBlock)
{
	ts_BufferBlock* pstBlock;

	#ifdef _DEBUG__
	#ifdef _DEBUG_IDE__
		kprintf("%s, read device %d block %d\n", __FUNCTION__, iDevice, iBlock);	
	#endif
	#endif	
//		kprintf("%s, read device %d block %d\n", __FUNCTION__, iDevice, iBlock);	
	if ( !(pstBlock=pstId1GetBlock(iDevice, iBlock)) )
		panic("\n%s:%s:%d line, GetBlock returned NULL\n", __FILE__,__FUNCTION__,__LINE__);

	if ( pstBlock->ucUpToDate )
		return pstBlock;
	//POSITION();
	// read from device...
	IdeReadWriteBlock(IDE_READ_BLK, pstBlock);
	#ifdef _DEBUG__
	#ifdef _DEBUG_IDE__
	POSITION();
	#endif
	#endif
	Id1WaitOnBuffer(pstBlock);
	//POSITION();
	
	if ( pstBlock->ucUpToDate )
		return pstBlock;
	//POSITION();

	Id1BufferRelease(pstBlock);
	return NULL;
}

/************************************************************
*************************************************************
**      Function Name:			Id1BufferRelease
**      Author:                 x.cheng
**
**      Comment:
**			release buffer...
**
**      List of parameters:
**			pucBlock - address
**
**      Return value:   
**
**      Revisions:
**
*************************************************************
*************************************************************/
void Id1BufferRelease( ts_BufferBlock* pstBlock)
{
	if (!pstBlock)
		return;

	Id1WaitOnBuffer(pstBlock);

	if ( !(pstBlock->ucRefers--) )
		panic("\n%s:%s:%d line, Trying to free free buffer\n", __FILE__,__FUNCTION__,__LINE__);

	vMtsTaskWakeup(g_pstBufferWaitTask);
}

/************************************************************
*************************************************************
**      Function Name:			pstId1GetBlock
**      Author:                 x.cheng
**
**      Comment:
**			Ok, this is GetBlock, and it isn't very clear, again to hinder
**		race-conditions. Most of the code is seldom used, (ie repeating),
**		so it should be much more efficient than it looks.
**
**      List of parameters:
**			iDevice - which device.
**			iBlock - which block.
**
**      Return value:   
**
**      Revisions:
**
*************************************************************
*************************************************************/
#define BADNESS(pstBlock) (((pstBlock)->ucDirty<<1)+(pstBlock)->ucLocked)
ts_BufferBlock* pstId1GetBlock(int iDevice, int iBlock)
{
	ts_BufferBlock *pstTemp, *pstBlock;
	
	//POSITION();
lbl_Repeat:
	if ( (pstBlock=pstId1GetHashTable(iDevice, iBlock)) )
		return pstBlock;
	//POSITION();

	pstTemp = g_pstFreeList;
	do {
		if (pstTemp->ucRefers)
			continue;
		if ( !pstBlock || BADNESS(pstTemp)<BADNESS(pstBlock) ) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -