예제 #1
0
파일: Pamiec.cs 프로젝트: Aredhela/ZonkilOS
    /// <summary>
    ///     Mapuje strone do pamieci fizycznej
    /// </summary>
    /// <param name="numerStrony"></param>
    /// <returns>Adres w pamieci fizycznej w ktorej strona zostala zmapowana</returns>
    private int ZmapujStrone(int numerStrony)
    {
        var adres  = -1;
        var strona = _strony[numerStrony];

        // Znajdz wolna strone pamieci
        for (var i = 0; i < _zajeteStronyFizyczne.Length; i++)
        {
            if (_zajeteStronyFizyczne[i] == false)
            {
                adres = i * RozmiarBloku;
                _zajeteStronyFizyczne[i] = true;
                break;
            }
        }

        // Jesli nie znaleziono wolnej strony, swapuj jedna na dysk zeby zwolnic miejsce
        if (adres == -1)
        {
            var nrStronyDoUsuniecia = _stronyZmapowane.Dequeue();
            _strony[nrStronyDoUsuniecia].JestZmapowanaWPamieciFizycznej = false;
            _strony[nrStronyDoUsuniecia].JestNaDysku = true;
            var daneDoZapisania = new byte[RozmiarBloku];
            Array.Copy(_pamiecFizyczna, _strony[nrStronyDoUsuniecia].AdresPoczatkowy, daneDoZapisania, 0,
                       RozmiarBloku);

            _swap.Zapisz((short)nrStronyDoUsuniecia, daneDoZapisania);
            adres = _strony[nrStronyDoUsuniecia].AdresPoczatkowy;
        }

        if (strona.JestNaDysku)
        {
            var daneZDysku = _swap.Odczytaj((short)numerStrony);

            daneZDysku.CopyTo(_pamiecFizyczna, adres);
        }
        else
        {
            // Strona istnieje, ale nigdy wczesniej nie byla uzywana.
            // Mapujemy ja w pamieci i zerujemy
            for (var i = 0; i < RozmiarBloku; i++)
            {
                _pamiecFizyczna[adres + i] = 0;
            }
        }

        _stronyZmapowane.Enqueue(numerStrony);
        strona.JestZmapowanaWPamieciFizycznej = true;
        strona.AdresPoczatkowy = adres;
        return(adres);
    }