📄 piece.c
字号:
#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 + -