Скачиваний:
46
Добавлен:
01.05.2014
Размер:
20 Кб
Скачать
{
  ‚­Ё¬ ­ЁҐ! „ ­­ п Їа®Ја ¬¬  § йЁйҐ­  § Є®­ ¬Ё ®Ў  ўв®абЄЁе
  Їа ў е Ё ¬Ґ¦¤г­ а®¤­л¬Ё б®Ј« иҐ­Ёп¬Ё. ЌҐ§ Є®­­­®Ґ
  ў®бЇа®Ё§ўҐ¤Ґ­ЁҐ Ё«Ё а бЇа®бва ­Ґ­ЁҐ ¤ ­­®© Їа®Ја ¬¬л Ё«Ё
  «оЎ®© ҐҐ з бвЁ ў«ҐзҐв Ја ¦¤ ­бЄго Ё гЈ®«®ў­го
  ®вўҐб⢥­­®бвм ;)  }

Unit Corout;

{$F+}

Interface

  Type
    ArPtr    = ^ArType;
    ArType   = Array [0..999] of Word; {Ї®¤ б⥪ - 1000 б«®ў}

    { Џа®жҐ¤га , ®ЇҐа в®ал Є®в®а®© ўлЇ®«­повбп ў Їа®жҐбб е }
    TProcedure = Procedure;

    { Џа®жҐбб = Їа®жҐ¤га  + б®бв®п­ЁҐ б⥪  + гЄ § вҐ«м ­  б«Ґ¤гойЁ©
        Їа®жҐбб (¤«п ®аЈ ­Ё§ жЁЁ бЇЁбЄ®ў Їа®жҐбб®ў).
        Џа®жҐбб ®¤Ё­ а § б®§¤ Ґвбп ў Ї ¬пвЁ Ё ®¤Ё­ а § г¤ «пҐвбп,
        ЇаЁ ЇҐаҐ¬ҐйҐ­ЁЁ Ё§ ®зҐаҐ¤Ё ў ®зҐаҐ¤м ¬Ґ­пҐвбп «Ёим Ї®«Ґ Next
        Ё гЄ § вҐ«м Root ў ᮮ⢥вбвўго饩 ®зҐаҐ¤Ё }
    Process  = ^ProcDesc;
    ProcDesc = Object
      { Џ®«п - ®ЇЁб ­ЁҐ ⥪г饣® б®бв®п­Ёп Їа®жҐбб  }
      SSReg,         { Џ®«®¦Ґ­ЁҐ ўҐаиЁ­л б⥪  ў Ї ¬пвЁ }
      SPReg  : Word;
      Stack : ArPtr; { ЊҐбв® ў ¤Ё­ ¬ЁзҐбЄ®© Ї ¬пвЁ Ї®¤ б⥪ }
      TAct : Longint; { ‚аҐ¬п  ЄвЁўЁ§ жЁЁ (®Є®­з ­Ёп § ¤Ґа¦ЄЁ) }
      { Џ®¤¤Ґа¦Є  ®зҐаҐ¤Ё }
      Next : Process; { “Є § вҐ«м ­  б«Ґ¤гойЁ© Їа®жҐбб }
      Constructor Init( Body:TProcedure );
      Destructor Done; Virtual;
      Procedure Set_Next( P:Process );
      Function Get_Next:Process;
    End;

    { -= ЋЎмҐЄв - бЇЁб®Є Їа®жҐбб®ў =- }
    TList = Object
      Root : Process; { Ќ з «® ®зҐаҐ¤Ё Їа®жҐбб®ў }
      Constructor Init; { €­ЁжЁ «Ё§Ёа®ў вм }
      Destructor Done; Virtual; { Ћбў®Ў®¤Ёвм Ї ¬пвм }
      Procedure Include( P:Process ); { ‚Є«озЁвм Їа®жҐбб ў ®зҐаҐ¤м, б ¬ Їа®жҐбб
        ЇаЁ н⮬ ­Ґ б®§¤ Ґвбп }
      Procedure Exclude( P:Process ); { “¤ «Ёвм Їа®жҐбб Ё§ ®зҐаҐ¤Ё, б ¬ Їа®жҐбб
        ЇаЁ н⮬ ­Ґ г­Ёз⮦ Ґвбп  }
      Function Get_Root: Process;
      Function Count: Longint; { Џ®¤бзЁв вм Є®«ЁзҐбвў® н«Ґ¬Ґ­в®ў ў бЇЁбЄҐ }
    End;

    { -= ЋЎмҐЄв - ®зҐаҐ¤м Ј®в®ўле Їа®жҐбб®ў =- }
    TReadyList = Object(TList)
      Constructor Init; { €­ЁжЁ «Ё§Ёа®ў вм }
      Destructor Done; Virtual; { Ћбў®Ў®¤Ёвм Ї ¬пвм }
      Procedure Run_Manager; { ‡ ЇгбвЁвм ¤ЁбЇҐвзҐа }
      Procedure Stop_Manager; { Ћбв ­®ўЁвм ¤ЁбЇҐвзҐа }
      Procedure Add_New_Process( Q:TProcedure ); { „®Ў ўЁвм ­®ўл© Їа®жҐбб }
      Procedure Activate_Next; { ЂЄвЁўЁа®ў вм б«Ґ¤гойЁ© }
    End;

    { -= ЋЎмҐЄв - ®зҐаҐ¤м Їа®жҐбб®ў, § ¤Ґа¦ ­­ле ­  ўаҐ¬п =- }
    TDelayList = Object(TList)
      Procedure Delay( T:Longint );
      Procedure Activisation;
    End {DelayList};

    { -= ЋЎмҐЄв - ®зҐаҐ¤м г­Ёз⮦ Ґ¬ле Їа®жҐбб®ў =- }
    TKillList = Object(TList)
      Procedure SelfInsert;
      Procedure Clear;
    End {KillList};

    { -= ‘Ґ¬ д®а - ‹ Ў  5 =- }
    PSemaphore = ^TSemaphore;
    TSemaphore = Object
      Counter : Longint;
      myList  : TList;
      Constructor Init( C:Longint );
      Destructor  Done; Virtual;
      Procedure   P;
      Procedure   V;
    End {TSemaphore};

    { -= ЃгдҐа - ‹ Ў  6 =- }
    Const BufferSize = 30;
    Type
      { Ћ¤Ё­ н«Ґ¬Ґ­в ЎгдҐа  }
      AnyType = Char;
      { Њ ббЁў н«Ґ¬Ґ­в®ў ЎгдҐа  }
      PCharArray = ^TCharArray;
      TCharArray = Array [0..$FFFE div SizeOf(AnyType)] of AnyType;
      TBuffer = Object
        BufferSize : Word; { €бЇ®«м§гҐвбп вЁЇ Word, в.Є. ў Pascal 7.0 Ё­¤ҐЄбл
          ¬ ббЁў®ў в®«мЄ® вЁЇ  Word }
        _in, _out  : Word; { 0..BufferSize-1 }
        n          : Word; { 0..BufferSize }
        Buf        : PCharArray;{ гЄ § вҐ«м ­  Array [0..BufferSize-1] Of AnyType) }
        ReadList, WriteList  : TList;
        Constructor Init( BufSize:Longint );
        Destructor  Done; Virtual;
        Procedure   Write(M : AnyType);
        Procedure   Read(Var M : AnyType);
        Procedure   Wait_Read;
        Procedure   Signal_Read;
        Procedure   Wait_Write;
        Procedure   Signal_Write;
      End {TBuffer};

    { -= "Џ®зв®ўл© пйЁЄ" - ¤«п ®Ў¬Ґ­  б®®ЎҐй­Ёп¬Ё - ‹ Ў  7 =- }
    { Ћ¤­® б®®ЎйҐ­ЁҐ }
    PMessage = ^TMessage;
    TMessage = Record
      Data : String;
      Next : PMessage;
    End;
    { ‘ЇЁб®Є б®®ЎйҐ­Ё© }
    TMessageList = Object
      Root : PMessage;
      Constructor Init;
      Destructor Done;
      Procedure Insert( P:PMessage );
      Procedure Remove( P:PMessage );
    End;
    { ‘®Ўб⢥­­® "Џ®зв®ўл© пйЁЄ" }
    TPostBox = Object
      MessageList  : TMessageList;{®зҐаҐ¤м гЄ § вҐ«Ґ© ­  б®®ЎйҐ­Ёп}
      SendProcList : TList;{®зҐаҐ¤м Їа®жҐбб®ў, Ї®б« ўиЁе б®®ЎйҐ­Ёп}
      WaitProcList : TList;  {®зҐаҐ¤м Їа®жҐбб®ў. ¦¤гйЁе б®®ЎйҐ­ЁҐ}
      Constructor Init;
      Destructor  Done; Virtual;
      Procedure   PutMsg( M : PMessage ); {Ї®б« вм б®®ЎйҐ­ЁҐ}
      Function    GetMsg    : PMessage;  {ЇаЁ­пвм б®®ЎйҐ­ЁҐ}
    End {TPostBox};

{ ЋвзЁбвЄ  ўбҐ© Ї ¬пвЁ }
Procedure Free_All_Subsystems;

{ ЋЇЁб ­ЁҐ Ј«®Ў «м­ле ЇҐаҐ¬Ґ­­ле }
Var
  ReadyList : TReadyList;
  DelayList : TDelayList;
  KillList  : TKillList;
  CurProc : Process; { ’ҐЄгйЁ© Їа®жҐбб (­ е®¤Ёвбп ў­Ґ ўбҐе ®зҐаҐ¤Ґ©) }
  TCur : Longint; { ’ҐЄг饥 ўаҐ¬п }

{ ЏҐаҐе®¤ ¬Ґ¦¤г Їа®жҐбб ¬Ё }
Procedure Transfer( OldProc, NewProc : Process );

{ Џа®жҐбб, Є®в®ал© ўбҐЈ¤  ў ®зҐаҐ¤Ё Ј®в®ўле }
Procedure Idler; far;

{ Џа®жҐбб - ®б­®ў­ п Їа®Ја ¬¬  }
Var main : Process;

{--------------------------------------------------------------------------}
Implementation

Uses DOS,CRT;

{ ‡¤Ґбм Ўг¤Ґ¬ еа ­Ёвм бв ал© ®Ўа Ў®взЁЄ ЇаҐалў ­Ёп 08 }
Var Int08Save : Pointer;

