УЧЕБНЫЙ ЭМУЛЯТОР МНОГОПОТОЧНЫХ РЕЖИМОВ ОПЕРАЦИОННЫХ СИСТЕМ - Студенческий научный форум

III Международная студенческая научная конференция Студенческий научный форум - 2011

УЧЕБНЫЙ ЭМУЛЯТОР МНОГОПОТОЧНЫХ РЕЖИМОВ ОПЕРАЦИОННЫХ СИСТЕМ

 Комментарии
Текст работы размещён без изображений и формул.
Полная версия работы доступна во вкладке "Файлы работы" в формате PDF

Функциональная модель учебного эмулятора многопоточных режимов операционных систем (УЭМОС)

Система УЭМОС логически разделена на три подсистемы, выполняющие каждая свои функции. Графическая подсистема отвечает за вывод графической информации на экран монитора, оперирование органами управления (ввиду несовершенства стандартных органов управления ОС MicrosoftTM Windows®, все органы управления были написаны с нуля). Подсистема подключаемых модулей отвечает за работу с динамически подключаемыми библиотеками, обеспечивая работу планировщиков, ведения аудита системы. Исполнительная подсистема отвечает за работу исполнительного ядра системы.

Несмотря на скоростные инструменты разработки, авторы решили отказаться от них из-за недостаточной гибкости их управления, малой скорости работы и отсутствия поддержки современных графических систем, таких как MicrosoftTM DirectX®. Вся система УЭМОС написана на языке Object Pascal с использованием WinAPI, DirectX® API.

Также система УЭМОС имеет многоязыковую поддержку, управляемую из командной строки. Языковой модуль представляет собой динамически подключаемые библиотеки. Таким образом, с системой могут работать люди, говорящие на любом языке.

Графическая подсистема

Для создания графической подсистемы авторами было решено использовать современную систему MicrosoftTM DirectX®. В ходе ее проектирования был создан ряд классов, отвечающих за работу различных органов управления (кнопки, ползунки, надписи, полоски прогресса и окна). Таким образом, авторы добились унификации программирования и оперирования различными элементами управления. Графическая подсистема в автоматическом режиме следит за состоянием своих компонентов и своевременно отвечает на их изменение.

Подсистема подключаемых модулей

Подсистема подключаемых модулей выполняет две функции. Одна отвечает за аудит системы, т.е. ведет подробный лог всех событий и изменений в системе. Вторая отвечает за связывание исполнительной подсистемы УЭМОС с планировщиками. Система при старте автоматически находит и подключает все планировщики, находящиеся в специальной папке. Настоящая подсистема спроектирована таким образом, что программисту не нужно думать о подключении динамических библиотек или очистке памяти после их работы. Все эти трудности подсистема берет на себя. Обращение к функциям также происходит через контейнеры, как если бы это были функции самой вызывающей программы.

Исполнительная подсистема

Исполнительная подсистема отвечает за работу эмулятора. Для обеспечения такой работы авторами был создан набор объектов, отвечающих каждый за свою часть системы - ЦП, КП, процессы, программы, каналы, обмены и VMOS - объект, связывающий и обеспечивающий работу всех остальных.

Объект ЦП отвечает за работу и сбор статистики центрального процессора эмулируемой системы. КП - за канальный процессор. Процессы отвечают за работу и сбор статистики процессов (потоков), программы - за выполнение процессов. Каналы имитируют ресурсы системы, обмены отвечают за работу канального процессора. VMOS - объединяет в себе все описанные объекты и координирует их работу.

Реализация УЭМОС

В ходе проектирования УЭМОС авторами было принято решение об использовании стандартных контейнеров для хранения универсальных объектов. Исходя из этого, базовым классом для всех объектов системы стал класс TPersistent. TPersistent обладает возможностью создания копий объектов, благодаря чему не создается путаницы с указателями на объекты, а также поддерживается стандартными объектами - списками, наследуемыми от класса TStrings.

Основным объектом эмулятора является VMOSSystem класса TVMOS.

Класс TVMOS

TVMOS = class(TPersistent)

private

  CurIntTimer:  integer;

public

  CPUs:      TStrings;

  CMUs:      TStrings;

  Devices:   TStrings;

  Exchanges: TStrings;

  Procs:     TStrings;

  Planners:  TStrings;

  LastExchange: integer;

  ActivePlanner: integer;

  ActiveProcess: integer;

  Paused:    Boolean;

  StopOnInt: Boolean;

  StopNext:  Boolean;

  Time:     integer;

  IntTimer: integer;

  PlanTime: integer;

  Finished: Boolean;

  constructor Create;

  destructor Destroy; override;

  procedure ClearSystem;

  procedure SaveThreadText(FileName: string; Proc: integer);

  procedure SaveThreadBin(FileName: string; Proc: integer);

  function LoadThreadText(FileName: string): integer;

  function LoadThreadBin(FileName: string): integer;

  procedure SaveSystem(FileName: string);

  procedure LoadSystem(FileName: string);

  procedure Tick;

  procedure CallPlanner;

  procedure ExecuteProc;

end;

Данный класс инкапсулирует работу всей системы, обеспечивая имитацию всех происходящих в эмулируемой ОС процессов, поддерживает сохранение и загрузку процессов, как в текстовом, так и в бинарном виде и целых систем только в бинарном виде.

Основную работу в данном классе выполняет процедура Tick, имитирующая один такт эмулируемой системы.

Процедура TVMOS.Tick

procedure TVMOS.Tick;

var

  i, me: integer;

  Proc: TProc;

  Ex: TExchange;

  PE: TProgramEntry;

  Pl: TPlanner;

