Отчет по дисциплине Операционные системы

Автор: Пользователь скрыл имя, 15 Июня 2012 в 14:25, лабораторная работа

Описание работы

Продумайте систему сегментного хранения информации. Исходные данные:
Программа на Cи (Си++), под Windows, Консольное приложение.
Вся доступная память представлена массивом 10 КБайт. Все операции с выделением, доступом и освобождением памяти проводятся только с памятью внутри этого массива.

Работа содержит 1 файл

оси.doc

— 81.00 Кб (Скачать)

Санкт-Петербургский  Государственный Политехнический  Университет

Кафедра Измерительных Информационных Технологий 
 
 
 
 
 

Отчет по дисциплине Операционные системы

По лабораторной работе №1

По теме «Менеджер сегментированной памяти»  
 
 
 
 
 

Выполнил:  Разов Владимир 
группа 1085/4 
 
 
 
 
 
 
 
 
 

2012 
Санкт-Петербург

Задание

  Продумайте  систему сегментного хранения  информации. Исходные данные:

  1. Программа на Cи (Си++), под Windows, Консольное приложение.
  2. Вся доступная память представлена массивом 10 КБайт. Все операции с выделением, доступом и освобождением памяти проводятся только с памятью внутри этого массива.

    Инициализация менеджера памяти (если необходима) должна вся находиться в функции:

    void InitMemory(void);

  1. Необходима функция для выделения памяти с прототипом:

    int AllocMemory(int Size);

    Size – запрашиваемый размер в байтах.

    Функция возвращает описатель выделенного блока  или 0, если нет доступной памяти.

  1. Необходима функция для освобождения памяти с прототипом:

    void FreeMemory(int MemoryHandle);

    MemoryHandle – описатель ранее выделенной памяти.

  1. Необходима функция для записи информации в ранее выделенную память с прототипом:

    int WriteMemory(int MemoryHandle, int Offset, int Size, void *Data);

    MemoryHandle – описатель ранее выделенной памяти.

    Offset – смещение внутри выделенного блока от его начала до места с которого необходимо записать данные.

    Size – размер блока данных для записи в байтах.

    Data – указатель на буфер, содержащий данные для копирования.

    Функция возвращает 0, если запись в память осуществлена корректно или 1, если произошла какая-либо ошибка.

  1. Необходима функция для чтения информации из ранее выделенной памяти с прототипом:

    int ReadMemory(int MemoryHandle, int Offset, int Size, void *Data);

    MemoryHandle – описатель ранее выделенной памяти.

    Offset – смещение внутри выделенного блока от его начала до места с которого необходимо прочитать данные.

    Size – размер блока данных для чтения в байтах.

    Data – указатель на буфер, куда должны быть скопированы данные. Функция возвращает 0, если чтение из памяти осуществлено корректно или 1, если произошла какая-либо ошибка.

  1. Необходима функция для «утряски» памяти в случае, если максимальный свободный блок памяти не достаточен для размещения очередного блока, но сумма всех свободных участков позволяет разместить его. При этом все уже выделенные блоки смещаются в начало массива и образуется один блок свободной памяти в конце массива, в котором и выделяется вновь запрашиваемый блок памяти.
  2. Необходима функция для вывода дампа всех блоков на экран:

    void DumpMemory(void);

    Функция выводит на экран для каждого блока внутри массива следующую информацию (одна строка на один блок):

  • описатель блока;
  • смещение от начала массива до начала блока;
  • размер блока;
  • занятый или пустой блок;
  • первые 10 байт блока.

    Пример:

    H:35   B:1234   S:345  Yes  2,3,3,2,1,1,2,3,4,5

    Здесь: H–описатель, B-начало блока, S-размер блока, Yes(No)-занят или свободен блок.

  1. Необходима функция для тестирования работоспособности менеджера памяти. Использоваться должны все вышеперечисленные функции для работы с памятью. Также необходимо сымитировать ситуацию, когда производится «утряска» памяти.
  2. В выводах ответьте на следующие вопросы:

    - Когда у вас происходит «утряски» памяти, в момент выделения памяти или в момент освобождения и почему? Приведите пример когда выгоднее использовать противоположную модель«утряски» памяти.

    - Можно ли в качестве описателя блока использовать смещение внутри массива памяти (в 10 кБайтов)? Если да, то что для этого нужно? 

Принцип работы

Структура. 

   Каждый  сегмент описывается структурой типа Block.

   Свойства:

  1. short int Adres – расположение сегмента начиная с начала массива;
  2. short Size – размер массива;
  3. bool Bit – бит занятости;
  4. short int Handle – уникальный ID сегмента;
  5. struct Block *next – указатель на следующий элемент;
 

Инициализация.

   Определяется количество свободной памяти. 