{ -= ЋЎмҐЄв - ®зҐаҐ¤м Їа®жҐбб®ў =- }
Procedure ProcDesc.Set_Next( P:Process );
Begin
  { ‘‹…„“ћ™€‰ := ...    ; }
  Next := P;
End;

Function ProcDesc.Get_Next:Process;
Begin
  { ЏЋ‹“—€’њ_‘‹…„“ћ™€‰ :=  ‘‹…„“ћ™€‰; }
  Get_Next := Next;
End;

{ ЏђЋ–…‘‘.€Ќ€–€Ђ‹€‡€ђЋ‚Ђ’њ; }
Constructor ProcDesc.Init( Body:TProcedure );
Begin
{  ‘Ћ‡„Ђ’њ_‘ЋЏђЋѓђЂЊЊ“;
  ‡ЂЏЋ‹Ќ€’њ ЏЋ‹… Ђ„ђ…‘_‘’…ЉЂ; }
  New(Stack);
  SSReg := seg(Stack^);
  SPReg := ofs(Stack^) + 1998 - 14;
  memw[ssreg:spreg+2] := ofs(body);
  memw[ssreg:spreg+4] := seg(body);
End;

{--------------------------------------------------------------------------}
Destructor ProcDesc.Done;
Begin
 { Ћ‘‚ЋЃЋ„€’њ ЏЂЊџ’њ, ‡ЂЌџ’“ћ ЏЋ„ ‘’…Љ; }
  Dispose(Stack)
End;

{-----------------------------------------------------}
{$F+}
Procedure Transfer( OldProc, NewProc : Process ); Assembler;
Asm                    {Є®¬ЇЁ«пв®а Ї®б«Ґ Call Transfer
                        Ї®¤бв ў«пҐв push bp; mov bp,sp}
   les di,oldproc
   mov es:[di],ss      {oldproc.ssreg := ss;}
   mov es:[di+2],sp    {oldproc.spreg := sp;  ¤аҐб ў®§ўа в  ў sp+2}
   les di,newproc
   mov ss,es:[di]      {ss := newproc.ssreg;}
   mov sp,es:[di+2]    {sp := newproc.spreg;}
   sti    { ђ §аҐи Ґ¬ ЇаҐалў ­Ёп !!! Џ®пў«пҐвбп, ­ зЁ­ п б « Ўл 2 }
   pop bp      {ўлв «ЄЁў ­ЁҐ bp ўлў®¤Ёв б⥪ ­   ¤аҐб ў®§ўа в }
   ret 8
       {§ в®«Є­г«Ё 8 Ў ©в®ў - 4 б«®ў  - §­ зҐ­Ёп oldproc Ё newproc}
End {Transfer};

{ -= "‡ ЇаҐвЁвм ЇаҐалў ­Ёп" =- }
Procedure Disable_Interrupt; Assembler;
Asm
  cli { CLose Interrupts }
End;

{ -= "ђ §аҐиЁвм ЇаҐалў ­Ёп" =- }
Procedure Enable_Interrupt; Assembler;
Asm
  sti { Stay Interrupts }
End;

{--------------------------------------------------------------------------}
{ -= Џа®жҐ¤га -®Ўа Ў®взЁЄ ЇаҐалў ­Ёп ®в в ©¬Ґа  =- }
Procedure Handler; Interrupt;
Begin
  { ‚л§лў Ґ¬ бв ал© ®Ўа Ў®взЁЄ в ©¬Ґа  (Є®в®ал© ¬л § ¬ҐбвЁ«Ё) }
  Asm Int 60h End;
  { ‡ ЇаҐй Ґ¬ ЇаҐалў ­Ёп }
  Disable_Interrupt;
  { “ўҐ«ЁзЁў Ґ¬ ⥪г饥 ўаҐ¬п ­  1 }
  Inc(TCur);
  { ЂЄвЁўЁ§ жЁп § ¤Ґа¦ ­­ле Їа®жҐбб®ў }
  DelayList.Activisation;
  { ЋвзЁбвЄ  ®зҐаҐ¤Ё г­Ёз⮦ Ґ¬ле Їа®жҐбб®ў }
  KillList.Clear;
  { ЂЄвЁўЁ§Ёа®ў вм б«Ґ¤гойЁ© Їа®жҐбб }
  ReadyList.Activate_Next;
