⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 memorymanager.cs

📁 C#编写的超小的操作系统,有兴趣的可以下载研究一下,
💻 CS
📖 第 1 页 / 共 3 页
字号:

			/// <summary>
			/// One of two parallel arrays, one of shared owners of this page, one of shared process indexes of this page
			/// </summary>
			public ArrayList pidSharedOwnerList = new ArrayList();

			/// <summary>
			/// One of two parallel arrayz, one of shared owners of this page, one of shared process indexes of this page
			/// </summary>
			public ArrayList pidSharedProcessIndex = new ArrayList();

			/// <summary>
			/// The number this page is in addressable Memory.  Set once and immutable
			/// </summary>
			public readonly uint pageNumber = 0;

			/// <summary>
			/// The address in addressable space this page is responsbile for
			/// </summary>
			public readonly uint addrVirtual = 0;

			/// <summary>
			/// The address in Process space this page is responsible for
			/// </summary>
			public uint addrProcessIndex = 0;

			/// <summary>
			/// The process address that originally allocated this page.  Kept so we can free that page(s) later.
			/// </summary>
			public uint heapAllocationAddr = 0;

			/// <summary>
			/// The process that is currently using this apge
			/// </summary>
			public uint pidOwner = 0;

			/// <summary>
			/// This is only valid when 
			/// pidOwner != 0 and isValid == true
			/// meaning the page is actually mapped and present
			/// </summary>
			public uint addrPhysical = 0; 
 
			/// <summary>
			/// Is the page in memory now?
			/// </summary>
			public bool isValid;		

			/// <summary>
			/// Has the page been changes since it was last swapped in from Disk?
			/// </summary>
			public bool isDirty = false;			
			
			/// <summary>
			/// For statistics: How many times has this page been involved in a pageFault?
			/// </summary>
			public uint pageFaults = 0;				

			/// <summary>
			/// For aging and swapping: How many times has this page's address range been accessed?
			/// </summary>
			public uint accessCount = 0;			

			/// <summary>
			/// For aging and swapping: When was this page last accessed?
			/// </summary>
			public DateTime lastAccessed = DateTime.Now; 

			/// <summary>
			/// Only public constructor for a Memory Page and is only called once 
			/// in the <see cref="MemoryManager"/> constructor
			/// </summary>
			/// <param name="initAddrVirtual">The address in addressable memory this page is responsible for</param>
			/// <param name="isValidFlag">Is this page in memory right now?</param>
			public MemoryPage(uint initAddrVirtual, bool isValidFlag)
			{
				isValid = isValidFlag;
				if (isValid)
					addrPhysical = initAddrVirtual;
				addrVirtual = initAddrVirtual;
				pageNumber = (addrVirtual)/CPU.pageSize;
			}
		}

		/// <summary>
		/// Represents the actual values in memory that a MemoryPage points to.  
		/// MemoryPageValue is serialized to disk, currently as XML, in <see cref="SwapOut"/>.
		/// </summary>
		[Serializable] public class MemoryPageValue
		{
			/// <summary>
			/// The array of bytes holding the value of memory for this page
			/// </summary>
			[XmlArray(ElementName = "byte", Namespace = "http://www.hanselman.com")]
			public byte[] memory = new byte[CPU.pageSize];
			
			/// <summary>
			/// For aging and swapping: How many times has this page's address range been accessed?
			/// </summary>
			public uint accessCount = 0;

			/// <summary>
			/// For aging and swapping: When was this page last accessed?
			/// </summary>
			public DateTime lastAccessed = DateTime.Now;
		}

		/// <summary>
		/// Swaps the specified <see cref="MemoryPage"/> to disk.  Currently implemented as XML for fun.
		/// </summary>
		/// <param name="victim">The <see cref="MemoryPage"/> to be swapped</param>
		public void SwapOut(MemoryPage victim)
		{
			if (victim.isDirty)
			{

				// Generate a filename based on address and page number
				string filename = System.Environment.CurrentDirectory + "/page" + victim.pageNumber + "-" + victim.addrVirtual + ".xml";

//				IFormatter ser = new BinaryFormatter();
//				Stream writer = new FileStream(filename, FileMode.Create);

				XmlSerializer ser = new XmlSerializer(typeof(MemoryPageValue));
				Stream fs = new FileStream(filename, FileMode.Create);
				XmlWriter writer = new XmlTextWriter(fs, new UTF8Encoding());

				MemoryPageValue pageValue = new MemoryPageValue();

				// Copy the bytes from Physical Memory so we don't pageFault in a Fault Hander
				byte[] bytes = new byte[CPU.pageSize];
				for (int i = 0; i < CPU.pageSize; i++)
					bytes[i] = CPU.physicalMemory[victim.addrPhysical+i];

				// Copy details from the MemoryPage to the MemoryPageValue
				pageValue.memory = bytes;
				pageValue.accessCount = victim.accessCount;
				pageValue.lastAccessed = victim.lastAccessed;

				//Console.WriteLine("Swapping out page {0} at physical memory {1}",victim.pageNumber, victim.addrPhysical);
			
				// Write the MemoryPageValue to disk!
				ser.Serialize(writer,pageValue);
						
				//writer.Flush();
				//writer.Close();
				fs.Close();
			}
			victim.isValid = false;
		}

		/// <summary>
		/// Swaps in the specified <see cref="MemoryPage"/> from disk.  Currently implemented as XML for fun.
		/// </summary>
		/// <param name="winner">The <see cref="MemoryPage"/> that is being swapped in</param>
		public void SwapIn(MemoryPage winner)
		{
			// Generate a filename based on address and page number
			string filename = System.Environment.CurrentDirectory + "/page" + winner.pageNumber + "-" + winner.addrVirtual + ".xml";
			if (File.Exists(filename) && winner.isValid == false)
			{
				//BinaryFormatter ser = new BinaryFormatter();
				//Stream reader = new FileStream(filename, FileMode.Open);

				XmlSerializer ser = new XmlSerializer(typeof(MemoryPageValue));
				Stream fs = new FileStream(filename, FileMode.Open);
				XmlReader reader = new XmlTextReader(fs);

				// Load the MemoryPageValue in from Disk!
				MemoryPageValue pageValue = (MemoryPageValue)ser.Deserialize(reader);
				
				// Copy the bytes from Physical Memory so we don't pageFault in a Fault Hander
				for (int i = 0; i < CPU.pageSize; i++)
					CPU.physicalMemory[winner.addrPhysical+i] = pageValue.memory[i];

				//Console.WriteLine("Swapping in page {0} at physical memory {1}",winner.pageNumber, winner.addrPhysical);
				
				winner.accessCount = pageValue.accessCount;
				winner.lastAccessed = pageValue.lastAccessed;

				pageValue = null;

				reader.Close();
				fs.Close();
				File.Delete(filename);
			}
			else //no swap file, do nothing
			{
				//Console.WriteLine(filename + " doesn't exist");
			}
			
			// We are now in memory and we were involved in Page Fault
			winner.isValid = true;
			winner.pageFaults++;
		}

		/// <summary>
		/// For statistical purposes only.  
		/// Total up how many times this Process has been involved in a Page Fault
		/// </summary>
		/// <param name="p">The Process to total</param>
		/// <returns>number of Page Faults</returns>
		public uint PageFaultsForProcess(Process p)
		{
			uint totalPageFaults = 0;
			foreach (MemoryPage page in _pageTable)
			{
				if (page.pidOwner == p.PCB.pid)
				{
					totalPageFaults += page.pageFaults;
				}
			}
			return totalPageFaults;
		}
	}

	/// <summary>
	/// Memory Protection: MemoryExceptions are constructed and thrown 
	/// when a <see cref="Process"/> accessed memory that doesn't belong to it.
	/// </summary>
	public class MemoryException : Exception
	{
		/// <summary>
		/// Process ID
		/// </summary>
		public uint pid = 0;
		/// <summary>
		/// Process address in question
		/// </summary>
		public uint processAddress = 0;

		/// <summary>
		/// Public Constructor for a Memory Exception
		/// </summary>
		/// <param name="pidIn">Process ID</param>
		/// <param name="addrIn">Process address</param>
		public MemoryException(uint pidIn, uint addrIn)
		{
			pid = pidIn;
			processAddress = addrIn;			
		}

		/// <summary>
		/// Pretty printing for MemoryExceptions
		/// </summary>
		/// <returns>Formatted string about the MemoryException</returns>
		public override string ToString()
		{
			return String.Format("Process {0} tried to access memory at address {1} and will be terminated! ",pid, processAddress);
		}
	}

	/// <summary>
	/// Memory Protection: MemoryExceptions are constructed and thrown 
	/// when a <see cref="Process"/> accessed memory that doesn't belong to it.
	/// </summary>
	public class StackException : Exception
	{
		/// <summary>
		/// Process ID
		/// </summary>
		public uint pid = 0;
		/// <summary>
		/// Num of Bytes more than the stack could handle
		/// </summary>
		public uint tooManyBytes = 0;

		/// <summary>
		/// Public Constructor for a Memory Exception
		/// </summary>
		/// <param name="pidIn">Process ID</param>
		/// <param name="tooManyBytesIn">Process address</param>
		public StackException(uint pidIn, uint tooManyBytesIn)
		{
			pid = pidIn;
			tooManyBytes = tooManyBytesIn;			
		}

		/// <summary>
		/// Pretty printing for MemoryExceptions
		/// </summary>
		/// <returns>Formatted string about the MemoryException</returns>
		public override string ToString()
		{
			return String.Format("Process {0} tried to push {1} too many bytes on to the stack and will be terminated! ",pid, tooManyBytes);
		}
	}

	/// <summary>
	/// Memory Protection: MemoryExceptions are constructed and thrown 
	/// when a <see cref="Process"/> accessed memory that doesn't belong to it.
	/// </summary>
	public class HeapException : Exception
	{
		/// <summary>
		/// Process ID
		/// </summary>
		public uint pid = 0;
		/// <summary>
		/// Num of Bytes more than the stack could handle
		/// </summary>
		public uint tooManyBytes = 0;

		/// <summary>
		/// Public Constructor for a Memory Exception
		/// </summary>
		/// <param name="pidIn">Process ID</param>
		/// <param name="tooManyBytesIn">Process address</param>
		public HeapException(uint pidIn, uint tooManyBytesIn)
		{
			pid = pidIn;
			tooManyBytes = tooManyBytesIn;			
		}

		/// <summary>
		/// Pretty printing for MemoryExceptions
		/// </summary>
		/// <returns>Formatted string about the MemoryException</returns>
		public override string ToString()
		{
			return String.Format("Process {0} tried to alloc {1} bytes more from the heap than were free and will be terminated! ",pid, tooManyBytes);
		}
	}


}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -