/// <summary>
 /// Initializez the page at the beginning of the simulation.
 /// Called by the PageTable once, when the OS requires the initialization of the page table.
 /// </summary>
 /// <param name="index">The index of the page in the page table.</param>
 internal Page(int index)
 {
     IsValid          = false;
     PageIndex        = index;
     IsDirty          = false;
     Requested        = -1;
     LastTimeAccessed = CurrentTimeGetter.GetCrtTime();
 }
        /// <summary>
        /// Method that handles the load of a page from disk to RAM.
        /// Sets the Requested field of the page with the process' pid and calls the OS to load it.
        /// After the OS loaded it, the MMU is notified and resets the Requested field.
        /// </summary>
        /// <param name="command">Represents the received command (read / write).</param>
        /// <param name="page">The page for which the request was made.</param>
        private async static Task HandlePageRequested(Command command, Page page)
        {
            page.Requested        = command.ProcessId;
            page.LastTimeAccessed = CurrentTimeGetter.GetCrtTime();
            await OS.LoadPage(page);

            page.Requested = -1;
            page.IsValid   = true;
        }
        /// <summary>
        /// Method that handles the actual read / write command.
        /// If the command is write, it simulates the handling by asking the OS to save changes to disk (if page is dirty)
        /// and resets the dirty bit.
        /// </summary>
        /// <param name="command">Represents the received command (read / write).</param>
        /// <param name="page">The page for which the request was made.</param>
        private async static Task HandleReadWriteCommand(Command command, Page page)
        {
            page.LastTimeAccessed = CurrentTimeGetter.GetCrtTime();

            if (command.AccessType == PageAccessType.Write)
            {
                if (page.IsDirty)
                {
                    await OS.SavePageChangesToDisk(page);
                }

                page.IsDirty = true;
            }
        }
Beispiel #4
0
        public void CurrentTimeGetterTest()
        {
            DateTime fixedDate = DateTime.Parse("2016, 3, 15").Date;

            using (ShimsContext.Create())
            {
                System.Fakes.ShimDateTime.NowGet = () => { return(new DateTime(2016, 3, 15)); };

                var currentTimeGetter = new CurrentTimeGetter();

                DateTime currentTime = currentTimeGetter.GetCurrentTime();

                Assert.AreEqual(fixedDate, currentTime);
            }
        }
        /// <summary>
        /// Simulates asynchronously the process of swapping a page when the RAM is fully loaded and another page needs to be loaded.
        /// </summary>
        /// <param name="swapPage">The page to be placed in the RAM instead of an old, unused one.</param>
        private async static Task SwapPage(Page swapPage)
        {
            (Page pageToSwap, int pid) = GetPageToBeSwapped();

            if (pageToSwap.IsDirty)
            {
                await SavePageChangesToDisk(pageToSwap);

                pageToSwap.IsDirty = false;
            }

            pageToSwap.IsValid          = false;
            pageToSwap.LastTimeAccessed = CurrentTimeGetter.GetCrtTime();
            Counter.IncrementPageSwaps();//Incremented for each swap. Ensures the correctness of the program's logic.

            LoadRamFrame(swapPage, FindIndexInRam(pid, pageToSwap.PageIndex));
        }
        /// <summary>
        /// Method that gets the page that willl be swapped, from all the processes and their page tables.
        /// </summary>
        /// <returns>A tuple containing the page to be swapped and the pid of the process it belongs to.</returns>
        private static (Page PageToSwap, int Pid) GetPageToBeSwapped()
        {
            string lastAccess = CurrentTimeGetter.GetCrtTime();
            Page   pageToSwap = new Page(-1);
            int    pid        = -1;

            foreach (var process in Processes)
            {
                foreach (var page in process.PageTable.Pages)
                {
                    if (page.IsValid)
                    {
                        if (page.LastTimeAccessed.CompareTo(lastAccess) < 0)
                        {
                            pageToSwap = page;
                            lastAccess = page.LastTimeAccessed;
                            pid        = process.Pid;
                        }
                    }
                }
            }

            return(pageToSwap, pid);
        }