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

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_7_1