This repository has been archived on 2025-04-11. You can view files and clone it, but cannot push or open issues or pull requests.
csce410pine64backup/MP4/MP4_Sources/cont_frame_pool.C

183 lines
4.7 KiB
C
Raw Normal View History

2017-07-06 17:47:31 -05:00
#include "cont_frame_pool.H"
#include "console.H"
#include "utils.H"
#include "assert.H"
ContFramePool* ContFramePool::pools = (ContFramePool *) FRAME_SIZE;
unsigned int ContFramePool::nPools = 0;
2017-07-06 17:47:31 -05:00
ContFramePool::ContFramePool(unsigned long _base_frame_no,
unsigned long _nframes,
unsigned long _info_frame_no,
unsigned long _n_info_frames)
2017-07-06 17:47:31 -05:00
{
// Bitmap must fit in a single frame!
assert(_nframes <= FRAME_SIZE * 8);
base_frame_no = _base_frame_no;
nframes = _nframes;
nFreeFrames = _nframes;
info_frame_no = _info_frame_no;
n_info_frames = _n_info_frames;
// If _info_frame_no is zero then we keep management info in the first
//frame, else we use the provided frame to keep management info
if(info_frame_no == 0) {
bitmap = (unsigned char *) (base_frame_no * FRAME_SIZE);
} else {
bitmap = (unsigned char *) (info_frame_no * FRAME_SIZE);
}
// Number of frames must be "fill" the bitmap!
assert ((nframes % 8 ) == 0);
// Everything ok. Proceed to mark all bits in the bitmap
for(int i=0; i*8 < _nframes; i++) {
bitmap[i] = 0xFF;
}
// Mark the first frame as being used if it is being used
if(_info_frame_no == 0) {
bitmap[0] = 0x7F;
nFreeFrames--;
}
pools[nPools] = *this;
nPools += 1;
Console::puts("Frame Pool initialized\n");
2017-07-06 17:47:31 -05:00
}
unsigned long ContFramePool::get_frames(unsigned int _n_frames)
{
assert(_n_frames > 1);
// Any frames left to allocate?
assert(nFreeFrames > 0);
// Find a frame that is not being used and return its frame index.
// Mark that frame as being used in the bitmap.
unsigned int frame_no = base_frame_no;
unsigned int i = 0;
while (bitmap[i] == 0x0) {
i++;
}
frame_no += i * 8;
unsigned char mask = 0x80;
while ((mask & bitmap[i]) == 0) {
mask = mask >> 1;
frame_no++;
}
nFreeFrames--;
// Update bitmap
bitmap[i] = bitmap[i] ^ mask;
return (frame_no);
2017-07-06 17:47:31 -05:00
}
void ContFramePool::mark_inaccessible(unsigned long _base_frame_no,
unsigned long _nframes)
{
// Mark all frames in the range as being used.
int i ;
for(i = _base_frame_no; i < _base_frame_no + _nframes; i++){
mark_inaccessible(i);
}
nFreeFrames -= _nframes;
}
void ContFramePool::mark_inaccessible(unsigned long _frame_no)
{
// Let's first do a range check.
assert ((_frame_no >= base_frame_no) && (_frame_no < base_frame_no + nframes));
unsigned int bitmap_index = (_frame_no - base_frame_no) / 8;
unsigned char mask = 0x80 >> ((_frame_no - base_frame_no) % 8);
// Is the frame being used already?
assert((bitmap[bitmap_index] & mask) != 0);
// Update bitmap
bitmap[bitmap_index] ^= mask;
nFreeFrames--;
}
void ContFramePool::release_frames(unsigned long _frame_no)
2017-07-06 17:47:31 -05:00
{
unsigned int i = 0;
while(i < nPools)
{
if(_frame_no <= pools[i].base_frame_no || _frame_no > (pools[i].base_frame_no + pools[i].nframes))
{
i++;
}
else
{
pools[i].release_frames_here(_frame_no);
return;
}
}
2017-07-06 17:47:31 -05:00
}
void ContFramePool::release_frames_here(unsigned long _first_frame_no)
2017-07-06 17:47:31 -05:00
{
// -- WE LEAVE THE IMPLEMENTATION OF THIS FUNCTION TO YOU.
// NOTE: Keep in mind that you first need to identify the correct frame pool.
// The function is static, and you are only given a frame number. You do have
// to figure out which frame pool this frame belongs to before you can call the
// frame-pool-specific release_frame function.
// Inside the frame-pool specific release_frame function we mark the frame
// as released as follows:
unsigned char * bitmap = this->bitmap;
unsigned int bitmap_index = (_first_frame_no - base_frame_no) / 8;
unsigned char mask = 0x80 >> ((_first_frame_no - base_frame_no) % 8);
if((bitmap[bitmap_index] & mask) != 0) {
Console::puts("Error, Frame being released is not being used\n");
assert(false);
}
bitmap[bitmap_index] ^= mask;
nFreeFrames++;
if(mask != 0x01)
{
mask = mask >> 1;
}
else
{
mask = 0x80;
bitmap_index++;
}
while(bitmap[bitmap_index] & mask == 0)
{
bitmap[bitmap_index] ^= mask;
if(mask != 0x01)
{
mask = mask >> 1;
}
else
{
mask = 0x80;
bitmap_index++;
}
nFreeFrames++;
}
2017-07-06 17:47:31 -05:00
}
unsigned long ContFramePool::needed_info_frames(unsigned long _n_frames)
{
return (_n_frames / (FRAME_SIZE * 8)) + ((_n_frames % (FRAME_SIZE * 8)) > 0 ? 1 : 0);
2017-07-06 17:47:31 -05:00
}