Since cont_frame_pool isn't working properly, making new implementation with simple_frame_pool as instructed.
This commit is contained in:
parent
9e1e4a7663
commit
66446dd170
5 changed files with 767 additions and 217 deletions
Binary file not shown.
404
MP3/MP3_Sources/tempc
Normal file
404
MP3/MP3_Sources/tempc
Normal file
|
@ -0,0 +1,404 @@
|
||||||
|
/*
|
||||||
|
File: ContFramePool.C
|
||||||
|
|
||||||
|
Author:
|
||||||
|
Date :
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/*
|
||||||
|
POSSIBLE IMPLEMENTATION
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
The class SimpleFramePool in file "simple_frame_pool.H/C" describes an
|
||||||
|
incomplete vanilla implementation of a frame pool that allocates
|
||||||
|
*single* frames at a time. Because it does allocate one frame at a time,
|
||||||
|
it does not guarantee that a sequence of frames is allocated contiguously.
|
||||||
|
This can cause problems.
|
||||||
|
|
||||||
|
The class ContFramePool has the ability to allocate either single frames,
|
||||||
|
or sequences of contiguous frames. This affects how we manage the
|
||||||
|
free frames. In SimpleFramePool it is sufficient to maintain the free
|
||||||
|
frames.
|
||||||
|
In ContFramePool we need to maintain free *sequences* of frames.
|
||||||
|
|
||||||
|
This can be done in many ways, ranging from extensions to bitmaps to
|
||||||
|
free-lists of frames etc.
|
||||||
|
|
||||||
|
IMPLEMENTATION:
|
||||||
|
|
||||||
|
One simple way to manage sequences of free frames is to add a minor
|
||||||
|
extension to the bitmap idea of SimpleFramePool: Instead of maintaining
|
||||||
|
whether a frame is FREE or ALLOCATED, which requires one bit per frame,
|
||||||
|
we maintain whether the frame is FREE, or ALLOCATED, or HEAD-OF-SEQUENCE.
|
||||||
|
The meaning of FREE is the same as in SimpleFramePool.
|
||||||
|
If a frame is marked as HEAD-OF-SEQUENCE, this means that it is allocated
|
||||||
|
and that it is the first such frame in a sequence of frames. Allocated
|
||||||
|
frames that are not first in a sequence are marked as ALLOCATED.
|
||||||
|
|
||||||
|
NOTE: If we use this scheme to allocate only single frames, then all
|
||||||
|
frames are marked as either FREE or HEAD-OF-SEQUENCE.
|
||||||
|
|
||||||
|
NOTE: In SimpleFramePool we needed only one bit to store the state of
|
||||||
|
each frame. Now we need two bits. In a first implementation you can choose
|
||||||
|
to use one char per frame. This will allow you to check for a given status
|
||||||
|
without having to do bit manipulations. Once you get this to work,
|
||||||
|
revisit the implementation and change it to using two bits. You will get
|
||||||
|
an efficiency penalty if you use one char (i.e., 8 bits) per frame when
|
||||||
|
two bits do the trick.
|
||||||
|
|
||||||
|
DETAILED IMPLEMENTATION:
|
||||||
|
|
||||||
|
How can we use the HEAD-OF-SEQUENCE state to implement a contiguous
|
||||||
|
allocator? Let's look a the individual functions:
|
||||||
|
|
||||||
|
Constructor: Initialize all frames to FREE, except for any frames that you
|
||||||
|
need for the management of the frame pool, if any.
|
||||||
|
|
||||||
|
get_frames(_n_frames): Traverse the "bitmap" of states and look for a
|
||||||
|
sequence of at least _n_frames entries that are FREE. If you find one,
|
||||||
|
mark the first one as HEAD-OF-SEQUENCE and the remaining _n_frames-1 as
|
||||||
|
ALLOCATED.
|
||||||
|
|
||||||
|
release_frames(_first_frame_no): Check whether the first frame is marked as
|
||||||
|
HEAD-OF-SEQUENCE. If not, something went wrong. If it is, mark it as FREE.
|
||||||
|
Traverse the subsequent frames until you reach one that is FREE or
|
||||||
|
HEAD-OF-SEQUENCE. Until then, mark the frames that you traverse as FREE.
|
||||||
|
|
||||||
|
mark_inaccessible(_base_frame_no, _n_frames): This is no different than
|
||||||
|
get_frames, without having to search for the free sequence. You tell the
|
||||||
|
allocator exactly which frame to mark as HEAD-OF-SEQUENCE and how many
|
||||||
|
frames after that to mark as ALLOCATED.
|
||||||
|
|
||||||
|
needed_info_frames(_n_frames): This depends on how many bits you need
|
||||||
|
to store the state of each frame. If you use a char to represent the state
|
||||||
|
of a frame, then you need one info frame for each FRAME_SIZE frames.
|
||||||
|
|
||||||
|
A WORD ABOUT RELEASE_FRAMES():
|
||||||
|
|
||||||
|
When we releae a frame, we only know its frame number. At the time
|
||||||
|
of a frame's release, we don't know necessarily which pool it came
|
||||||
|
from. Therefore, the function "release_frame" is static, i.e.,
|
||||||
|
not associated with a particular frame pool.
|
||||||
|
|
||||||
|
This problem is related to the lack of a so-called "placement delete" in
|
||||||
|
C++. For a discussion of this see Stroustrup's FAQ:
|
||||||
|
http://www.stroustrup.com/bs_faq2.html#placement-delete
|
||||||
|
|
||||||
|
*/
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* DEFINES */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* -- (none) -- */
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* INCLUDES */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "cont_frame_pool.H"
|
||||||
|
#include "console.H"
|
||||||
|
#include "utils.H"
|
||||||
|
#include "assert.H"
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* DATA STRUCTURES */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* -- (none) -- */
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* CONSTANTS */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* -- (none) -- */
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* FORWARDS */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* -- (none) -- */
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* METHODS FOR CLASS C o n t F r a m e P o o l */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
ContFramePool* ContFramePool::pools = (ContFramePool *) FRAME_SIZE; // List of frame pools, managed by the class
|
||||||
|
unsigned int ContFramePool::nPools = 0; // Number of pools being managed
|
||||||
|
|
||||||
|
ContFramePool::ContFramePool(unsigned long _base_frame_no,
|
||||||
|
unsigned long _n_frames,
|
||||||
|
unsigned long _info_frame_no,
|
||||||
|
unsigned long _n_info_frames)
|
||||||
|
{
|
||||||
|
// Bitmap must fit in a single frame!
|
||||||
|
// NOTE: In theory, we don't need to make the bitmap any larger,
|
||||||
|
// since as stated in the instructions it is already big enough to
|
||||||
|
// hold for 128MB of memory with one bit per frame, so should still
|
||||||
|
// be enough for 64MB of memory with 2 bits per frame.
|
||||||
|
// Assertion changed to match max size of frames allowed.
|
||||||
|
assert(_n_frames <= FRAME_SIZE * 4);
|
||||||
|
|
||||||
|
base_frame_no = _base_frame_no;
|
||||||
|
nframes = _n_frames;
|
||||||
|
nFreeFrames = _n_frames;
|
||||||
|
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(s), else we use the provided frame(s) to keep management info
|
||||||
|
// NOTE: bitmap needs to be allocated with n_info_frames if specified.
|
||||||
|
if(info_frame_no == 0)
|
||||||
|
{
|
||||||
|
bitmap = (unsigned char *) (base_frame_no * FRAME_SIZE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bitmap = (unsigned char *) (info_frame_no * FRAME_SIZE * n_info_frames);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Number of frames must "fill" the bitmap!
|
||||||
|
assert ((nframes % 8 ) == 0);
|
||||||
|
|
||||||
|
|
||||||
|
// Everything ok. Proceed to mark all bits in the bitmap
|
||||||
|
// NOTE: changed to reflect that I need 2 bits per frame now
|
||||||
|
for(int i=0; i*4 < _n_frames; i++)
|
||||||
|
{
|
||||||
|
bitmap[i] = 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mark the first frame as being used if it is being used
|
||||||
|
// NOTE: need to mark multiple frames if needed.
|
||||||
|
if(info_frame_no == 0)
|
||||||
|
{
|
||||||
|
bitmap[0] = 0x3F;
|
||||||
|
nFreeFrames--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
unsigned int i = info_frame_no / 4;
|
||||||
|
unsigned int r = info_frame_no % 4;
|
||||||
|
unsigned char mask = 0x80;
|
||||||
|
mask = mask >> r*2;
|
||||||
|
|
||||||
|
unsigned int c = 0;
|
||||||
|
while(c < n_info_frames)
|
||||||
|
{
|
||||||
|
bitmap[i] = bitmap[i] ^ mask;
|
||||||
|
bitmap[i] = bitmap[i] ^ (mask >> 1);
|
||||||
|
if(mask == 0x02)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
mask = 0x80;
|
||||||
|
}
|
||||||
|
c++;
|
||||||
|
nFreeFrames--;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pools[nPools] = *this;
|
||||||
|
nPools += 1;
|
||||||
|
|
||||||
|
Console::puts("Frame Pool initialized\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ContFramePool::get_frames(unsigned int _n_frames)
|
||||||
|
{
|
||||||
|
// Are there enough frames left to allocate?
|
||||||
|
assert(nFreeFrames > _n_frames);
|
||||||
|
|
||||||
|
// Find a frame that is not being used and return its frame index.
|
||||||
|
// Mark that frame as being used in the bitmap.
|
||||||
|
// NOTE: Must be updated to find a sequence of contiguous frames
|
||||||
|
// that are not being used and return the index of the head.
|
||||||
|
unsigned int frame_no = base_frame_no;
|
||||||
|
|
||||||
|
// i is being used as the frame_no / 4
|
||||||
|
// j is frame_no % 4
|
||||||
|
// together, they will give the actual frame_no.
|
||||||
|
// c is used as a counter to count a squence of free frames.
|
||||||
|
unsigned int i = 0;
|
||||||
|
unsigned int j = 0;
|
||||||
|
unsigned int c = 0;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
unsigned char mask = 0x80 >> (j*2);
|
||||||
|
// check every 2 bits for a free frame in the bitmap
|
||||||
|
while((mask & bitmap[i]) == 0 || ((mask >> 1) & bitmap[i]) == 0)
|
||||||
|
{
|
||||||
|
if(mask != 0x02)
|
||||||
|
{
|
||||||
|
j++;
|
||||||
|
mask = mask >> 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
j = 0;
|
||||||
|
mask = 0x80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// if frame is found, start checking for sequence
|
||||||
|
unsigned int temp = i;
|
||||||
|
c++;
|
||||||
|
while(c < _n_frames)
|
||||||
|
{
|
||||||
|
if(mask != 0x02)
|
||||||
|
{
|
||||||
|
mask = mask >> 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp++;
|
||||||
|
mask = 0x80;
|
||||||
|
}
|
||||||
|
if((mask & bitmap[temp]) != 0 && ((mask >> 1) & bitmap[temp]) != 0)
|
||||||
|
{
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
c = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(c == _n_frames)
|
||||||
|
{
|
||||||
|
nFreeFrames -= _n_frames;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
frame_no += i*4 + j;
|
||||||
|
|
||||||
|
// Update bitmap
|
||||||
|
// First: clear most significant bit to mark head of sequence.
|
||||||
|
bitmap[i] = bitmap[i] ^ (0x80 >> (j*2));
|
||||||
|
// Second: clear both bits for all remaining frames in the sequence.
|
||||||
|
c = 1;
|
||||||
|
unsigned char mask = 0x80 >> j*2;
|
||||||
|
unsigned int temp = i;
|
||||||
|
while(c < _n_frames)
|
||||||
|
{
|
||||||
|
if(mask != 0x02)
|
||||||
|
{
|
||||||
|
mask = mask >> 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp++;
|
||||||
|
mask = 0x80;
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap[temp] = bitmap[temp] ^ mask;
|
||||||
|
bitmap[temp] = bitmap[temp] ^ (mask >> 1);
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return (frame_no);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContFramePool::mark_inaccessible(unsigned long _base_frame_no,
|
||||||
|
unsigned long _n_frames)
|
||||||
|
{
|
||||||
|
// Mark all frames in the range as being used.
|
||||||
|
int i ;
|
||||||
|
for(i = _base_frame_no; i < _base_frame_no + _n_frames; i++){
|
||||||
|
mark_inaccessible(i);
|
||||||
|
}
|
||||||
|
nFreeFrames -= _n_frames;
|
||||||
|
}
|
||||||
|
|
||||||
|
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) / 4;
|
||||||
|
unsigned char mask = 0x80 >> ((_frame_no - base_frame_no) % 4) * 2;
|
||||||
|
|
||||||
|
// Is the frame being used already?
|
||||||
|
assert(((bitmap[bitmap_index] & mask) != 0) && (bitmap[bitmap_index] & (mask >> 1)) != 0);
|
||||||
|
|
||||||
|
// Update bitmap
|
||||||
|
bitmap[bitmap_index] ^= mask;
|
||||||
|
bitmap[bitmap_index] ^= mask >> 1;
|
||||||
|
nFreeFrames--;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContFramePool::release_frames(unsigned long _frame_no)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContFramePool::release_frames_here(unsigned long _first_frame_no)
|
||||||
|
{
|
||||||
|
unsigned char * bitmap = this->bitmap;
|
||||||
|
|
||||||
|
unsigned int bitmap_index = (_first_frame_no - base_frame_no) / 4;
|
||||||
|
unsigned char mask = 0x80 >> ((_first_frame_no - base_frame_no) % 4) * 2;
|
||||||
|
|
||||||
|
if(!((bitmap[bitmap_index] & mask) == 0 && (bitmap[bitmap_index] & (mask >> 1)) != 0))
|
||||||
|
{
|
||||||
|
if((bitmap[bitmap_index] & mask) != 0 && (bitmap[bitmap_index] & (mask >> 1)) != 0)
|
||||||
|
{
|
||||||
|
Console::puts("Error, Frame being released is not being used\n");
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
Console::puts("Error, Frame being released is not head of sequence\n");
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
bitmap[bitmap_index] ^= mask;
|
||||||
|
nFreeFrames++;
|
||||||
|
|
||||||
|
if(mask != 0x02)
|
||||||
|
{
|
||||||
|
mask = mask >> 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = 0x80;
|
||||||
|
bitmap_index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(bitmap[bitmap_index] & mask == 0 && (bitmap[bitmap_index] & (mask >> 1)) == 0)
|
||||||
|
{
|
||||||
|
bitmap[bitmap_index] ^= mask;
|
||||||
|
bitmap[bitmap_index] ^= (mask >> 1);
|
||||||
|
if(mask != 0x02)
|
||||||
|
{
|
||||||
|
mask = mask >> 2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mask = 0x80;
|
||||||
|
bitmap_index++;
|
||||||
|
}
|
||||||
|
nFreeFrames++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long ContFramePool::needed_info_frames(unsigned long _n_frames)
|
||||||
|
{
|
||||||
|
return (_n_frames / (FRAME_SIZE * 4)) + (_n_frames % (FRAME_SIZE * 4) > 0 ? 1 : 0);
|
||||||
|
}
|
132
MP3/MP3_Sources/temph
Executable file
132
MP3/MP3_Sources/temph
Executable file
|
@ -0,0 +1,132 @@
|
||||||
|
/*
|
||||||
|
File: cont_frame_pool.H
|
||||||
|
|
||||||
|
Author: R. Bettati
|
||||||
|
Department of Computer Science
|
||||||
|
Texas A&M University
|
||||||
|
Date : 17/02/04
|
||||||
|
|
||||||
|
Description: Management of the CONTIGUOUS Free-Frame Pool.
|
||||||
|
|
||||||
|
As opposed to a non-contiguous free-frame pool, here we can allocate
|
||||||
|
a sequence of CONTIGUOUS frames.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _CONT_FRAME_POOL_H_ // include file only once
|
||||||
|
#define _CONT_FRAME_POOL_H_
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* DEFINES */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* -- (none) -- */
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* INCLUDES */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
#include "machine.H"
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* DATA STRUCTURES */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* -- (none) -- */
|
||||||
|
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
/* C o n t F r a m e P o o l */
|
||||||
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
class ContFramePool {
|
||||||
|
|
||||||
|
private:
|
||||||
|
/* -- DEFINE YOUR CONT FRAME POOL DATA STRUCTURE(s) HERE. */
|
||||||
|
|
||||||
|
unsigned char * bitmap; // Remember the bitmap here needs 2 bits per frame
|
||||||
|
unsigned int nFreeFrames; //
|
||||||
|
unsigned long base_frame_no; // Where does the frame pool start in phys mem?
|
||||||
|
unsigned long nframes; // Size of the frame pool
|
||||||
|
unsigned long info_frame_no; // Where do we store the management information?
|
||||||
|
unsigned long n_info_frames; // Number of frames needed to store management info
|
||||||
|
static ContFramePool* pools; // List of frame pools, managed by the class
|
||||||
|
static unsigned int nPools; // Number of pools being managed
|
||||||
|
|
||||||
|
void mark_inaccessible(unsigned long _frame_no); // Should be a frame marked as
|
||||||
|
// a head, otherwise fails
|
||||||
|
void release_frames_here(unsigned long _frame_no); // non-static member function
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
// The frame size is the same as the page size, duh...
|
||||||
|
static const unsigned int FRAME_SIZE = Machine::PAGE_SIZE;
|
||||||
|
|
||||||
|
ContFramePool(unsigned long _base_frame_no,
|
||||||
|
unsigned long _n_frames,
|
||||||
|
unsigned long _info_frame_no,
|
||||||
|
unsigned long _n_info_frames);
|
||||||
|
/*
|
||||||
|
Initializes the data structures needed for the management of this
|
||||||
|
frame pool.
|
||||||
|
_base_frame_no: Number of first frame managed by this frame pool.
|
||||||
|
_n_frames: Size, in frames, of this frame pool.
|
||||||
|
EXAMPLE: If _base_frame_no is 16 and _n_frames is 4, this frame pool manages
|
||||||
|
physical frames numbered 16, 17, 18 and 19.
|
||||||
|
_info_frame_no: Number of the first frame that should be used to store the
|
||||||
|
management information for the frame pool.
|
||||||
|
NOTE: If _info_frame_no is 0, the frame pool is free to
|
||||||
|
choose any frames from the pool to store management information.
|
||||||
|
_n_info_frames: If _info_frame_no is 0, this argument specifies the
|
||||||
|
number of consecutive frames needed to store the management information
|
||||||
|
for the frame pool.
|
||||||
|
EXAMPLE: If _info_frame_no is 699 and _n_info_frames is 3,
|
||||||
|
then Frames 699, 700, and 701 are used to store the management information
|
||||||
|
for the frame pool.
|
||||||
|
NOTE: This function must be called before the paging system
|
||||||
|
is initialized.
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned long get_frames(unsigned int _n_frames);
|
||||||
|
/*
|
||||||
|
Allocates a number of contiguous frames from the frame pool.
|
||||||
|
_n_frames: Size of contiguous physical memory to allocate,
|
||||||
|
in number of frames.
|
||||||
|
If successful, returns the frame number of the first frame.
|
||||||
|
If fails, returns 0.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void mark_inaccessible(unsigned long _base_frame_no,
|
||||||
|
unsigned long _n_frames);
|
||||||
|
/*
|
||||||
|
Marks a contiguous area of physical memory, i.e., a contiguous
|
||||||
|
sequence of frames, as inaccessible.
|
||||||
|
_base_frame_no: Number of first frame to mark as inaccessible.
|
||||||
|
_n_frames: Number of contiguous frames to mark as inaccessible.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static void release_frames(unsigned long _frame_no);
|
||||||
|
/*
|
||||||
|
Releases a previously allocated contiguous sequence of frames
|
||||||
|
back to its frame pool.
|
||||||
|
The frame sequence is identified by the number of the first frame.
|
||||||
|
NOTE: This function is static because there may be more than one frame pool
|
||||||
|
defined in the system, and it is unclear which one this frame belongs to.
|
||||||
|
This function must first identify the correct frame pool and then call the frame
|
||||||
|
pool's release_frame function.
|
||||||
|
*/
|
||||||
|
|
||||||
|
static unsigned long needed_info_frames(unsigned long _n_frames);
|
||||||
|
/*
|
||||||
|
Returns the number of frames needed to manage a frame pool of size _n_frames.
|
||||||
|
The number returned here depends on the implementation of the frame pool and
|
||||||
|
on the frame size.
|
||||||
|
EXAMPLE: For FRAME_SIZE = 4096 and a bitmap with a single bit per frame
|
||||||
|
(not appropriate for contiguous allocation) one would need one frame to manage a
|
||||||
|
frame pool with up to 8 * 4096 = 32k frames = 128MB of memory!
|
||||||
|
This function would therefore return the following value:
|
||||||
|
_n_frames / 32k + (_n_frames % 32k > 0 ? 1 : 0) (always round up!)
|
||||||
|
Other implementations need a different number of info frames.
|
||||||
|
The exact number is computed in this function..
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
#endif
|
|
@ -1,162 +1,182 @@
|
||||||
/*
|
|
||||||
File: ContFramePool.C
|
|
||||||
|
|
||||||
Author:
|
|
||||||
Date :
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/*
|
|
||||||
POSSIBLE IMPLEMENTATION
|
|
||||||
-----------------------
|
|
||||||
|
|
||||||
The class SimpleFramePool in file "simple_frame_pool.H/C" describes an
|
|
||||||
incomplete vanilla implementation of a frame pool that allocates
|
|
||||||
*single* frames at a time. Because it does allocate one frame at a time,
|
|
||||||
it does not guarantee that a sequence of frames is allocated contiguously.
|
|
||||||
This can cause problems.
|
|
||||||
|
|
||||||
The class ContFramePool has the ability to allocate either single frames,
|
|
||||||
or sequences of contiguous frames. This affects how we manage the
|
|
||||||
free frames. In SimpleFramePool it is sufficient to maintain the free
|
|
||||||
frames.
|
|
||||||
In ContFramePool we need to maintain free *sequences* of frames.
|
|
||||||
|
|
||||||
This can be done in many ways, ranging from extensions to bitmaps to
|
|
||||||
free-lists of frames etc.
|
|
||||||
|
|
||||||
IMPLEMENTATION:
|
|
||||||
|
|
||||||
One simple way to manage sequences of free frames is to add a minor
|
|
||||||
extension to the bitmap idea of SimpleFramePool: Instead of maintaining
|
|
||||||
whether a frame is FREE or ALLOCATED, which requires one bit per frame,
|
|
||||||
we maintain whether the frame is FREE, or ALLOCATED, or HEAD-OF-SEQUENCE.
|
|
||||||
The meaning of FREE is the same as in SimpleFramePool.
|
|
||||||
If a frame is marked as HEAD-OF-SEQUENCE, this means that it is allocated
|
|
||||||
and that it is the first such frame in a sequence of frames. Allocated
|
|
||||||
frames that are not first in a sequence are marked as ALLOCATED.
|
|
||||||
|
|
||||||
NOTE: If we use this scheme to allocate only single frames, then all
|
|
||||||
frames are marked as either FREE or HEAD-OF-SEQUENCE.
|
|
||||||
|
|
||||||
NOTE: In SimpleFramePool we needed only one bit to store the state of
|
|
||||||
each frame. Now we need two bits. In a first implementation you can choose
|
|
||||||
to use one char per frame. This will allow you to check for a given status
|
|
||||||
without having to do bit manipulations. Once you get this to work,
|
|
||||||
revisit the implementation and change it to using two bits. You will get
|
|
||||||
an efficiency penalty if you use one char (i.e., 8 bits) per frame when
|
|
||||||
two bits do the trick.
|
|
||||||
|
|
||||||
DETAILED IMPLEMENTATION:
|
|
||||||
|
|
||||||
How can we use the HEAD-OF-SEQUENCE state to implement a contiguous
|
|
||||||
allocator? Let's look a the individual functions:
|
|
||||||
|
|
||||||
Constructor: Initialize all frames to FREE, except for any frames that you
|
|
||||||
need for the management of the frame pool, if any.
|
|
||||||
|
|
||||||
get_frames(_n_frames): Traverse the "bitmap" of states and look for a
|
|
||||||
sequence of at least _n_frames entries that are FREE. If you find one,
|
|
||||||
mark the first one as HEAD-OF-SEQUENCE and the remaining _n_frames-1 as
|
|
||||||
ALLOCATED.
|
|
||||||
|
|
||||||
release_frames(_first_frame_no): Check whether the first frame is marked as
|
|
||||||
HEAD-OF-SEQUENCE. If not, something went wrong. If it is, mark it as FREE.
|
|
||||||
Traverse the subsequent frames until you reach one that is FREE or
|
|
||||||
HEAD-OF-SEQUENCE. Until then, mark the frames that you traverse as FREE.
|
|
||||||
|
|
||||||
mark_inaccessible(_base_frame_no, _n_frames): This is no different than
|
|
||||||
get_frames, without having to search for the free sequence. You tell the
|
|
||||||
allocator exactly which frame to mark as HEAD-OF-SEQUENCE and how many
|
|
||||||
frames after that to mark as ALLOCATED.
|
|
||||||
|
|
||||||
needed_info_frames(_n_frames): This depends on how many bits you need
|
|
||||||
to store the state of each frame. If you use a char to represent the state
|
|
||||||
of a frame, then you need one info frame for each FRAME_SIZE frames.
|
|
||||||
|
|
||||||
A WORD ABOUT RELEASE_FRAMES():
|
|
||||||
|
|
||||||
When we releae a frame, we only know its frame number. At the time
|
|
||||||
of a frame's release, we don't know necessarily which pool it came
|
|
||||||
from. Therefore, the function "release_frame" is static, i.e.,
|
|
||||||
not associated with a particular frame pool.
|
|
||||||
|
|
||||||
This problem is related to the lack of a so-called "placement delete" in
|
|
||||||
C++. For a discussion of this see Stroustrup's FAQ:
|
|
||||||
http://www.stroustrup.com/bs_faq2.html#placement-delete
|
|
||||||
|
|
||||||
*/
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/* DEFINES */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* -- (none) -- */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/* INCLUDES */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
#include "cont_frame_pool.H"
|
#include "cont_frame_pool.H"
|
||||||
#include "console.H"
|
#include "console.H"
|
||||||
#include "utils.H"
|
#include "utils.H"
|
||||||
#include "assert.H"
|
#include "assert.H"
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
ContFramePool* ContFramePool::pools = (ContFramePool *) FRAME_SIZE;
|
||||||
/* DATA STRUCTURES */
|
unsigned int ContFramePool::nPools = 0;
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* -- (none) -- */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/* CONSTANTS */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* -- (none) -- */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/* FORWARDS */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
/* -- (none) -- */
|
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
/* METHODS FOR CLASS C o n t F r a m e P o o l */
|
|
||||||
/*--------------------------------------------------------------------------*/
|
|
||||||
|
|
||||||
ContFramePool::ContFramePool(unsigned long _base_frame_no,
|
ContFramePool::ContFramePool(unsigned long _base_frame_no,
|
||||||
unsigned long _nframes,
|
unsigned long _nframes,
|
||||||
unsigned long _info_frame_no,
|
unsigned long _info_frame_no,
|
||||||
unsigned long _n_info_frames)
|
unsigned long _n_info_frames)
|
||||||
{
|
{
|
||||||
// TODO: IMPLEMENTATION NEEEDED!
|
// Bitmap must fit in a single frame!
|
||||||
assert(false);
|
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");
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long ContFramePool::get_frames(unsigned int _n_frames)
|
unsigned long ContFramePool::get_frames(unsigned int _n_frames)
|
||||||
{
|
{
|
||||||
// TODO: IMPLEMENTATION NEEEDED!
|
|
||||||
assert(false);
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContFramePool::mark_inaccessible(unsigned long _base_frame_no,
|
void ContFramePool::mark_inaccessible(unsigned long _base_frame_no,
|
||||||
unsigned long _n_frames)
|
unsigned long _nframes)
|
||||||
{
|
{
|
||||||
// TODO: IMPLEMENTATION NEEEDED!
|
// Mark all frames in the range as being used.
|
||||||
assert(false);
|
int i ;
|
||||||
|
for(i = _base_frame_no; i < _base_frame_no + _nframes; i++){
|
||||||
|
mark_inaccessible(i);
|
||||||
|
}
|
||||||
|
nFreeFrames -= _nframes;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContFramePool::release_frames(unsigned long _first_frame_no)
|
void ContFramePool::mark_inaccessible(unsigned long _frame_no)
|
||||||
{
|
{
|
||||||
// TODO: IMPLEMENTATION NEEEDED!
|
// Let's first do a range check.
|
||||||
assert(false);
|
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)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContFramePool::release_frames_here(unsigned long _first_frame_no)
|
||||||
|
{
|
||||||
|
// -- 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++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned long ContFramePool::needed_info_frames(unsigned long _n_frames)
|
unsigned long ContFramePool::needed_info_frames(unsigned long _n_frames)
|
||||||
{
|
{
|
||||||
// TODO: IMPLEMENTATION NEEEDED!
|
return (_n_frames / (FRAME_SIZE * 8)) + ((_n_frames % (FRAME_SIZE * 8)) > 0 ? 1 : 0);
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,18 @@
|
||||||
/*
|
/*
|
||||||
File: cont_frame_pool.H
|
File: simple_frame_pool.H
|
||||||
|
|
||||||
Author: R. Bettati
|
Author: R. Bettati
|
||||||
Department of Computer Science
|
Department of Computer Science
|
||||||
Texas A&M University
|
Texas A&M University
|
||||||
Date : 17/02/04
|
Date : 12/09/03
|
||||||
|
|
||||||
Description: Management of the CONTIGUOUS Free-Frame Pool.
|
Description: Management of the non-contiguous Free-Frame Pool.
|
||||||
|
|
||||||
As opposed to a non-contiguous free-frame pool, here we can allocate
|
|
||||||
a sequence of CONTIGUOUS frames.
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef _CONT_FRAME_POOL_H_ // include file only once
|
#ifndef _FRAME_POOL_H_ // include file only once
|
||||||
#define _CONT_FRAME_POOL_H_
|
#define _FRAME_POOL_H_
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
/* DEFINES */
|
/* DEFINES */
|
||||||
|
@ -35,72 +33,67 @@
|
||||||
/* -- (none) -- */
|
/* -- (none) -- */
|
||||||
|
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
/* C o n t F r a m e P o o l */
|
/* S i m p l e F r a m e P o o l */
|
||||||
/*--------------------------------------------------------------------------*/
|
/*--------------------------------------------------------------------------*/
|
||||||
|
|
||||||
class ContFramePool {
|
class ContFramePool {
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* -- DEFINE YOUR CONT FRAME POOL DATA STRUCTURE(s) HERE. */
|
/* -- DEFINE YOUR FRAME POOL DATA STRUCTURE(s) HERE. */
|
||||||
|
|
||||||
|
|
||||||
|
unsigned char * bitmap; // We implement the simple frame pool with a bitmap
|
||||||
|
unsigned int nFreeFrames; //
|
||||||
|
unsigned long base_frame_no; // Where does the frame pool start in phys mem?
|
||||||
|
unsigned long nframes; // Size of the frame pool
|
||||||
|
unsigned long info_frame_no; // Where do we store the management information?
|
||||||
|
unsigned long n_info_frames;
|
||||||
|
static ContFramePool* pools;
|
||||||
|
static unsigned int nPools;
|
||||||
|
|
||||||
|
void mark_inaccessible(unsigned long _frame_no);
|
||||||
|
void release_frames_here(unsigned long _frame_no);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// The frame size is the same as the page size, duh...
|
|
||||||
static const unsigned int FRAME_SIZE = Machine::PAGE_SIZE;
|
static const unsigned int FRAME_SIZE = Machine::PAGE_SIZE;
|
||||||
|
|
||||||
ContFramePool(unsigned long _base_frame_no,
|
ContFramePool(unsigned long _base_frame_no,
|
||||||
unsigned long _n_frames,
|
unsigned long _nframes,
|
||||||
unsigned long _info_frame_no,
|
unsigned long _info_frame_no,
|
||||||
unsigned long _n_info_frames);
|
unsigned long _n_info_frames);
|
||||||
/*
|
/* Initializes the data structures needed for the management of this
|
||||||
Initializes the data structures needed for the management of this
|
frame pool. This function must be called before the paging system
|
||||||
frame pool.
|
is initialized.
|
||||||
_base_frame_no: Number of first frame managed by this frame pool.
|
_base_frame_no is the frame number at the start of the physical memory
|
||||||
_n_frames: Size, in frames, of this frame pool.
|
region that this frame pool manages.
|
||||||
EXAMPLE: If _base_frame_no is 16 and _nframes is 4, this frame pool manages
|
_nframes is the number of frames in the physical memory region that this
|
||||||
physical frames numbered 16, 17, 18 and 19.
|
frame pool manages.
|
||||||
_info_frame_no: Number of the first frame that should be used to store the
|
e.g. If _base_frame_no is 16 and _nframes is 4, this frame pool manages
|
||||||
management information for the frame pool.
|
physical frames numbered 16, 17, 18 and 19
|
||||||
NOTE: If _info_frame_no is 0, the frame pool is free to
|
_info_frame_no is the frame number (within the directly mapped region) of
|
||||||
choose any frames from the pool to store management information.
|
the frame that should be used to store the management information of the
|
||||||
_n_info_frames: If _info_frame_no is 0, this argument specifies the
|
frame pool. However, if _info_frame_no is 0, the frame pool is free to
|
||||||
number of consecutive frames needed to store the management information
|
choose any frame from the pool to store management information.
|
||||||
for the frame pool.
|
*/
|
||||||
EXAMPLE: If _info_frame_no is 699 and _n_info_frames is 3,
|
|
||||||
then Frames 699, 700, and 701 are used to store the management information
|
|
||||||
for the frame pool.
|
|
||||||
NOTE: This function must be called before the paging system
|
|
||||||
is initialized.
|
|
||||||
*/
|
|
||||||
|
|
||||||
unsigned long get_frames(unsigned int _n_frames);
|
unsigned long get_frames(unsigned int _n_frames);
|
||||||
/*
|
/* Allocates a frame from the frame pool. If successful, returns the frame
|
||||||
Allocates a number of contiguous frames from the frame pool.
|
* number of the frame. If fails, returns 0. */
|
||||||
_n_frames: Size of contiguous physical memory to allocate,
|
|
||||||
in number of frames.
|
|
||||||
If successful, returns the frame number of the first frame.
|
|
||||||
If fails, returns 0.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void mark_inaccessible(unsigned long _base_frame_no,
|
void mark_inaccessible(unsigned long _base_frame_no,
|
||||||
unsigned long _n_frames);
|
unsigned long _nframes);
|
||||||
/*
|
/* Mark the area of physical memory as inaccessible. The arguments have the
|
||||||
Marks a contiguous area of physical memory, i.e., a contiguous
|
* same semanticas as in the constructor.
|
||||||
sequence of frames, as inaccessible.
|
*/
|
||||||
_base_frame_no: Number of first frame to mark as inaccessible.
|
|
||||||
_n_frames: Number of contiguous frames to mark as inaccessible.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static void release_frames(unsigned long _first_frame_no);
|
static void release_frames(unsigned long _frame_no);
|
||||||
/*
|
/* Releases frame back to the given frame pool.
|
||||||
Releases a previously allocated contiguous sequence of frames
|
The frame is identified by the frame number.
|
||||||
back to its frame pool.
|
NOTE: This function is static because there may be more than one frame pool
|
||||||
The frame sequence is identified by the number of the first frame.
|
defined in the system, and it is unclear which one this frame belongs to.
|
||||||
NOTE: This function is static because there may be more than one frame pool
|
This function must first identify the correct frame pool and then call the frame
|
||||||
defined in the system, and it is unclear which one this frame belongs to.
|
pool's release_frame function. */
|
||||||
This function must first identify the correct frame pool and then call the frame
|
|
||||||
pool's release_frame function.
|
|
||||||
*/
|
|
||||||
|
|
||||||
static unsigned long needed_info_frames(unsigned long _n_frames);
|
static unsigned long needed_info_frames(unsigned long _n_frames);
|
||||||
/*
|
/*
|
||||||
|
@ -111,9 +104,10 @@ public:
|
||||||
(not appropriate for contiguous allocation) one would need one frame to manage a
|
(not appropriate for contiguous allocation) one would need one frame to manage a
|
||||||
frame pool with up to 8 * 4096 = 32k frames = 128MB of memory!
|
frame pool with up to 8 * 4096 = 32k frames = 128MB of memory!
|
||||||
This function would therefore return the following value:
|
This function would therefore return the following value:
|
||||||
_n_frames / 32k + (_n_frames % 32k > 0 ? 1 : 0) (always round up!)
|
_n_frames / 32k + (_n_frames % 32k > 0 ? 1 : 0) (always round up!)
|
||||||
Other implementations need a different number of info frames.
|
Other implementations need a different number of info frames.
|
||||||
The exact number is computed in this function..
|
The exact number is computed in this function.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
Reference in a new issue