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

📄 piece.c

📁 嵌入式系统中文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
  }
   marked by chilong 10/3/2001 */

  /**** modified by chilong 10/4/2001 ****/
  // find an emtry entry in the RD_PLT
  for (index = 0; index < RD_PLT_ENTRY_NUM; index++)
  {
  	pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + index);
  	if (pPieceDS->startAddress == piece)
	{
		break;
	}
  }
  /**** modified by chilong 10/4/2001 ****/

  if (index == RD_PLT_ENTRY_NUM)
  {
	return -1;	// the target piece is not inside RD_PLT
  }

  // target piece found, check the free block link
  if (checkPieceFree(piece) == 0)
  {
	return -1;	// not all blocks within the target piece are free
  }

#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  // the piece can be freed
  currBlock = (struct diskBlock *)piece;

  if (currBlock->prevBlock != NULL)
	((struct diskBlock *)(currBlock->prevBlock))->nextBlock = currBlock->nextBlock;

  if (currBlock->nextBlock != NULL)
	((struct diskBlock *)(currBlock->nextBlock))->prevBlock = currBlock->prevBlock;

  if (RD_FirstFreeBlock == currBlock)
  {
	RD_FirstFreeBlock = currBlock->nextBlock;
	((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
  }

#else	// #ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  // all blocks within the target piece are free
  // remove these blocks from the free block list
  currBlock = (struct diskBlock *)piece;
  for (index = 0; index < RD_BLOCKS_PER_PIECE; index++)
  {
	// if the first free block is the current block, the next block
	//   becomes the first free block
	if (RD_FirstFreeBlock == currBlock)
	{
		RD_FirstFreeBlock = currBlock->nextBlock;
		((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
	}

	// link up the previous and the next blocks to skip the current block
	if (currBlock->prevBlock != NULL)
		((struct diskBlock *)(currBlock->prevBlock))->nextBlock = currBlock->nextBlock;
	if (currBlock->nextBlock != NULL)
		((struct diskBlock *)(currBlock->nextBlock))->prevBlock = currBlock->prevBlock;

	// go to next block
	currBlock = (struct diskBlock *)((unsigned long)currBlock + RDSystemBlockSize);
  }

#endif	// #ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  // all done, final clean up
  sc_free(piece);
  
  RD_DiskSize -= pPieceDS->size;
  pPieceDS->startAddress = NULL;
  pPieceDS->size = 0;
  
  
  ((struct signature *)RD_BootBegin)->size = RD_DiskSize;

  return 0;
}



/*************************************************************
Function: checkPieceFree
Description:
	check if the target piece is completely free
Input:
	piece - the target piece
Output:
	1 if totally free
	0 if not free
**************************************************************/
int checkPieceFree(void *piece)
{
#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  struct diskBlock *currBlock;

  int index;
  PIECE_DS *pPieceDS;
  
  // check if the target piece is within RD_PLT
  for (index = 0; index < RD_PLT_ENTRY_NUM; index++)
  {
  	pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + index);
  	if (pPieceDS->startAddress == piece)
  	{
		// got it, the target piece is here
		break;
	}
  }
  
  if (index == RD_PLT_ENTRY_NUM)
  	return -1;

  currBlock = RD_FirstFreeBlock;
  while (currBlock != NULL)
  {
	if (currBlock == piece)
	{
		// the starting locations match, check if the whole piece is free
//		if (currBlock->size < RDPieceSize - B_HEADER - B_TAIL)

		if (currBlock->size < pPieceDS->size - B_HEADER - B_TAIL)
		{
			// only the first part of the piece is free
			// cannot free the piece
			return 0;
		}
		else
		{
			// the piece can be freed
			return 1;
		}
	}

	// not this block, try next block
	currBlock = currBlock->nextBlock;
  }

  return 0;

#else	// #ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  int index;
  struct diskBlock *currBlock;
  char isFree[RD_BLOCKS_PER_PIECE];
  unsigned long lowerBound;
  unsigned long upperBound;

  // set the array to 0
  memoryZero(isFree, RD_BLOCKS_PER_PIECE);

  // set the lower and upper bounds
  lowerBound = (unsigned long)piece;
  upperBound = (unsigned long)piece + RDPieceSize;

  // check all blocks in the free block list
  currBlock = RD_FirstFreeBlock;

  while (currBlock != NULL)
  {
	if ((unsigned long)currBlock >= lowerBound && (unsigned long)currBlock < upperBound)
	{
		// the current free block is within the piece
		index = ((unsigned long)currBlock - (unsigned long)piece) / RDSystemBlockSize;
		isFree[index] = 1;
	}
	currBlock = currBlock->nextBlock;
  }

  // check if all blocks within the target piece is free
  for (index = 0; index < RD_BLOCKS_PER_PIECE; index++)
  {
	if (isFree[index] == 0)
		return 0;
  }

  // all blocks within the target piece is free
  return 1;

#endif	// #ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
}



/*************************************************************
Function: freeAllPieceNC
Description:
	free all pieces without checking whether they are totally unused
Input:
	index - freeing starts from this entry
Output:
	NONE
**************************************************************/
void freeAllPieceNC(int index)
{
  int i;

/* marked by chilong 10/3/2001
  for (i = index; i < RD_PLT_ENTRY_NUM; i++)
  {
	if (RD_PLT[i] != NULL)
	{
		if ((unsigned long)(RD_PLT[i]) >= RDLowerBoundary && (unsigned long)(RD_PLT[i]) < RDUpperBoundary)
		{
			sc_free(RD_PLT[i]);
			RD_PLT[i] = NULL;
			RD_DiskSize -= RDPieceSize;
			((struct signature *)RD_BootBegin)->size = RD_DiskSize;
		}
	}
  }
   marked by chilong 10/3/2001 */
   
  PIECE_DS *pPieceDS;
  for (i = index; i < RD_PLT_ENTRY_NUM; i++)
  {
  	pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + i);
  	if (pPieceDS->startAddress != NULL)
	{
		if ((unsigned long)(pPieceDS->startAddress) >= RDLowerBoundary && 
			(unsigned long)(pPieceDS->startAddress) < RDUpperBoundary)
		{
			sc_free(pPieceDS->startAddress);
			pPieceDS->startAddress = NULL;
			RD_DiskSize -= pPieceDS->size;
			((struct signature *)RD_BootBegin)->size = RD_DiskSize;
		}
	}
  }
  
  return;
}



/*************************************************************
Function: freeUnusedPiece
Description:
	free all unused pieces
Input:
	index - freeing starts from this entry
Output:
	number of pieces freed
**************************************************************/
int freeUnusedPiece(int index)
{
  int i;
  int freeCount;

/* marked by chilong 10/3/2001
  freeCount = 0;
  for (i = index; i < RD_PLT_ENTRY_NUM; i++)
  {
	if (RD_PLT[i] != NULL)
	{
		if ((unsigned long)(RD_PLT[i]) >= RDLowerBoundary && (unsigned long)(RD_PLT[i]) < RDUpperBoundary)
		{
			if (freePiece(RD_PLT[i]) == 0)
				freeCount++;
		}
	}
  }
   marked by chilong 10/3/2001 */

  PIECE_DS *pPieceDS;
  
  freeCount = 0;
  for (i = index; i < RD_PLT_ENTRY_NUM; i++)
  {
  	pPieceDS = (PIECE_DS*) ((PIECE_DS*)RD_PLT + i);
  	if (pPieceDS->startAddress != NULL)
	{
		if ((unsigned long)(pPieceDS->startAddress) >= RDLowerBoundary && 
			(unsigned long)(pPieceDS->startAddress) < RDUpperBoundary)
		{
			if (freePiece(pPieceDS->startAddress) == 0)
				freeCount++;
		}
	}
  }
   
  return freeCount;
}



#ifdef PIECE_TEST

//#include <ansi_c/stdio.h>
#include <stdio.h>

void RD4showFreeMemSize(void)
{
  struct diskBlock *curBlock;
  struct diskBlock *lastBlock = NULL;
  char tempString[80];
  int blockCount;

  curBlock = RD4RD_FirstFreeBlock;

  sprintf(tempString, "From head to tail\r\n");
  myLogWrite("\\PIECE.TXT", tempString, strlen(tempString));

  blockCount = 0;

  while (curBlock != NULL)
  {
	sprintf(tempString, "[%08x] %6d\r\n", (unsigned long)curBlock, curBlock->size);
	myLogWrite("\\PIECE.TXT", tempString, strlen(tempString));

	blockCount++;

	lastBlock = curBlock;
	curBlock = curBlock->nextBlock;
  }

  sprintf(tempString, "%d blocks\r\n", blockCount);
  myLogWrite("\\PIECE.TXT", tempString, strlen(tempString));
  printStringLn(tempString);

  sprintf(tempString, "From tail to head\r\n");
  myLogWrite("\\PIECE.TXT", tempString, strlen(tempString));

  blockCount = 0;

  while (lastBlock != NULL)
  {
	sprintf(tempString, "[%08x] %6d\r\n", (unsigned long)lastBlock, lastBlock->size);
	myLogWrite("\\PIECE.TXT", tempString, strlen(tempString));

	blockCount++;

	lastBlock = lastBlock->prevBlock;
  }

  sprintf(tempString, "%d blocks\r\n", blockCount);
  myLogWrite("\\PIECE.TXT", tempString, strlen(tempString));
  printStringLn(tempString);

  return;
}
#endif	// #ifdef PIECE_TEST



#endif	// #ifdef RAMDISK_ID



⌨️ 快捷键说明

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