begin

  if Finished then Exit;

  Pl := Planners.Objects[ActivePlanner] as TPlanner;

  if Time = 0 then begin

    Log.AddMessage(LangStr(57));

    CurIntTimer := PlanTime;

  end;

  if (ActiveProcess <> -1) or (PlanTime <> 0) then Inc(Time);

  if StopNext then begin

    Paused := true;

    StopNext := false;

  end;

  Dec(CurIntTimer);

  for i := 0 to Procs.Count - 1 do Inc((Procs.Objects[i] as TProc).NOP);

  (CMUs.Objects[0] as TCMU).Busy := false;

  if Exchanges.Count > 0 then begin

    (CMUs.Objects[0] as TCMU).Busy := true;

    me := 0;

    for i := 0 to Exchanges.Count - 1 do begin

      Dec((Exchanges.Objects[i] as TExchange).Time);

      if (Exchanges.Objects[i] as TExchange).Time < (Exchanges.Objects[me] as TExchange).Time then me := i;

    end;

    Ex := Exchanges.Objects[me] as TExchange;

    if Ex.Time <= 0 then begin

      if StopOnInt then begin

        Paused := true;

        StopOnInt := false;

      end;

      if (ActiveProcess >= 0) and (Ex.Proc <> ActiveProcess) then begin

        (Procs.Objects[ActiveProcess] as TProc).Busy := false;

        (Procs.Objects[ActiveProcess] as TProc).NOP := 0;

        ActiveProcess := -1;

        CurIntTimer := PlanTime;

      end;

      Proc := Procs.Objects[(Exchanges.Objects[me] as TExchange).Proc] as TProc;

      if Proc.WaitForExchange = (Exchanges.Objects[me] as TExchange).ID then begin

        Proc.WaitForExchange := -1;

        for i := Proc.CurProg downto 0 do begin

          PE := (Proc.Prog.Objects[i] as TProgramEntry);

          if (PE.Code = 4) and (PE.Params[0] = Ex.Device) then begin

            PE.Params[2] := PE.Params[1];

            break;

          end;

        end;

        for i := Proc.CurProg to Proc.Prog.Count - 1 do begin

          PE := (Proc.Prog.Objects[i] as TProgramEntry);

          if (PE.Code >= 2) and (PE.Code <= 5) and (PE.Params[0] = Ex.Device) then begin

            if (PE.Code = 5) then PE.Params[2] := 1;

            break;

          end;

        end;

        Log.AddMessage(Format(LangStr(58), [Time, Ex.Proc, Ex.Device]));

        Exchanges.Objects[me].Free;

        Exchanges.Delete(me);

      end;

    end;

  end;

  (CPUs.Objects[0] as TCPU).Busy := false;

  if (Exchanges.Count = 0) or (poParallelCPUs in Pl.Options) then begin

    if CurIntTimer <= 0 then begin

      if ActiveProcess >= 0 then begin

        if poIntTimerExists in Pl.Options then begin

          if StopOnInt then begin

            Paused := true;

            StopOnInt := false;

          end;

          Log.AddMessage(Format(LangStr(59), [Time]));

          (Procs.Objects[ActiveProcess] as TProc).Busy := false;

          ActiveProcess := -1;

          CurIntTimer := PlanTime;

          (CPUs.Objects[0] as TCPU).Busy := true;

        end;

      end else ActiveProcess := -2;

    end;

    if ActiveProcess = -2 then begin

      (CPUs.Objects[0] as TCPU).Busy := true;

      if (Exchanges.Count = 0) then CallPlanner

      else if ((not (poIgnoreNextProc in Pl.Options)) or (poIntTimerExists in Pl.Options)) then CallPlanner;

      if ActiveProcess < 0 then begin

        (CPUs.Objects[0] as TCPU).Busy := false;

        CurIntTimer := 0;

        if Exchanges.Count = 0 then begin

          if Procs.Count > 0 then begin

            for i := 0 to Procs.Count - 1 do begin

              if (Procs.Objects[i] as TProc).Priority <> ppSleep then begin

                Log.AddMessage(Format(LangStr(56), [Time]));

                break;

              end;

              Log.AddMessage(Format(LangStr(55), [Time]));

            end;

          end else Log.AddMessage(Format(LangStr(55), [Time]));

          Finished := true;

          Exit;

        end else Log.AddMessage(Format(LangStr(65), [Time]));

      end else Log.AddMessage(Format(LangStr(60), [Time, ActiveProcess]));

    end else if ActiveProcess >= 0 then begin

      (CPUs.Objects[0] as TCPU).Busy := true;

      ExecuteProc;

    end;

  end;

  if (CPUs.Objects[0] as TCPU).Busy then Inc((CPUs.Objects[0] as TCPU).Work);

  if (CMUs.Objects[0] as TCMU).Busy then Inc((CMUs.Objects[0] as TCMU).Work);

end;

Как можно увидеть из кода процедуры, универсальность вносит некоторую сложность его восприятия, как и многоязыковая поддержка. Однако, этот способ позволяет не создавать множество очередей с данными разных типов, что существенно упрощает само программирование.

За вызов планировщика отвечает процедура CallPlanner. Она собирает данные для планировщика в зависимости от его настроек и вызывает процедуру Select. Переменная Select принадлежит классу TPlanner и является указателем на внешнюю процедуру, подгружаемую из динамической библиотеки.

Интерфейс УЭМОС представлен ниже:

Набор стандартных планировщиков можно расширить, выбрав новое сочетание из 9 их свойств. УЭМОС позволяет проследить процессы, протекающие в различных операционных системах в динамике, а также получить подробный отчет обо всех событиях, имевших место в процессе имитации, в том числе о тупиках, о средней загрузке процессора и каналов.

Редактор процессов существенно расширен добавлением операторов управления нитями, их синхронизацией, а также оператора ожидания канала. Интерфейс редактора приведен далее:

Разработана методика применения в учебном процессе данной разработки, представлен тематический план проведения лабораторных работ с использованием УЭМОС и составлен список возможных заданий.

Просмотров работы: 4