Final Submission of MP2.

This commit is contained in:
Shadow8t4 2017-06-19 21:37:54 -05:00
parent 7a7e8c9d95
commit 1b81f28bb3
9 changed files with 536 additions and 235 deletions

Binary file not shown.

View file

@ -1,235 +0,0 @@
00000000000i[ ] Bochs x86 Emulator 2.4.6
00000000000i[ ] Build from CVS snapshot, on February 22, 2011
00000000000i[ ] Compiled at Nov 11 2011, 09:31:18
00000000000i[ ] System configuration
00000000000i[ ] processors: 1 (cores=1, HT threads=1)
00000000000i[ ] A20 line support: yes
00000000000i[ ] CPU configuration
00000000000i[ ] level: 6
00000000000i[ ] SMP support: no
00000000000i[ ] APIC support: yes
00000000000i[ ] FPU support: yes
00000000000i[ ] MMX support: yes
00000000000i[ ] 3dnow! support: no
00000000000i[ ] SEP support: yes
00000000000i[ ] SSE support: sse2
00000000000i[ ] XSAVE support: no
00000000000i[ ] AES support: no
00000000000i[ ] MOVBE support: no
00000000000i[ ] x86-64 support: yes
00000000000i[ ] 1G paging support: no
00000000000i[ ] VMX support: no
00000000000i[ ] Optimization configuration
00000000000i[ ] RepeatSpeedups support: yes
00000000000i[ ] Trace cache support: yes
00000000000i[ ] Fast function calls: yes
00000000000i[ ] Devices configuration
00000000000i[ ] ACPI support: yes
00000000000i[ ] NE2000 support: yes
00000000000i[ ] PCI support: yes, enabled=yes
00000000000i[ ] SB16 support: yes
00000000000i[ ] USB support: yes
00000000000i[ ] VGA extension support: vbe
00000000000i[MEM0 ] allocated memory at 0x7f048b2b5010. after alignment, vector=0x7f048b2b6000
00000000000i[MEM0 ] 32.00MB
00000000000i[MEM0 ] mem block size = 0x00100000, blocks=32
00000000000i[MEM0 ] rom at 0xfffe0000/131072 ('BIOS-bochs-latest')
00000000000i[MEM0 ] rom at 0xc0000/38400 ('VGABIOS-lgpl-latest')
00000000000i[VTIME] using 'realtime pit' synchronization method
00000000000i[ ] lt_dlhandle is 0x2bea560
00000000000i[PLGIN] loaded plugin libbx_cmos.so
00000000000i[ ] lt_dlhandle is 0x2beaf80
00000000000i[PLGIN] loaded plugin libbx_dma.so
00000000000i[ ] lt_dlhandle is 0x2beb9e0
00000000000i[PLGIN] loaded plugin libbx_pic.so
00000000000i[ ] lt_dlhandle is 0x2bec220
00000000000i[PLGIN] loaded plugin libbx_pit.so
00000000000i[ ] lt_dlhandle is 0x2becb90
00000000000i[PLGIN] loaded plugin libbx_vga.so
00000000000i[ ] lt_dlhandle is 0x2bed2c0
00000000000i[PLGIN] loaded plugin libbx_hdimage.so
00000000000i[ ] lt_dlhandle is 0x2bedb80
00000000000i[PLGIN] loaded plugin libbx_floppy.so
00000000000i[ ] lt_dlhandle is 0x2bee770
00000000000i[PLGIN] loaded plugin libbx_soundmod.so
00000000000i[ ] lt_dlhandle is 0x2befdc0
00000000000i[PLGIN] loaded plugin libbx_pci.so
00000000000i[ ] lt_dlhandle is 0x2bf09f0
00000000000i[PLGIN] loaded plugin libbx_pci2isa.so
00000000000i[ ] lt_dlhandle is 0x2bf12d0
00000000000i[PLGIN] loaded plugin libbx_usb_common.so
00000000000i[ ] lt_dlhandle is 0x2bf1b30
00000000000i[PLGIN] loaded plugin libbx_unmapped.so
00000000000i[ ] lt_dlhandle is 0x2bf23a0
00000000000i[PLGIN] loaded plugin libbx_biosdev.so
00000000000i[ ] lt_dlhandle is 0x2bf2cd0
00000000000i[PLGIN] loaded plugin libbx_speaker.so
00000000000i[ ] lt_dlhandle is 0x2bf3500
00000000000i[PLGIN] loaded plugin libbx_extfpuirq.so
00000000000i[ ] lt_dlhandle is 0x2bf3d70
00000000000i[PLGIN] loaded plugin libbx_gameport.so
00000000000i[ ] lt_dlhandle is 0x2bf46e0
00000000000i[PLGIN] loaded plugin libbx_pci_ide.so
00000000000i[ ] lt_dlhandle is 0x2bf50b0
00000000000i[PLGIN] loaded plugin libbx_acpi.so
00000000000i[ ] lt_dlhandle is 0x2bf59f0
00000000000i[PLGIN] loaded plugin libbx_ioapic.so
00000000000i[ ] lt_dlhandle is 0x2bf63a0
00000000000i[PLGIN] loaded plugin libbx_keyboard.so
00000000000i[ ] lt_dlhandle is 0x2bf6ba0
00000000000i[PLGIN] loaded plugin libbx_harddrv.so
00000000000i[ ] lt_dlhandle is 0x2c08c70
00000000000i[PLGIN] loaded plugin libbx_serial.so
00000000000i[ ] lt_dlhandle is 0x2c09ae0
00000000000i[PLGIN] loaded plugin libbx_parallel.so
00000000000i[CMOS ] Using specified time for initial clock
00000000000i[CMOS ] Setting initial clock to: Fri Dec 31 17:00:00 1999 (time0=946681200)
00000000000i[DMA ] channel 4 used by cascade
00000000000i[DMA ] channel 2 used by Floppy Drive
00000000000i[FDD ] fd0: 'dev_kernel_grub.img' ro=0, h=2,t=80,spt=18
00000000000i[PCI ] 440FX Host bridge present at device 0, function 0
00000000000i[PCI ] PIIX3 PCI-to-ISA bridge present at device 1, function 0
00000000000i[VGA ] interval=50000
00000000000i[MEM0 ] Register memory access handlers: 0x00000000000a0000 - 0x00000000000bffff
00000000000i[XGUI ] test_alloc_colors: 16 colors available out of 16 colors tried
00000000000i[XGUI ] font 8 wide x 16 high, display depth = 24
00000000000i[MEM0 ] Register memory access handlers: 0x00000000e0000000 - 0x00000000e0ffffff
00000000000i[VGA ] VBE Bochs Display Extension Enabled
00000000000i[PLGIN] init_dev of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'speaker' plugin device by virtual method
00000000000i[SPEAK] Failed to open /dev/console: Resource temporarily unavailable
00000000000i[SPEAK] Deactivating beep on console
00000000000i[PLGIN] init_dev of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'gameport' plugin device by virtual method
00000000000i[PLGIN] init_dev of 'pci_ide' plugin device by virtual method
00000000000i[PCI ] PIIX3 PCI IDE controller present at device 1, function 1
00000000000i[PLGIN] init_dev of 'acpi' plugin device by virtual method
00000000000i[PCI ] ACPI Controller present at device 1, function 3
00000000000i[PLGIN] init_dev of 'ioapic' plugin device by virtual method
00000000000i[IOAP ] initializing I/O APIC
00000000000i[MEM0 ] Register memory access handlers: 0x00000000fec00000 - 0x00000000fec00fff
00000000000i[PLGIN] init_dev of 'keyboard' plugin device by virtual method
00000000000i[KBD ] will paste characters every 1000 keyboard ticks
00000000000i[PLGIN] init_dev of 'harddrv' plugin device by virtual method
00000000000i[HD ] Using boot sequence floppy, none, none
00000000000i[HD ] Floppy boot signature check is enabled
00000000000i[PLGIN] init_dev of 'serial' plugin device by virtual method
00000000000i[SER ] com1 at 0x03f8 irq 4
00000000000i[PLGIN] init_dev of 'parallel' plugin device by virtual method
00000000000i[PAR ] parallel port 1 at 0x0378 irq 7
00000000000i[PLGIN] register state of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] register state of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] register state of 'speaker' plugin device by virtual method
00000000000i[PLGIN] register state of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] register state of 'gameport' plugin device by virtual method
00000000000i[PLGIN] register state of 'pci_ide' plugin device by virtual method
00000000000i[PLGIN] register state of 'acpi' plugin device by virtual method
00000000000i[PLGIN] register state of 'ioapic' plugin device by virtual method
00000000000i[PLGIN] register state of 'keyboard' plugin device by virtual method
00000000000i[PLGIN] register state of 'harddrv' plugin device by virtual method
00000000000i[PLGIN] register state of 'serial' plugin device by virtual method
00000000000i[PLGIN] register state of 'parallel' plugin device by virtual method
00000000000i[SYS ] bx_pc_system_c::Reset(HARDWARE) called
00000000000i[CPU0 ] cpu hardware reset
00000000000i[APIC0] allocate APIC id=0 (MMIO enabled) to 0x00000000fee00000
00000000000i[CPU0 ] CPUID[0x00000000]: 00000003 756e6547 6c65746e 49656e69
00000000000i[CPU0 ] CPUID[0x00000001]: 00000f23 00000800 00002000 07cbfbff
00000000000i[CPU0 ] CPUID[0x00000002]: 00410601 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000003]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000004]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x00000007]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000000]: 80000008 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000001]: 00000000 00000000 00000001 2a100800
00000000000i[CPU0 ] CPUID[0x80000002]: 20202020 20202020 20202020 6e492020
00000000000i[CPU0 ] CPUID[0x80000003]: 286c6574 50202952 69746e65 52286d75
00000000000i[CPU0 ] CPUID[0x80000004]: 20342029 20555043 20202020 00202020
00000000000i[CPU0 ] CPUID[0x80000006]: 00000000 42004200 02008140 00000000
00000000000i[CPU0 ] CPUID[0x80000007]: 00000000 00000000 00000000 00000000
00000000000i[CPU0 ] CPUID[0x80000008]: 00003028 00000000 00000000 00000000
00000000000i[PLGIN] reset of 'unmapped' plugin device by virtual method
00000000000i[PLGIN] reset of 'biosdev' plugin device by virtual method
00000000000i[PLGIN] reset of 'speaker' plugin device by virtual method
00000000000i[PLGIN] reset of 'extfpuirq' plugin device by virtual method
00000000000i[PLGIN] reset of 'gameport' plugin device by virtual method
00000000000i[PLGIN] reset of 'pci_ide' plugin device by virtual method
00000000000i[PLGIN] reset of 'acpi' plugin device by virtual method
00000000000i[PLGIN] reset of 'ioapic' plugin device by virtual method
00000000000i[PLGIN] reset of 'keyboard' plugin device by virtual method
00000000000i[PLGIN] reset of 'harddrv' plugin device by virtual method
00000000000i[PLGIN] reset of 'serial' plugin device by virtual method
00000000000i[PLGIN] reset of 'parallel' plugin device by virtual method
00000000000i[XGUI ] [x] Mouse off
00000003302i[BIOS ] $Revision: 1.209 $ $Date: 2008/06/02 20:08:10 $
00000318057i[KBD ] reset-disable command received
00000438667i[VBIOS] VGABios $Id: vgabios.c,v 1.67 2008/01/27 09:44:12 vruppert Exp $
00000438738i[VGA ] VBE known Display Interface b0c0
00000438770i[VGA ] VBE known Display Interface b0c4
00000441695i[VBIOS] VBE Bios $Id: vbe.c,v 1.60 2008/03/02 07:47:21 vruppert Exp $
00000600000i[XGUI ] charmap update. Font Height is 16
00000764696i[BIOS ] Starting rombios32
00000765523i[BIOS ] ram_size=0x02000000
00001019718i[BIOS ] Found 1 cpu(s)
00001036019i[BIOS ] bios_table_addr: 0x000fb778 end=0x000fcc00
00001036086i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00001494893i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00001954380i[P2I ] PCI IRQ routing: PIRQA# set to 0x0b
00001954427i[P2I ] PCI IRQ routing: PIRQB# set to 0x09
00001954474i[P2I ] PCI IRQ routing: PIRQC# set to 0x0b
00001954521i[P2I ] PCI IRQ routing: PIRQD# set to 0x09
00001954537i[P2I ] write: ELCR2 = 0x0a
00001955474i[BIOS ] PIIX3 init: elcr=00 0a
00001975729i[BIOS ] PCI: bus=0 devfn=0x00: vendor_id=0x8086 device_id=0x1237
00001978966i[BIOS ] PCI: bus=0 devfn=0x08: vendor_id=0x8086 device_id=0x7000
00001981699i[BIOS ] PCI: bus=0 devfn=0x09: vendor_id=0x8086 device_id=0x7010
00001982160i[PIDE ] new BM-DMA address: 0xc000
00001983043i[BIOS ] region 4: 0x0000c000
00001985619i[BIOS ] PCI: bus=0 devfn=0x0b: vendor_id=0x8086 device_id=0x7113
00001986119i[ACPI ] new irq line = 11
00001986156i[ACPI ] new PM base address: 0xb000
00001986218i[ACPI ] new SM base address: 0xb100
00001986686i[CPU0 ] Enter to System Management Mode
00001986696i[CPU0 ] RSM: Resuming from System Management Mode
00001986730i[PCI ] setting SMRAM control register to 0x4a
00001987012i[PCI ] setting SMRAM control register to 0x0a
00002010293i[BIOS ] MP table addr=0x000fb850 MPC table addr=0x000fb780 size=0xd0
00002012496i[BIOS ] SMBIOS table addr=0x000fb860
00002015540i[BIOS ] ACPI tables: RSDP addr=0x000fb970 ACPI DATA addr=0x01ff0000 size=0x9d8
00002035073i[PCI ] 440FX PMC write to PAM register 59 (TLB Flush)
00002036085i[BIOS ] bios_table_cur_addr: 0x000fb994
00500104718i[BIOS ] Booting from 0000:7c00
00510000000i[XGUI ] charmap update. Font Height is 16
00586200000i[XGUI ] charmap update. Font Height is 16
00594600000i[XGUI ] charmap update. Font Height is 16
00905192000p[XGUI ] >>PANIC<< POWER button turned off.
00905192000i[CPU0 ] CPU is in protected mode (active)
00905192000i[CPU0 ] CS.d_b = 32 bit
00905192000i[CPU0 ] SS.d_b = 32 bit
00905192000i[CPU0 ] EFER = 0x00000000
00905192000i[CPU0 ] | RAX=0000000000000000 RBX=0000000000026260
00905192000i[CPU0 ] | RCX=0000000000000f00 RDX=00000000000003d4
00905192000i[CPU0 ] | RSP=0000000000104f90 RBP=0000000000104ff8
00905192000i[CPU0 ] | RSI=00000000000263d3 RDI=00000000000263df
00905192000i[CPU0 ] | R8=0000000000000000 R9=0000000000000000
00905192000i[CPU0 ] | R10=0000000000000000 R11=0000000000000000
00905192000i[CPU0 ] | R12=0000000000000000 R13=0000000000000000
00905192000i[CPU0 ] | R14=0000000000000000 R15=0000000000000000
00905192000i[CPU0 ] | IOPL=0 id vip vif ac vm rf nt of df if tf sf ZF af PF cf
00905192000i[CPU0 ] | SEG selector base limit G D
00905192000i[CPU0 ] | SEG sltr(index|ti|rpl) base limit G D
00905192000i[CPU0 ] | CS:0008( 0001| 0| 0) 00000000 ffffffff 1 1
00905192000i[CPU0 ] | DS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00905192000i[CPU0 ] | SS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00905192000i[CPU0 ] | ES:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00905192000i[CPU0 ] | FS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00905192000i[CPU0 ] | GS:0010( 0002| 0| 0) 00000000 ffffffff 1 1
00905192000i[CPU0 ] | MSR_FS_BASE:0000000000000000
00905192000i[CPU0 ] | MSR_GS_BASE:0000000000000000
00905192000i[CPU0 ] | RIP=0000000000100431 (0000000000100431)
00905192000i[CPU0 ] | CR0=0x60000011 CR2=0x0000000000000000
00905192000i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00905192000i[CPU0 ] 0x0000000000100431>> jmp .-2 (0x00100431) : EBFE
00905192000i[CMOS ] Last time is 946681426 (Fri Dec 31 17:03:46 1999)
00905192000i[XGUI ] Exit
00905192000i[ ] restoring default signal behavior
00905192000i[CTRL ] quit_sim called with exit code 1

Binary file not shown.

BIN
MP2/design.odt Normal file

Binary file not shown.

BIN
MP2/design.pdf Normal file

Binary file not shown.

BIN
MP2/mp2.zip Normal file

Binary file not shown.

404
MP2/mp2/cont_frame_pool.C Normal file
View 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
MP2/mp2/cont_frame_pool.H Executable file
View 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

BIN
MP2/mp2/design.pdf Normal file

Binary file not shown.