Создание  нового сегмента (выделение) памяти. 

   Метод принимает размер выделяемой памяти в байтах (int) и возвращает handle сегмента или 0, если выделение невозможно (int).

   Создание  происходит по сценарию:

  1. Если это первый сегмент и под него хватает места, то создаем структуру, описывающую его(struct Block), выделяем для неё память в массиве и выделяем сегмент.
  2. Если сегмент не первый, то:
    1. Проверяем место между блоками(ищем блок у которого бит занятости равен 0 и его размер меньше или равен необходимому(p), если находим такой блок то создаем структуру типа Block выделяем новый сегмент внутри блока (p) а размер уменьшаем на переменную Size).
    2. Если места между блоками не хватает, то проверяем объем после сегментов, если его хватает, то выделяем там новую структуру и новый сегмент.
    3. Если после блоков не хватает места, но в сумме(после блоков и между) хватает места то вызываем утряску памяти и потом вновь выделяем сегмент.

 

Освобождение памяти. 

   Функция принимает handle (int).

   Производим поиск совпадения ID (handle) по всем сегментам, удаляем сегмент. Удаление заключается в «занулении» элементов массива, принадлежащих данному и присвоении биту занятости 0. 

   Запись  данных 

    Функция  принимает  описатель ранее выделенной памяти(Handle), смещение внутри выделенного блока от его начала до места с которого необходимо записать данные(Offset), размер блока данных для записи в байтах(Size), указатель на буфер, содержащий данные для копирования(Data).

    Первоначально ищется сегмент с необходимым  описателем(Handle), предполагается, что сегмент с необходимым описателем выделен. Затем проверяются следующие условия:

      Смещение  меньше, чем размер сегмента.

    1. Сумма смещения и размера данных меньше, чем размер сегмнта.
    2. Размер больше 0.
    3. Смешение больше 0.

    Если хоть одно из условий не выполняется то запись не осуществляется и функция возвращает 1.

    Затем, начиная  со смещения данные побайтово копируются из буфер (указатель на него подается в функцию). 

Чтение  данных 

    Функция  принимает  описатель ранее выделенной памяти(Handle), смещение внутри выделенного блока от его начала до места с которого необходимо записать данные(Offset), размер блока данных для записи в байтах(Size), указатель на буфер, куда должны быть скопированы данные(Data).

    Первоначально ищется сегмент с необходимым описателем(Handle), предполагается, что сегмент с необходимым описателем выделен. Затем проверяются следующие условия:

      Смещение  меньше, чем размер сегмента.

    1. Сумма смещения и размера данных меньше, чем размер сегмнта.
    2. Размер больше 0.
    3. Смешение больше 0.

    Если хоть одно из условий не выполняется то запись не осуществляется и функция  возвращает 1.

    Затем, начиная  со смещения данные побайтово копируются в буфер (указатель на него подается в функцию). 
     

«Утряска» памяти. 

   Ищется  сегмент, у которого бит занятости равен 0. Затем все сегменты смещаются на его размер. Затем каждую структуру, у которой поле bool Bit равно 0 удаляем и производим смещение всех структур на её размер. 
 

   Дамп  памяти 

   Данная  функция выводит информацию о  блоках. Выводятся данные сегментов, у которых у описывающей структуры переменная Sort не равна 1. Так же выводится информация о количестве свободной памяти. 

Вывод. 

    1. «Утряска» вызывается в момент выделения памяти и только тогда, когда отдельных свободных областей недостаточно для нового сегмента, а суммарно свободного места для него как раз хватает. Таким образом, данная функция срабатывает редко и только при крайней необходимости и выделение памяти в большинстве случаев происходит достаточно быстро.
    2. В моей программе использование смещения (Adres) сегмента внутри памяти как уникальный ID (handle) является невозможным. Так как при «утряске» смещение (Adres) у всех сегментов может сильно измениться и мы не сможем больше к ним обращаться. Поэтому для этого у сегмента есть отдельное свойство handle, где храниться уникальный номер. Номера присваиваются последовательно в момент создания сегмента.
 
 
 
 
 
 
 
 
 
 

     Листинг

test.cpp

#include "prot.h"

#include "stdio.h"

#include "conio.h"

#include <locale.h>

#include <stdlib.h>

#include <iostream>

using namespace std; 

int main(int)

{

      setlocale(LC_ALL, "Russian_Russia.1251");

      InitMemory(); 

      int h=AllocMemory(1500);

      DumpMemory();

      printf("\n");

      int m=AllocMemory(1500);

      DumpMemory();

      printf("\n");

      int k=AllocMemory(1500);

      int Offset=2;

      char xm[]="ololosh\0";

      void *Data=(void*)xm;

      int Offset1=3;

      int Size1=7;

      char ololo[30]="\0";

      void *Data1=(void*)ololo;

      WriteMemory(m, Offset,sizeof(xm),Data);

      ReadMemory(m, Offset1,Size1,Data1);

      DumpMemory();

      printf("\n");

Информация о работе Отчет по дисциплине Операционные системы