End;

{ ‚ᥣ¤  ў ®зҐаҐ¤Ё Ј®в®ўле }
Procedure Idler;
Begin
  While True do;
End;

{ -= ЋЎмҐЄв - ®зҐаҐ¤м Їа®жҐбб®ў =- }
Constructor TList.Init; { €­ЁжЁ «Ё§Ёа®ў вм }
Begin
  { ЌЂ—Ђ‹Ћ := NIL; }
  Root := nil;
End;

Destructor TList.Done; { Ћбў®Ў®¤Ёвм Ї ¬пвм }
Var Temp : Process;
Begin
  { (–ЁЄ« Ї® ўбҐ¬ Їа®жҐбб ¬ ®зҐаҐ¤Ё)
   ЏђЋ–…‘‘.Ћ‘‚ЋЃЋ„€’њ_ЏЂЊџ’њ; }
  While Root<>nil do begin
    Temp := Root;
    Root := Temp^.Next;
    Dispose(Temp,Done); { “¤ «пҐ¬ б ўл§®ў®¬ ¤ҐбвагЄв®а  }
  end;
End;

{ Џ®¤ўҐиЁў Ґ¬ Їа®жҐбб ў Є®­Ґж ­ иҐ© ®зҐаҐ¤Ё }
Procedure TList.Include( P:Process );
Var Cur : Process;
Begin
  P^.Next := nil;
  If Root = nil then
    Root := P
  Else
    Begin
      Cur := Root;
      While Cur^.Next<>nil do
        Cur := Cur^.Next;
      Cur^.Next := P;
    End;
End;

{ €бЄ«оз Ґ¬ Їа®жҐбб Ё§ ­ иҐ© ®зҐаҐ¤Ё }
Procedure TList.Exclude( P:Process );
Var Cur : Process;
Begin
  If P=Root then
    Root := P^.Next
  Else
    Begin
      Cur := Root;
      While Cur<>nil do
        Begin
          If Cur^.Next = P then
            Begin
              Cur^.Next := P^.Next;
              Break;
            End;
          Cur:=Cur^.Next;
        End;
    End;
End;

Function TList.Get_Root: Process;
Begin
  { ЏЋ‹“—€’њ_ЌЂ—Ђ‹Ћ := ЌЂ—Ђ‹Ћ; }
  Get_Root := Root;
End;

{ Џ®¤бзЁв вм Є®«ЁзҐбвў® н«Ґ¬Ґ­в®ў ў бЇЁбЄҐ }
Function TList.Count: Longint;
Var Temp : Process;
  Cnt : Longint;
Begin
  Temp := Root;
  Cnt := 0;
  While Temp<>nil do
    Begin
      Inc(Cnt);
      Temp := Temp^.Next;
    End;
  Count := Cnt;
End;

{ -= ЋЎмҐЄв - ®зҐаҐ¤м Ј®в®ўле Їа®жҐбб®ў =- }
Constructor TReadyList.Init; { €­ЁжЁ «Ё§Ёа®ў вм }
Begin
  Inherited Init; { Ћ—…ђ…„њ.€Ќ€–€Ђ‹€‡€ђЋ‚Ђ’њ; }
End;

Destructor TReadyList.Done; { Ћбў®Ў®¤Ёвм Ї ¬пвм }
Begin
  TList.Done; { Ћ—…ђ…„њ.Ћ‘‚ЋЃЋ„€’њ_ЏЂЊџ’њ; }
End;

Procedure TReadyList.Run_Manager; { ‡ ЇгбвЁвм ¤ЁбЇҐвзҐа }
Begin
  TCur := 0; { Ќ з «® ®вбзҐв  ўаҐ¬Ґ­Ё }
  { ‡ЂЏђ…’€’њ_Џђ…ђ›‚ЂЌ€џ; }
  Disable_Interrupt; { ‡ ЇаҐвЁвм_ЇаҐалў ­Ёп }
  { Џ…ђ…“‘’ЂЌЋ‚€’њ_‚…Љ’Ћђ_Џђ…ђ›‚ЂЌ€џ_Ћ’_’Ђ‰Њ…ђЂ; }
  GetIntVec($08,Int08Save); { ‘®е࠭塞 бв ал© ®Ўа Ў®взЁЄ ЇаҐалў ­Ёп }
  SetIntVec($60,Int08Save);
  { “‘’ЂЌЋ‚€’њ_ЌЂ_‚…Љ’Ћђ_8_ЏђЋ–…„“ђ“_Handler; }
  SetIntVec($08,Addr(Handler)); { “бв ­ ў«Ёў Ґ¬ бў®© ®Ўа Ў®взЁЄ ЇаҐалў ­Ёп }
  { ЏЋ‹“—€’њ_ЌЂ—Ђ‹Ћ; }
  CurProc := Root;
  { €‘Љ‹ћ—€’њ_ЏђЋ–…‘‘; }
  Exclude(CurProc);
  { Џ…ђ…„Ђ’њ_“ЏђЂ‚‹…Ќ€…; }
  Transfer(main,CurProc);
