// Sun Mar 12 18:16:51 CET 2000 // Dinko Korunic, 0036355514, kreator@fly.srk.fer.hr // Vjezba broj 1 iz predmeta Operacijski sustavi 1 // Simuliranje komuniciranja jezgre i procesa sa signalima // te analogije sa doticnim na razini procesora // Opis rjesenja: // Napisan je program koji koristi funkcije sigset, sigrelse, sighold // i time. Za cekanje potrebnih broj sekundi (10) koristi se funkcija // time. Omogucavanje prekida vrsi se sa instrukcijom sigrelse, a // zabranjivanje prekida sa sighold. Prekidna rutina sadrzi ispis // pocetka izvrsavanja, kod koji ceka odredjen broj sekundi i ispis // zavrsetka izvrsavanja. #include #include #include #include // kludge za Unix98 nacin koristenja signala i Linux glibc2.1 extern "C" { extern int sighold __P ((int __sig)); extern int sigrelse __P ((int __sig)); } #define N 10 // broj razina prekida // sleep kludge void MySleep (unsigned int Seconds) { while ((Seconds=sleep(Seconds))); } // klasa u kojoj ce se nalaziti potrebni i podaci i funkcije. class Prekid { // polja u kojima ce se nalaziti flagovi potrebni za rad int OznakaCekanja[N]; int Prioritet[N]; int TekuciPrioritet; // funkcija za obradu prekida void ObradaPrekida(int Nivo) { cout << "Poceo obradu prekida " << Nivo << endl; MySleep(2); cout << "Zavrsio obradu prekida " << Nivo << endl; } public: // konstruktor kojime se osiguram da je tekuci prioritet najnizi Prekid(int i=0) : TekuciPrioritet(i) {}; // prekidna rutina sa potrebnim petljama i baratanjem signalima void *PrekidnaRutina(int Signal) { // ulaz u rutinu, zaustavi signale sighold(Signal); time_t Vrijeme=time(NULL); cout << "Vrijeme je " << ctime(&Vrijeme) << "Upisi razinu prekida "; int Nivo=N; for (;Nivo>N-1 || Nivo<0;) cin >> Nivo; // ovo mi pak sluzi za vishe poziva istog nivoa! OznakaCekanja[Nivo]++; int j=N-1; // obradi sve moguce razine, slijedno po visini while(j>=0) { // radi samo nesto ceka i ako je prioritet // veci od doticnog prioriteta if (OznakaCekanja[j] && j>TekuciPrioritet) { // smanji ili obrisi prioritet // te zapisi trenutni prioritet // zbog prekida OznakaCekanja[j]--; Prioritet[j]=TekuciPrioritet; TekuciPrioritet=j; // dozvoli, obradi, zabrani prekide // vrti se u petlji.. sigrelse(Signal); ObradaPrekida(j); sighold(Signal); TekuciPrioritet=Prioritet[j]; j=N-1; } else j--; } sigrelse(Signal); return NULL; } }; // wrapper funkcija i globalni objekt koji mi sluzi da mi se funkcija // moze `sjetiti' objekta.. Prekid MojPrekid; void PrekidMemberFunctionWrapper(int Signal) { signal(SIGINT, PrekidMemberFunctionWrapper); MojPrekid.PrekidnaRutina(Signal); } // main, u kojem cemo postaviti signal handler i vrtiti se u prazno int main(void) { signal(SIGINT, PrekidMemberFunctionWrapper); // sigset(SIGINT, PrekidMemberFunctionWrapper); cout << "Poceo osnovni program" << endl; MySleep(15); cout << "Zavrsio osnovni program" << endl; return 0; }