home *** CD-ROM | disk | FTP | other *** search
- // This may look like C code, but it is really -*- C++ -*-
- /*
- ************************************************************************
- *
- * UNT Virtual Machine
- *
- * Real, Virtual and Swap memory manager
- * Data structures
- *
- * The concept of the working set is now supported. See mem_manager.cc
- * for details.
- *
- ************************************************************************
- */
-
- #ifndef _mem_manager_h
- #define _mem_manager_h 1
- #pragma interface
-
- #include "hardware.h"
- #include "sysqueues.h"
-
- /*
- *------------------------------------------------------------------------
- * Managing pages of physical memory
- */
-
- typedef unsigned short PFN; // Page Frame No
- const PFN NIL_pfn = (unsigned)(-1);
-
- class PageFrameTable;
-
- // Note, QueueLink.id is the page frame no
- class PageFrame : public QueueLink
- {
- friend class PageFrameTable;
-
- public:
- PageFrame(void);
- ~PageFrame(void) {}
- };
-
- class PageFrameTable
- {
- const int no_page_frames;
- PageFrame * page_frames;
-
- BasicQueue freePFs;
-
- public:
- const int sys_page_frame = 0; // Permanently allocated to OS
-
- PageFrameTable(const int no_phys_pages);
- ~PageFrameTable(void) {}
-
- // Get a Page Frame given its no
- PageFrame& operator [] (const PFN pfn) const;
- PFN allocate(void); // Allocate a new physical page, return NIL
- // if no physical page is available
- void dispose(const PFN pfn); // Dispose of a given page
- void dump_status(void) const; // Print info about physical memory allocation
- };
-
- /*
- *------------------------------------------------------------------------
- * Managing pages of virtual memory
- * Virtual space of the system is essentially the collection of drum sectors
- * (pages). Therefore, virtual page number is exactly the drum sector
- * number. A virtual page may be free or allocated (to one or several
- * processes if it is a code page shared between the processes), may exist
- * only on the drum or loaded to the physical memory into some page frame.
- * If the page is shared between several processes, it might be mapped
- * (actually referenced or accessed) by all or only several of them.
- * Virtual pages of the program images that were inserted on the drum
- * by the linker (task builder) are declared private, in that they are
- * never put into the free list (even if the process that uses them is
- * over), i.e. the contents of the private page is preserved. It implies
- * the same drum file can be used in different runs of VM UNT.
- * The mapped page may be locked, it means the page remains mapped until
- * it is unlocked explicitly; this feature is used primarily to make sure
- * that the pages needed for I/O would would not suddenly get swapped
- * in the middle of I/O. Locking is implemented as increasing the reference
- * counter and setting the 'locked_page' bit. Note that the locked page
- * may be locked again (without any effect, though).
- *
- */
-
- typedef unsigned short VPN; // (Virtual) Page No
- const VPN NIL_vpn = (unsigned)(-1);
-
- class VirtualPageTable;
-
- // Note, QueueLink.id is the VPN
- class VirtualPage : public QueueLink
- {
- friend class VirtualPageTable;
-
- short own_count; // How many processes own this page
- short ref_count; // How many processes are actually
- // using, i.e. accessing this page
- unsigned char
- private_page : 1, // TRUE means the page belongs to
- // the exec image and is not to be
- // overwritten or disposed
- data_page : 1, // 1 - data page, 0 - code page
- locked_page : 1;
-
- public:
- PFN page_frame; // Page frame the page is mapped to
-
- VirtualPage(void);
- ~VirtualPage(void) {}
- int q_data_page(void) const { return data_page; }
- void declare_data_page(void) { data_page = 1; }
- int is_shared(void) const { return own_count > 1; }
- int is_shared_mapped(void) const { return ref_count > 1; }
- int is_mapped(void) const { return ref_count > 0; }
- int is_locked(void) const { return locked_page; }
- };
-
- class VirtualPageTable
- {
- const int no_pages;
- VirtualPage * pages;
- BasicQueue freeVPs;
- PageFrameTable page_frames;
- Memory& physical_memory;
- int no_locked_pages;
-
- public:
-
- VirtualPageTable(Memory& _physical_memory,
- const int no_phys_pages,const int no_virtual_pages);
- ~VirtualPageTable(void) {}
-
- // Get a Virtual Page given its no
- VirtualPage& operator [] (const VPN vpn) const;
- // Allocate a new virtual page, return NIL
- // if no page is available
- VPN allocate(void);
- VirtualPage& allocate(VPN desired_vpn);
- void declare_page_private(VPN vpn);
- void copy(const VPN to, const VPN from);
- void dispose(const VPN vpn); // Dispose of a given page
- void dump_status(void) const; // Print info about virtual memory allocation
- PFN reference(const VPN vpn); // The page is being demanded, reference it
- // The page is to be swapped out, unreference
- // and swap it out if needed
- void unreference(const VPN vpn,const int to_write);
- void lock(const VPN vpn); // Lock the mapped page
- void unlock(const VPN vpn); // Unlock the mapped page
-
- // Reserve the physical page for the system
- // Returns the physical address it starts
- Address reserve_physical_page();
- };
-
- /*
- *------------------------------------------------------------------------
- * Memory manager itself
- */
-
- class MemoryManager;
-
- // OS Memory manangement context of a process
- class MMContext : public MMUContext
- {
- friend class MemoryManager;
- const int process_virtual_space = 32; // in pages
- short no_mapped_pages; // Current size of the working set
- const short working_set_quota = 14; // Max no. of mapped pages allowed
- VPN vm_map[process_virtual_space]; // Process virtual space
- PageTableEntry page_table[process_virtual_space];
- short time_since_last_ref[process_virtual_space]; // for each page
- long no_page_faults;
-
- // Given vm_map, map of the process virtual
- // space, construct the page table
- void build_page_table(const VirtualPageTable& virtual_space);
-
- public:
- MMContext(void);
- virtual ~MMContext(void) {}
-
- void load_MMU(MemoryManagementUnit& mmu); // Load and save the hardware
- void save_MMU(const MemoryManagementUnit& mmu);// (MMU) context
- void dump(void) const; // Dump whatever's in the context
- };
-
- class MemoryManager : public DiagnosticPanel
- {
- Memory& physical_memory;
- VirtualPageTable virtual_space;
-
- short no_programs; // No of programs on the drum.
- const short max_no_programs = 14;
- struct ProgDescr { Address pc; Word mem_map; }
- prog_descriptors[max_no_programs];
-
- // Simple rule to partition the
- // virtual space of the program
- // into the data and code space
- int is_text_segment(const int page_no) const { return page_no <= 15; }
-
- public:
- MemoryManager(Memory& _physical_memory);
- ~MemoryManager(void) {}
-
- int q_no_programs(void); // Read the drum header and tell the
- // number of programs on the drum
-
- void dump_status(void) const; // Tell what's going on with memory
-
- // Load program and return starting PC
- Address load_program(MMContext& context,const unsigned int prog_no);
-
- // Take care of son's virtual space
- // Return FALSE if some problem
- // occurred
- int fork_son(MMContext& son_context,const MMContext& dad_context);
-
- // Load the virtual page from the
- // drum and establish mapping to
- // a physical page
- enum MMAnswer {Ok, PhysMemoryExhausted, LethalFault };
- MMAnswer load_the_page(MMContext& context,
- MMUContext::VirtualMemoryAddr culprit_VA);
-
- // Release the virtual memory
- // occupied by the process
- void dispose(MMContext& context);
-
- // Swap out a victim - forcibly
- // deprive it of the mapped pages
- // Return 0 if no page frame was
- // released (unsuccessful swapping)
- int swap_out(MMContext& context);
-
- // Run the LRU page replacement
- // strategy to find out the least
- // referenced page and push it out
- void replace_LRU_page(MMContext& context);
-
- // Lock the page that contains the
- // specified virtual address. The page
- // should be already mapped
- // Return FALSE if failed
- int lock_loaded_page(MMContext& context,const Address addr);
-
- // Unlock the page that contains the
- // specified virtual address. The page
- // should be already mapped & locked
- void unlock_page(MMContext& context,const Address addr);
-
- // Translate the virtual address to
- // physical one. The page has to be
- // loaded. Returns 0 if fails
- Address translate_va(MMContext& context,const Address addr);
-
- // Reserve the physical page for the
- // system. Returns the physical
- // address where it starts
- Address reserve_physical_page()
- { return virtual_space.reserve_physical_page(); }
- };
-
- #endif
-