End;

Procedure TReadyList.Stop_Manager; { Ћбв ­®ўЁвм ¤ЁбЇҐвзҐа }
Begin
  { ‡ЂЏђ…’€’њ_Џђ…ђ›‚ЂЌ€џ; }
  Disable_Interrupt; { ‡ ЇаҐвЁвм_ЇаҐалў ­Ёп }
  { ‚Ћ‘‘’ЂЌЋ‚€’њ_‚…Љ’Ћђ_Џђ…ђ›‚ЂЌ€џ_Ћ’_’Ђ‰Њ…ђЂ; }
  SetIntVec($08,Int08Save); { “бв ­ ў«Ёў Ґ¬ ®Ўа в­® ®Ўа Ў®взЁЄ }
  { Џ…ђ…„Ђ’њ_“ЏђЂ‚‹…Ќ€…; (ў Ј« ў­го Їа®Ја ¬¬г) }
  Transfer(CurProc,main);
End;

Procedure TReadyList.Add_New_Process( Q:TProcedure ); { „®Ў ўЁвм ­®ўл© Їа®жҐбб }
Var NewProc : Process;
Begin
  New(NewProc);
  NewProc^.Init(Q);
  Include(NewProc);
End;

Procedure TReadyList.Activate_Next; { ЂЄвЁўЁа®ў вм б«Ґ¤гойЁ© }
Var LastProc : Process;
Begin
  Include(CurProc);
  LastProc := CurProc;
  CurProc := LastProc^.Get_Next;
  If CurProc = nil then CurProc := Root;
  Exclude(CurProc);
  Transfer(LastProc,CurProc);
End;

{ -= ЋЎмҐЄв - ®зҐаҐ¤м Їа®жҐбб®ў, § ¤Ґа¦ ­­ле ­  ўаҐ¬п =- }
Procedure TDelayList.Delay( T:Longint );
Var PrevProc : Process;
Begin
  PrevProc := CurProc;
 { ‘®е࠭塞 ў ¤ҐбЄаЁЇв®аҐ Їа®жҐбб  ўаҐ¬п Є®Ј¤  ҐЈ® ­г¦­® Ўг¤Ґв  ЄвЁўЁ§Ёа®ў вм }
  PrevProc^.Tact := T + TCur;
  Include(PrevProc); { „®Ў ў«пҐ¬ § ¤Ґа¦ ­­л© Їа®жҐбб ў "­ иг" ®зҐаҐ¤м }
 { ЏҐаҐЄ«озЁ¬бп ў ЇҐаўл© Їа®жҐбб ў бЇЁбЄҐ Ј®в®ўле }
  CurProc := ReadyList.Root;
  ReadyList.Exclude(CurProc);
  Transfer(PrevProc,CurProc);
End {DelayList.Delay};

Procedure TDelayList.Activisation;
Var Cur, NextProc : Process;
Begin
  { Џа®бв® Їа®ЎҐЈ Ґ¬ ўҐбм бЇЁб®Є, Ё Їа®жҐббл, г Є®в®але ­ бвгЇЁ«® ўаҐ¬п
     ЄвЁўЁ§ жЁЁ ЇҐаҐ­®бЁ¬ ў ®зҐаҐ¤м Ј®в®ўле }
  Cur := Root;
  While Cur <> NIL do Begin
    NextProc := Cur^.Next;
    If Cur^.Tact = Tcur then Begin
      Exclude(Cur);
      ReadyList.Include(Cur);
    End; {If}
    Cur := NextProc;
  End; {While}
End {DelayList.Activisation};

{ -= ЋЎмҐЄв - ®зҐаҐ¤м г­Ёз⮦ Ґ¬ле Їа®жҐбб®ў =- }
Procedure TKillList.Clear;
Begin
  TList.Done;
End;

Procedure TKillList.SelfInsert;
Var OldProc : Process;
Begin
  { ’ҐЄгйЁ© Їа®жҐбб Ї®¬Ґй Ґ¬ ў ®зҐаҐ¤м ¤«п г¤ «Ґ­Ёп }
  OldProc := CurProc;
  Include(OldProc);
  { ЏҐаҐ¬Ґй Ґ¬бп ў ЇҐаўл© Їа®жҐбб ў бЇЁбЄҐ Ј®в®ўле }
  CurProc := ReadyList.Root;
  ReadyList.Exclude(CurProc);
  Transfer(OldProc,CurProc);
