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

📄 piece.c

📁 嵌入式系统中文件系统源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <sys/syscall.h>
#include <ramdisk.h>
#include <piece.h>


#ifdef RAMDISK_ID



// the piece location table
void **RD_PLT;

// the size of a piece
unsigned long RDPieceSize;

#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
	// variable block size
#else
	// fixed block size
	unsigned long RDSystemBlockSize;
#endif



// dskblk.c
extern struct diskBlock *RD_FirstFreeBlock;

// basic.c
//extern int RDerrno;
extern void *RD_BootBegin;
extern unsigned long RD_DiskSize;
extern unsigned long RDLowerBoundary;
extern unsigned long RDUpperBoundary;


void memoryZero(void *source, unsigned int size);



/*************************************************************
Function: initPieceParameters
Description:
	initialize the piece parameters
Input:
	NONE
Output:
	NONE
**************************************************************/
void initPieceParameters(void)
{
#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
  RDPieceSize = RD_PIECE_SIZE;
#else
  RDSystemBlockSize = RD_BLOCK_SIZE + sizeof(struct diskBlock);
  RDPieceSize = RDSystemBlockSize * RD_BLOCKS_PER_PIECE;
#endif

  return;
}



/*************************************************************
Function: initPLT
Description:
	initialize the RD_PLT
Input:
	NONE
Output:
	NONE
**************************************************************/
void initPLT(void)
{
//  memoryZero(RD_PLT, (RD_PLT_ENTRY_NUM * sizeof(void *)));

#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
  memoryZero(RD_PLT, (RD_PLT_ENTRY_NUM * sizeof(PIECE_DS)));
#else
  memoryZero(RD_PLT, (RD_PLT_ENTRY_NUM * sizeof(void *)));
#endif  
  return;
}

/*************************************************************
Function: getPiece
Description:
	get a piece from memory
Input:
	wantSize
Output:
	the pointer to the head of the piece
	NULL if failed
**************************************************************/
//void *getPiece(unsigned long wantSize)

void *getPiece(unsigned long wantSize)
{
  int index;
  void *piece;
  
  PIECE_DS *pPieceDS;

  // make wantSize a multiple of the size of (block header + block size(4096 bytes) + block tail)
  wantSize = ((wantSize - 1)/(B_HEADER + RD_BLOCK_SIZE + B_TAIL) + 1) * (B_HEADER + RD_BLOCK_SIZE + B_TAIL);
  
  // check if the size of all the pieces plus wantSize is
  //	over the maximum RAMDISK size
  if ((RD_DiskSize + wantSize) > RD_PLT_ENTRY_NUM * RDPieceSize)
  {
	RDerrno = ERROR_DISK_FULL;
  	return NULL;
  }

/* marked by chilong 10/4/2001   
  // find an emtry entry in the RD_PLT
  for (index = 0; index < RD_PLT_ENTRY_NUM; index++)
  {
	if (RD_PLT[index] == NULL)
	{
		break;
	}
  }
   marked 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 == NULL)
	{
		break;
	}
  }
   
  if (index == RD_PLT_ENTRY_NUM)
  {
	// no more empty entry, disk full
	RDerrno = ERROR_DISK_FULL;
	return NULL;
  }

/* marked by chilong 10/1/2001
  // get a piece of memory  
  piece = sc_malloc(RDPieceSize);
  if (piece == NULL)
  {
	RDerrno = ERROR_ALLOC_MEM;
	return NULL;
  }
   marked by chilong 10/1/2001 */
   
  if (wantSize <= RDPieceSize)
  	wantSize = RDPieceSize;
  	
  piece = sc_malloc(wantSize);
  if (piece == NULL)
  {
	RDerrno = ERROR_ALLOC_MEM;
	return NULL;
  }

  // set the owner of this piece of memory to kernel
  setMemoryOwner(piece, -11);

/* marked by chilong 10/2/2001 
  // record the location of the piece in piece location table (RD_PLT)
  RD_PLT[index] = piece;
  
  addNewPieceToFBL(piece);

  RD_DiskSize += RDPieceSize;
  
   marked by chilong 10/2/2001 */

  // record the location of the piece in piece location table (RD_PLT)
  pPieceDS->startAddress = piece;
  pPieceDS->size = wantSize;

  addNewPieceToFBL(piece, wantSize);
  RD_DiskSize += wantSize;

  ((struct signature *)RD_BootBegin)->size = RD_DiskSize;

  return piece;
}

