Отчет по дисциплине Операционные системы
Лабораторная работа, 15 Июня 2012, автор: пользователь скрыл имя
Описание работы
Продумайте систему сегментного хранения информации. Исходные данные:
Программа на Cи (Си++), под Windows, Консольное приложение.
Вся доступная память представлена массивом 10 КБайт. Все операции с выделением, доступом и освобождением памяти проводятся только с памятью внутри этого массива.
Работа содержит 1 файл
оси.doc
— 81.00 Кб (Скачать)Санкт-Петербургский
Государственный
Кафедра
Измерительных Информационных Технологий
Отчет по дисциплине Операционные системы
По лабораторной работе №1
По теме
«Менеджер сегментированной памяти»
Выполнил:
Разов Владимир
группа 1085/4
2012
Санкт-Петербург
Задание
Продумайте систему сегментного хранения информации. Исходные данные:
- Программа на Cи (Си++), под Windows, Консольное приложение.
- Вся доступная память представлена массивом 10 КБайт. Все операции с выделением, доступом и освобождением памяти проводятся только с памятью внутри этого массива.
Инициализация менеджера памяти (если необходима) должна вся находиться в функции:
void InitMemory(void);
- Необходима функция для выделения памяти с прототипом:
int AllocMemory(int Size);
Size – запрашиваемый размер в байтах.
Функция возвращает описатель выделенного блока или 0, если нет доступной памяти.
- Необходима функция для освобождения памяти с прототипом:
void FreeMemory(int MemoryHandle);
MemoryHandle – описатель ранее выделенной памяти.
- Необходима функция для записи информации в ранее выделенную память с прототипом:
int WriteMemory(int MemoryHandle, int Offset, int Size, void *Data);
MemoryHandle – описатель ранее выделенной памяти.
Offset – смещение внутри выделенного блока от его начала до места с которого необходимо записать данные.
Size – размер блока данных для записи в байтах.
Data – указатель на буфер, содержащий данные для копирования.
Функция возвращает 0, если запись в память осуществлена корректно или 1, если произошла какая-либо ошибка.
- Необходима функция для чтения информации из ранее выделенной памяти с прототипом:
int ReadMemory(int MemoryHandle, int Offset, int Size, void *Data);
MemoryHandle – описатель ранее выделенной памяти.
Offset – смещение внутри выделенного блока от его начала до места с которого необходимо прочитать данные.
Size – размер блока данных для чтения в байтах.
Data – указатель на буфер, куда должны быть скопированы данные. Функция возвращает 0, если чтение из памяти осуществлено корректно или 1, если произошла какая-либо ошибка.
- Необходима функция для «утряски» памяти в случае, если максимальный свободный блок памяти не достаточен для размещения очередного блока, но сумма всех свободных участков позволяет разместить его. При этом все уже выделенные блоки смещаются в начало массива и образуется один блок свободной памяти в конце массива, в котором и выделяется вновь запрашиваемый блок памяти.
- Необходима функция для вывода дампа всех блоков на экран:
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)-занят или свободен блок.
- Необходима функция для тестирования работоспособности менеджера памяти. Использоваться должны все вышеперечисленные функции для работы с памятью. Также необходимо сымитировать ситуацию, когда производится «утряска» памяти.
- В выводах ответьте на следующие вопросы:
- Когда у вас происходит «утряски» памяти, в момент выделения памяти или в момент освобождения и почему? Приведите пример когда выгоднее использовать противоположную модель«утряски» памяти.
- Можно ли в качестве
описателя блока использовать смещение
внутри массива памяти (в 10 кБайтов)? Если
да, то что для этого нужно?
Принцип работы
Структура.
Каждый сегмент описывается структурой типа Block.
Свойства:
- short int Adres – расположение сегмента начиная с начала массива;
- short Size – размер массива;
- bool Bit – бит занятости;
- short int Handle – уникальный ID сегмента;
- struct Block *next – указатель на следующий элемент;
Инициализация.
Определяется
количество свободной памяти.
Создание
нового сегмента (выделение)
памяти.
Метод принимает размер выделяемой памяти в байтах (int) и возвращает handle сегмента или 0, если выделение невозможно (int).
Создание происходит по сценарию:
- Если это первый сегмент и под него хватает места, то создаем структуру, описывающую его(struct Block), выделяем для неё память в массиве и выделяем сегмент.
- Если сегмент не первый, то:
- Проверяем место между блоками(ищем блок у которого бит занятости равен 0 и его размер меньше или равен необходимому(p), если находим такой блок то создаем структуру типа Block выделяем новый сегмент внутри блока (p) а размер уменьшаем на переменную Size).
- Если места между блоками не хватает, то проверяем объем после сегментов, если его хватает, то выделяем там новую структуру и новый сегмент.
- Если после блоков не хватает места, но в сумме(после блоков и между) хватает места то вызываем утряску памяти и потом вновь выделяем сегмент.
Освобождение
памяти.
Функция принимает handle (int).
Производим
поиск совпадения ID (handle) по всем сегментам,
удаляем сегмент. Удаление заключается
в «занулении» элементов массива, принадлежащих
данному и присвоении биту занятости 0.
Запись
данных
Функция принимает описатель ранее выделенной памяти(Handle), смещение внутри выделенного блока от его начала до места с которого необходимо записать данные(Offset), размер блока данных для записи в байтах(Size), указатель на буфер, содержащий данные для копирования(Data).
Первоначально ищется сегмент с необходимым описателем(Handle), предполагается, что сегмент с необходимым описателем выделен. Затем проверяются следующие условия:
Смещение меньше, чем размер сегмента.
- Сумма смещения и размера данных меньше, чем размер сегмнта.
- Размер больше 0.
- Смешение больше 0.
Если хоть одно из условий не выполняется то запись не осуществляется и функция возвращает 1.
Затем, начиная
со смещения данные побайтово копируются
из буфер (указатель на него подается
в функцию).
Чтение
данных
Функция принимает описатель ранее выделенной памяти(Handle), смещение внутри выделенного блока от его начала до места с которого необходимо записать данные(Offset), размер блока данных для записи в байтах(Size), указатель на буфер, куда должны быть скопированы данные(Data).
Первоначально ищется сегмент с необходимым описателем(Handle), предполагается, что сегмент с необходимым описателем выделен. Затем проверяются следующие условия:
Смещение меньше, чем размер сегмента.
- Сумма смещения и размера данных меньше, чем размер сегмнта.
- Размер больше 0.
- Смешение больше 0.
Если хоть одно из условий не выполняется то запись не осуществляется и функция возвращает 1.
Затем, начиная
со смещения данные побайтово копируются
в буфер (указатель на него подается
в функцию).
«Утряска»
памяти.
Ищется
сегмент, у которого бит занятости равен
0. Затем все сегменты смещаются на его
размер. Затем каждую структуру, у которой
поле bool Bit равно 0 удаляем и производим
смещение всех структур на её размер.
Дамп
памяти
Данная
функция выводит информацию о
блоках. Выводятся данные сегментов, у
которых у описывающей структуры переменная
Sort не равна 1. Так же выводится информация
о количестве свободной памяти.
Вывод.
- «Утряска» вызывается в момент выделения памяти и только тогда, когда отдельных свободных областей недостаточно для нового сегмента, а суммарно свободного места для него как раз хватает. Таким образом, данная функция срабатывает редко и только при крайней необходимости и выделение памяти в большинстве случаев происходит достаточно быстро.
- В моей программе использование смещения (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");