End;

{ -= ‘Ґ¬ д®а - ‹ Ў  5 =- }
Constructor TSemaphore.Init( C:Longint );
Begin
  Counter := C;
  myList.Init; { ‘®§¤ вм ЋзҐаҐ¤м_ᥬ д®а ; }
End {TSemaphore.Init};

Destructor TSemaphore.Done;
Begin
  myList.Done; { ђ §агиЁвм ЋзҐаҐ¤м_ᥬ д®а ; }
End {TSemaphore.Done};

Procedure TSemaphore.P;
Var PrevProc : Process;
Begin
  Disable_Interrupt; { ‡ ЇаҐвЁвм_ЇаҐалў ­Ёп; }
  Dec(Counter);
  If Counter < 0 Then Begin {Ў«®ЄЁа®ў вм Їа®жҐбб}
    PrevProc := CurProc;
    myList.Include(PrevProc); { ЋзҐаҐ¤м_ᥬ д®а .‚Є«озЁвм(ЏаҐ¤л¤гйЁ©); }
    CurProc := ReadyList.Root; { ’ҐЄгйЁ© := ЋзҐаҐаҐ¤м_Ј®в®ўле.ЏҐаўл©; }
    ReadyList.Exclude(CurProc); { ЋзҐаҐ¤м_Ј®в®ўле.€§ў«Ґзм(’ҐЄгйЁ©); }
    Transfer(PrevProc,CurProc);
  End {If};
  Enable_Interrupt; { § зҐ¬ нв® ­г¦­® ??? }
End {TSemaphore.P};

Procedure TSemaphore.V;
Var PrevProc : Process;
Begin
  Disable_Interrupt;
  Inc(Counter);
  If Counter <= 0 Then Begin { ЄвЁўЁ§Ёа®ў вм Їа®жҐбб}
    PrevProc := CurProc; { ЏаҐ¤л¤гйЁ© := ’ҐЄгйЁ©; }
    ReadyList.Include(PrevProc); { ЋзҐаҐ¤м_Ј®в®ўле.‚Є«озЁвм(ЏаҐ¤л¤гйЁ©); }
    CurProc := myList.Root; { ’ҐЄгйЁ© := ЋзҐаҐ¤м_ᥬ д®а .ЏҐаўл©; }
    myList.Exclude(CurProc); { ЋзҐаҐ¤м_ᥬ д®а .€§ў«Ґзм(’ҐЄгйЁ©); }
    Transfer(PrevProc,CurProc);
  End {If};
  Enable_Interrupt; { § зҐ¬ нв® ­г¦­® ??? }
End {TSemaphore.V};

{ -= ЃгдҐа - ‹ Ў  6 =- }
Constructor TBuffer.Init( BufSize:Longint );
Begin
  BufferSize := BufSize;
  GetMem(Buf,BufferSize*SizeOf(AnyType));
  {}
  _in := 0; _out := 0; n := 0;
  ReadList.Init;
  WriteList.Init;
End {TBuffer.Init};

Destructor TBuffer.Done;
Begin
  FreeMem(Buf,BufferSize*SizeOf(AnyType));
  {}
  ReadList.Done;
  WriteList.Done;
End {TBuffer.Done};

{ ‘Ё­еа®­Ё§ жЁп § ЇЁбЁ Ё з⥭Ёп }
Procedure TBuffer.Wait_Read; {§ бв ў«пҐв Їа®жҐбб ¦¤ вм з⥭Ёп, Ґб«Ё ЎгдҐа Їгбв®©}
Var OldProc : Process;
Begin
  OldProc := CurProc;
  ReadList.Include(OldProc);
  CurProc := ReadyList.Root;
  ReadyList.Exclude(CurProc);
  Transfer(OldProc,CurProc);
End {TBuffer.Wait_Read};

Procedure TBuffer.Wait_Write; {§ бв ў«пҐв Їа®жҐбб ¦¤ вм § ЇЁбЁ, Ґб«Ё ЎгдҐа Ї®«­л©}
Var OldProc : Process;
Begin
  OldProc := CurProc;
  WriteList.Include(OldProc);
  CurProc := ReadyList.Root;
  ReadyList.Exclude(CurProc);
  Transfer(OldProc, CurProc);
End {TBuffer.Wait_Write};

Procedure TBuffer.Write(M : AnyType);
Begin
  Disable_Interrupt;
  If n = BufferSize Then Wait_Write; {ЎгдҐа Ї®«­л©}
  n := n + 1;
  Buf^[_in] := M;
  _in := (_in + 1) MOD BufferSize;
  Signal_Read;
  Enable_Interrupt;;
End {TBuffer.Write};

