154 lines
3.1 KiB
Tcl
154 lines
3.1 KiB
Tcl
source symul_lib.tcl
|
|
|
|
# 8 wierzchołków
|
|
set liczbaWierz 8
|
|
|
|
#tworzę graf pełny
|
|
iterate i $liczbaWierz {
|
|
set check 0
|
|
|
|
# przechodzę przez wszystkie wierzchołki
|
|
# {start} {test} {next}
|
|
for {set j 0} {$j < $liczbaWierz} {incr j} {
|
|
|
|
# jeśli dany wierzchołek nie jest równy sprawdzanemu
|
|
if {$i!=$j} {
|
|
|
|
# jeśli check = 0
|
|
if {$check==0} {
|
|
set s "$j"
|
|
set check 1
|
|
|
|
# jeśli nie
|
|
} else {
|
|
set x1 $s
|
|
set x2 $j
|
|
set s "$x1 $x2"
|
|
}
|
|
}
|
|
}
|
|
set sasiedzi($i) "$s"
|
|
}
|
|
|
|
#definicja wierzchołka
|
|
fiber create $liczbaWierz {
|
|
set king 1;
|
|
set K $id_los;
|
|
set KS 1;
|
|
set waiting "";
|
|
dostarcz 0 "Collect $id_los";
|
|
|
|
|
|
while {$run} {
|
|
for {set i 0} {$i < $stopien} {incr i} {
|
|
|
|
#lindex pobiera indeks z listy
|
|
set x [lindex $kom($i) 0]
|
|
|
|
#jeśli x[0] == Collect
|
|
if {[lindex $x 0]=="Collect"} {
|
|
if {$K==""} {
|
|
set K $i
|
|
set KS 1
|
|
set king 0
|
|
dostarcz $i "Join";
|
|
czytaj $i
|
|
} elseif {$king==1} {
|
|
if {$K<[lindex $x 1]} {
|
|
set king 0
|
|
set K $i
|
|
set KS 1
|
|
dostarcz $i "Join";
|
|
}
|
|
czytaj $i
|
|
} elseif {$waiting==""} {
|
|
if {$id_los < [lindex $x 1]} {
|
|
set waiting $i
|
|
dostarcz $K "Check [lindex $x 1]"
|
|
}
|
|
czytaj $i
|
|
}
|
|
}
|
|
|
|
#jeśli x[0] = Check
|
|
if {[lindex $x 0]=="Check"} {
|
|
if {$K < [lindex $x 1]} {
|
|
set K ""
|
|
set KS 1
|
|
dostarcz $i "Ack"
|
|
} else {
|
|
dostarcz $i "Ref"
|
|
}
|
|
czytaj $i
|
|
}
|
|
|
|
# jeśli x[0] = Ack
|
|
if {[lindex $x 0]=="Ack"} {
|
|
set KS 1
|
|
dostarcz $waiting "Join";
|
|
set waiting ""
|
|
czytaj $i
|
|
}
|
|
|
|
#jeśli x[0] = Ref
|
|
if {[lindex $x 0]=="Ref"} {
|
|
set waiting ""
|
|
czytaj $i
|
|
}
|
|
|
|
#jeśli x[0] = Join
|
|
if {[lindex $x 0]=="Join"} {
|
|
if {$king==1} {
|
|
if {$KS < $stopien} {
|
|
dostarcz $KS "Collect $id_los";
|
|
} else {
|
|
_puts "wybrano lidera: $id_los"
|
|
}
|
|
incr KS
|
|
}
|
|
czytaj $i
|
|
}
|
|
}
|
|
fiber switchto main;
|
|
}
|
|
}
|
|
InicjalizacjaAsynch
|
|
|
|
#procedura wizalizacji
|
|
proc wizualizacja {} {
|
|
fiber_iterate {_puts "$id,$id_los, $KS, $kom0, $kom1, $kom2, $kom3, $kom4, $kom5, $kom6"}
|
|
}
|
|
|
|
#główna egzekucja
|
|
set check 0;
|
|
proc egzekucja {liczbaWierz check} {
|
|
set s ""
|
|
#expr - wylicz wartość wyrazenia
|
|
set rand [expr {int(rand()*[expr $liczbaWierz+1])}];
|
|
for {set i 0} {$i < $liczbaWierz} {incr i} {
|
|
if {$check==0} {
|
|
set x1 $s
|
|
set x2 $i
|
|
set s "$x1 $x2"
|
|
fiber switchto $i;
|
|
} elseif {$i!=$rand} {
|
|
set x1 $s
|
|
set x2 $i
|
|
set s "$x1 $x2"
|
|
fiber switchto $i;
|
|
}
|
|
}
|
|
_puts "Wierzchołki: {$s }"
|
|
}
|
|
|
|
egzekucja $liczbaWierz $check;set check 1;wizualizacja;
|
|
|
|
|
|
|
|
#5. symulacja modelu asynchronicznego:
|
|
# + generujemy "zdarzenie obliczeniowe" z konsoli przy pomocy
|
|
# fiber switchto $id
|
|
# a zdarzenie to kończy się w kodzie algorytmu przez
|
|
# fiber switchto main
|
|
# + istnieje procedura "dostarcz" działająca tak jak "wyslij"
|
|
# z tą różnicą, że komunikaty są od razu dostarczane |