Vježba 1: Prekidi i signali

Operacijski sustav ne dozvoljava pojedinom korisniku izravno korištenje prekida procesora. Stoga prekide treba simulirati koristeći signale koje jezgra operacijskog sustava šalje procesima.

Zadatak

Napisati program obrada.py koji omogućava obradu prekida s više razina/prioriteta (simulira ponašanje sustava opisanog u 3. poglavlju i to bez sklopa za prihvat prekida).

Struktura prekidne rutine dana je sljedećim pseudokodom:

prekidna_rutina  /* pokreće se pojavom signala */
	odredi uzrok prekida, tj. indeks i
	OZNAKA_ČEKANJA[i] = 1
	dok je i > TEKUĆI_PRIORITET
		OZNAKA_ČEKANJA[i] = 0
		PRIORITET[i] = TEKUĆI_PRIORITET
		TEKUĆI_PRIORITET = i
		obrada_prekida(i)
		TEKUĆI_PRIORITET = PRIORITET[i]
		i = 0
		za j = TEKUĆI_PRIORITET + 1 do N radi
			ako je OZNAKA_ČEKANJA[j]<>0 tada
				i = j

UPUTA

Za simulaciju prekida različita prioriteta koristiti signal SIGINT (Ctrl+C) te na početku prihvata signala ručno upisivati prioritet simuliranog prekida.

Predložak i pomoćne funkcije za ispis (sig-win.py):

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import time, signal, sys

TEKUCI_PRIORITET = 0
PRIORITET = [0,0,0,0,0,0]
OZNAKA_CEKANJA = [0,0,0,0,0,0]

def ispisi_pojavu_signala(prioritet): # prioritet u rangu 1-5
	print('\t' + '- ' * prioritet + 'X ' + '- ' * (5-prioritet))
def ispisi_pocetak_obrade_signala(prioritet):
	print('\t' + '- ' * prioritet + 'P ' + '- ' * (5-prioritet))
def ispisi_kraj_obrade_signala(prioritet):
	print('\t' + '- ' * prioritet + 'K ' + '- ' * (5-prioritet))
def ispisi_korak_obrade_signala(prioritet, korak):
	print('\t' + '- ' * prioritet + str(korak) + ' ' + '- ' * (5-prioritet))
def ispisi_korak_obrade_glavnog_programa(korak):
	print('\t' + str(korak%10) + ' -' * 5)

def simulacija_obrade_prekida(prioritet):
	ispisi_pocetak_obrade_signala(prioritet)
	for korak in range(1,6):
		ispisi_korak_obrade_signala(prioritet, korak)
		time.sleep(1)
	ispisi_kraj_obrade_signala(prioritet)

def prekidna_rutina(signal, frame):
	global TEKUCI_PRIORITET
	i = int(input("Unesi prioritet prekida: "))
	if i == 10:
		print("\nZavršavam rad")
		sys.exit(1)

	ispisi_pojavu_signala(i)
	OZNAKA_CEKANJA[i] = 1;

	# ostatak koda prema gornjem pseudokodu
	# ...
	simulacija_obrade_prekida(i)
	# ...

def main():
	print("\tG 1 2 3 4 5")

	signal.signal(signal.SIGINT, prekidna_rutina)

	for korak in range(100):
		ispisi_korak_obrade_glavnog_programa(korak)
		time.sleep(1)

if __name__ == "__main__":
	main()
Primjer rada s ispisom poziva funkcija i gniježđenja
Ispis		Funkcije
-------------------------
G 1 2 3 4 5	main
0 - - - - -	main
1 - - - - -	main
2 - - - - -	main
3 - - - - -	main
4 - - - - -	main
Unesi...: 3	main=>SIGINT=>prekidna_rutina
- - - X - -	main=>SIGINT=>prekidna_rutina->ispisi_pojavu_signala
- - - P - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - 1 - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - 2 - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
Unesi...: 5	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina
- - - - - X	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->ispisi_pojavu_signala
- - - - - P	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - - - 1	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - - - 2	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - - - 3	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
Unesi...: 2	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina
- - X - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->ispisi_pojavu_signala
- - - - - 4	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - - - 5	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - - - K	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - 3 - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - 4 - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - 5 - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - - K - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - P - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - 1 - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - 2 - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - 3 - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - 4 - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - 5 - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
- - K - - -	main=>SIGINT=>prekidna_rutina->simulacija_obrade_prekida
5 - - - - -	main
6 - - - - -	main