Procedure TBuffer.Read( Var M : AnyType );
Begin
  Disable_Interrupt;
  If n = 0 Then Wait_Read; {ЎгдҐа Їгбв®©}
  n := n - 1;
  M := Buf^[_out];
  Buf^[_out] := ' '; { „«п ¤Ґ¬®бва жЁЁ, зв® ¬л Їа®зЁв «Ё нв®в бЁ¬ў®« }
  _out := (_out + 1) MOD BufferSize;
  Signal_Write;
  Enable_Interrupt;
End {TBuffer.Read};

Procedure TBuffer.Signal_Read;
Var OldProc, Local : Process;
Begin
  Local := ReadList.Root;
  If Local <> NIL Then Begin   {®зҐаҐ¤м ­Ґ Їгбв п}
    OldProc := CurProc;
    CurProc := Local;
    ReadList.Exclude(Local);
    ReadyList.Include(OldProc);
    Transfer(OldProc, CurProc);
  End {If};
End {TBuffer.Signal_Read};

Procedure TBuffer.Signal_Write;
Var OldProc, Local : Process;
Begin
  Local := WriteList.Root;
  If Local <> NIL Then Begin   {®зҐаҐ¤м ­Ґ Їгбв п}
    OldProc := CurProc;
    CurProc := Local;
    WriteList.Exclude(Local);
    ReadyList.Include(OldProc);
    Transfer(OldProc, CurProc);
  End {If};
End {TBuffer.Signal_Read};

{ -= "Џ®зв®ўл© пйЁЄ" - ¤«п ®Ў¬Ґ­  б®®ЎҐй­Ёп¬Ё - ‹ Ў  7 =- }

Constructor TMessageList.Init;
Begin
  Root := nil;
End;

Destructor TMessageList.Done; { € б­®ў  ваЁўЁ «м­®Ґ г­Ёз⮦Ґ­ЁҐ бЇЁбЄ  :) }
Var Temp : PMessage;
Begin
  While Root<>nil do
    Begin
      Temp := Root;
      Root := Root^.Next;
      Dispose(Temp);
    End;
End;

{ „®Ў ў«пҐ¬ б®®ЎйҐ­Ёп ў Є®­Ґж бЇЁбЄ  }
Procedure TMessageList.Insert( P:PMessage );
Var Temp : PMessage;
Begin
  P^.Next := nil;
  if Root = nil then
    Root := P
  Else
    Begin
      Temp := Root;
      While Temp^.Next <> nil do Temp := Temp^.Next;
      Temp^.Next := P;
    End;
End;

{ “¤ «пҐ¬ бгйҐбвўго饥 б®®ЎйҐ­ЁҐ }
{ (!) …б«Ё б®®ЎйҐ­Ёп ­Ґв -> ЌЁзҐЈ® ­Ґ ¤Ґ« Ґв!!! }
Procedure TMessageList.Remove( P:PMessage );
Var Temp : PMessage;
Begin
  if P=Root then
    Root := Root^.Next
  Else
    Begin
      Temp := Root;
      While ((Temp^.Next<>P) and (Temp^.Next<>nil)) do
        Temp := Temp^.Next;
      If Temp^.Next = P then
        Begin
          Temp^.Next := P^.Next;
          Dispose(P);
        End;
    End;
End;

{ ------------- }
Constructor TPostBox.Init;
Begin
  MessageList.Init; { €­ЁжЁ «Ё§ жЁп ўбҐе ®зҐаҐ¤Ґ© }
  SendProcList.Init;
  WaitProcList.Init;
End {TPostBox.Init};

Destructor TPostBox.Done;
Begin
  MessageList.Done; { ЋвзЁбвЄ  ўбҐе ®зҐаҐ¤Ґ© }
  SendProcList.Done;
  WaitProcList.Done;
End {TPostBox.Done};

Procedure TPostBox.PutMsg( M : PMessage );
Var OldProc : Process;
Begin
  Disable_Interrupt; { ‡ ЇаҐвЁвм ЇаҐалў ­Ёп - зв®Ўл ­ б ­Ґ ЇаҐалў «Ё ў
    Їа®жҐбᥠࠡ®вл }
  MessageList.Insert(M); { „®Ў ўЁвм б®®ЎйҐ­ЁҐ ў бЇЁб®Є б®®ЎйҐ­Ё© }
  OldProc := CurProc; { Њл Ўг¤Ґ¬ ЇҐаҐЄ«оз вмбп Ё§ ⥪г饣® Їа®жҐбб  }
  SendProcList.Include(OldProc); { „®Ў ўЁ¬ ⥪гйЁ© Їа®жҐбб ў ®зҐаҐ¤м
    Ї®б« ўиЁе б®®ЎйҐ­ЁҐ }
  { ‚ Є зҐб⢥ ­®ў®Ј® Їа®жҐбб  ў®§м¬Ґ¬ ... }
  If WaitProcList.Root <> NIL Then Begin { ... ЇҐаўл© Їа®жҐбб ¦¤гйЁ© б®®ЎйҐ­ЁҐ ... }
    CurProc := WaitProcList.Root;
    WaitProcList.Exclude(CurProc); { -- ЁбЄ«оз Ґ¬ Ё§ бЇЁбЄ  -- }
  End Else Begin { ...  , Ґб«Ё Їа®жҐбб®ў ¦¤гйЁе б®®ЎйҐ­Ёп ­Ґв, в® ... }
    CurProc := Readylist.Root; { ... ЇҐаўл© Ё§ Ј®в®ўле Є ўлЇ®«­Ґ­Ёо. }
    Readylist.Exclude(CurProc); { -- ЁбЄ«оз Ґ¬ Ё§ бЇЁбЄ  -- }
  End {If};
  Transfer(OldProc, CurProc); { ЏҐаҐЄ«оз Ґ¬бп! }
  Enable_Interrupt; { ђ §аҐиЁвм ЇаҐалў ­Ёп }
