Добавил:
Studfiles2
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Лабораторная работа №5 по О-Средам / lab_5_1 / COROUT
.PAS {
‚Ё¬ ЁҐ! „ п Їа®Ја ¬¬ § йЁйҐ § Є® ¬Ё ®Ў ўв®абЄЁе
Їа ў е Ё ¬Ґ¦¤г த묨 б®Ј« 襨ﬨ. ЌҐ§ Є®®Ґ
ў®бЇа®Ё§ўҐ¤ҐЁҐ Ё«Ё а бЇа®бва ҐЁҐ ¤ ®© Їа®Ја ¬¬л Ё«Ё
«оЎ®© ҐҐ з бвЁ ў«ҐзҐв Ја ¦¤ бЄго Ё гЈ®«®ўго
®вўҐб⢥®бвм ;) }
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}.
‚Ё¬ ЁҐ! „ п Їа®Ја ¬¬ § йЁйҐ § Є® ¬Ё ®Ў ўв®абЄЁе
Їа ў е Ё ¬Ґ¦¤г த묨 б®Ј« 襨ﬨ. ЌҐ§ Є®®Ґ
ў®бЇа®Ё§ўҐ¤ҐЁҐ Ё«Ё а бЇа®бва ҐЁҐ ¤ ®© Їа®Ја ¬¬л Ё«Ё
«оЎ®© ҐҐ з бвЁ ў«ҐзҐв Ја ¦¤ бЄго Ё гЈ®«®ўго
®вўҐб⢥®бвм ;) }
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}.