/*************************************************************
Function: addNewPieceToFBL
Description:
	add a newly obtained piece to the free block list
Input:
	piece - the new piece
	size - the size of the piece
Output:
	NONE
**************************************************************/
//void addNewPieceToFBL(void *piece)
void addNewPieceToFBL(void *piece, unsigned long size)

{
  struct diskBlock *currBlock;
  struct diskBlock *prevBlock;
  struct diskBlock *nextBlock;
  struct diskBlock *tailBlock;

#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK
#else
  int index;
#endif

#ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  // prepare the header of the new piece
  currBlock = (struct diskBlock *)piece;

  // chilong: check this line while tracing 
  //	the code in 
  //	  else if (blkPtr1->size >= wantSize) {...}
  //	in getBlock2() of dskblk.c
  
//  currBlock->size = RDPieceSize - B_HEADER - B_TAIL;

  currBlock->size = size - B_HEADER - B_TAIL;
  
  currBlock->dataSize = 0;
  currBlock->actualSize = 0;
  currBlock->status = 0;
  currBlock->userCount = 0;
  currBlock->prevBlock = NULL;
  currBlock->nextBlock = NULL;
  
//  *((long *)((unsigned long)currBlock + RDPieceSize - B_TAIL)) = currBlock->size;

  *((long *)((unsigned long)currBlock + size - B_TAIL)) = currBlock->size;

  // the last block is also the current block
  tailBlock = currBlock;

#else	// #ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  // a new piece has BLOCKS_IN_PIECE empty blocks
  // put them in the free block list
  currBlock = (struct diskBlock *)piece;
  tailBlock = NULL;

//  for (index = 0; index < RD_BLOCKS_PER_PIECE; index++)

  for (index = 0; index < size/RD_BLOCK_SIZE; index++)
  {
	currBlock->size = RD_BLOCK_SIZE;
	currBlock->dataSize = 0;
	currBlock->actualSize = 0;
	currBlock->status = 0;
	currBlock->userCount = 0;
	currBlock->prevBlock = (void *)tailBlock;
	currBlock->nextBlock = (void *)((unsigned long)currBlock + RDSystemBlockSize);

	tailBlock = currBlock;
	currBlock = currBlock->nextBlock;
  }

  currBlock = (struct diskBlock *)piece;

#endif	// #ifdef RAMDISK_USE_VARIABLE_SIZE_BLOCK

  // now we have a list of blocks in ascending order to be added to the free block list
  // currBlock is the head and tailBlock is the tail of the list of blocks

  if (RD_FirstFreeBlock == NULL)
  {
	// the free block list is empty
	RD_FirstFreeBlock = currBlock;
	((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;

	return;
  }

  // find the suitable position in the free block list for the new block
  // remember that the list is sort ascendingly according to the addresses of the free blocks
  nextBlock = RD_FirstFreeBlock;
  prevBlock = NULL;

  while (nextBlock != NULL)
  {
	if (nextBlock > currBlock)
		break;

	prevBlock = nextBlock;
	nextBlock = nextBlock->nextBlock;
  }

  if (nextBlock == NULL)
  {
	// the new block is added to the tail of the free block list
	prevBlock->nextBlock = currBlock;
	currBlock->prevBlock = prevBlock;

	return;
  }

  if (prevBlock == NULL)
  {
	// the new block is added to the head of the free block list
	RD_FirstFreeBlock = currBlock;
	((struct signature *)RD_BootBegin)->freeBegin = (void *)RD_FirstFreeBlock;
	tailBlock->nextBlock = nextBlock;
	nextBlock->prevBlock = tailBlock;

	return;
  }

  // the new block is added at the middle of the free block list
  prevBlock->nextBlock = currBlock;
  currBlock->prevBlock = prevBlock;
  nextBlock->prevBlock = tailBlock;
  tailBlock->nextBlock = nextBlock;

  return;
}



/*************************************************************
Function: freePiece
Description:
	free a piece to memory
Input:
	piece - the target piece
Output:
	 0 if succeeded
	-1 if failed
**************************************************************/
int freePiece(void *piece)
{
  int index;
  struct diskBlock *currBlock;
  
  PIECE_DS *pPieceDS;

  if (((unsigned long)piece < RDLowerBoundary) || ((unsigned long)piece >= RDUpperBoundary))
  {
	// the piece is out of bound
	return -1;
  }

/* marked by chilong 10/3/2001 
  // check if the target piece is within RD_PLT
  for (index = 0; index < RD_PLT_ENTRY_NUM; index++)
  {
	if (RD_PLT[index] == piece)
	{
		// got it, the target piece is here
		break;
	}

⌨️ 快捷键说明

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