End  {TPostBox.PutMsg};

Function TPostBox.GetMsg : PMessage;
Var M : Pointer;
  S,OldProc : Process;
Begin
  Disable_Interrupt; { ‡ ЇаҐй Ґ¬ ЇаҐалў ­Ёп }
  If MessageList.Root = NIL Then Begin { …б«Ё б®®ЎйҐ­Ё© ­Ґв }
    OldProc := CurProc;       { ’® Ї®¬Ґй Ґ¬ ⥪гйЁ© Їа®жҐбб }
    WaitProcList.Include(OldProc); { ў ®зҐаҐ¤м Їа®жҐбб®ў }
    CurProc := Readylist.Root;     { ¦¤гйЁе б®®ЎйҐ­Ёп }
    Readylist.Exclude(CurProc); { ...   б ¬Ё ЇҐаҐЄ«оз Ґ¬бп ў ЇҐаўл© Ё§ }
    Transfer(OldProc, CurProc); { ®бв ўиЁебп  ЄвЁў­ле Їа®жҐбб®ў }
      { ‚®§ўа й Ґ¬бп ®Ўа в­® ў нв®в Їа®жҐбб }
    Disable_Interrupt; { ‡ ЇаҐй Ґ¬ ЇаҐалў ­Ёп (¬л Ёе а §аҐиЁ«Ё ў Transfer) }
  End {If};
  M := MessageList.Root; { €§ў«ҐЄ Ґ¬ ЇҐаў®Ґ б®®ЎйҐ­ЁҐ Ё§ бЇЁбЄ  б®®ЎйҐ­Ё© }
  MessageList.Remove(M);
  GetMsg := M;
  S := SendProcList.Root; { “ЎЁа Ґ¬ ЇҐаўл© Їа®жҐбб Ё§ бЇЁбЄ  Їа®жҐбб®ў }
  SendProcList.Exclude(S); {  Ї®б« ўйЁе б®®ЎйҐ­Ёп }
  Readylist.Include(S);
  Enable_Interrupt; { ђ §аҐи Ґ¬ ЇаҐалў ­Ёп }
End {TPostBox.GetMsg};

{ -= ‡ ЄалвЁҐ ўбҐе Ї®¤бЁб⥬ =- }
Procedure Free_All_Subsystems;
Begin
  ReadyList.Done;
  DelayList.Done;
  KillList.Done;
  Dispose(CurProc,Done);
  {}
  Writeln('„®бвгЇ­® Ї ¬пвЁ ў Є®­жҐ: ',MemAvail);
End;

Begin
  New(main);
  {}
  ClrScr;
  Writeln('„®бвгЇ­® Ї ¬пвЁ ў ­ з «Ґ: ',MemAvail);
  {}
  ReadyList.Init;
  DelayList.Init;
  KillList.Init;
  {}
  ReadyList.Add_New_Process(Idler); { „®Ў ў«пҐ¬ Їгбв®© Їа®жҐбб ў ®зҐаҐ¤м
    Ј®в®ўле. Њ®¦­® г­Ёз⮦Ёвм ўбҐ Ї®«м§®ў вҐ«мбЄЁҐ Їа®жҐббл, ­® ®зҐаҐ¤м
    Ј®в®ўле Є ЁбЇ®«­Ґ­Ёо Їа®жҐбб®ў ­ЁЄ®Ј¤  ­Ґ ¤®«¦­  Ўлвм Їгбв®© (¬Ґ­Ґ¤¦Ґаг
    Їа®жҐбб®ў ­ ¤® б 祬-в® ЁЈа вмбп). Idler Ўг¤Ґв ўбҐЈ¤  ў ®зҐаҐ¤Ё Ј®в®ўле Є
    ЁбЇ®«­Ґ­Ёо }
End {Corout}.
Соседние файлы в папке lab_5_1