diff --git a/flake.nix b/flake.nix index 6293139..b4d3ac1 100644 --- a/flake.nix +++ b/flake.nix @@ -36,6 +36,7 @@ swiProlog gnu-smalltalk zip + julia_19-bin ]; }; } diff --git a/lab4/zad1/.gitignore b/lab4/zad1/.gitignore new file mode 100644 index 0000000..5866d7b --- /dev/null +++ b/lab4/zad1/.gitignore @@ -0,0 +1,4 @@ +/obj/ +/bin/ +/alire/ +/config/ diff --git a/lab4/zad1/alire.toml b/lab4/zad1/alire.toml new file mode 100644 index 0000000..84f22d8 --- /dev/null +++ b/lab4/zad1/alire.toml @@ -0,0 +1,9 @@ +name = "zad1" +description = "" +version = "0.1.0-dev" + +authors = ["poz"] +maintainers = ["poz "] +maintainers-logins = ["jacekpoz"] + +executables = ["zad1"] diff --git a/lab4/zad1/src/main.adb b/lab4/zad1/src/main.adb new file mode 100644 index 0000000..1343529 --- /dev/null +++ b/lab4/zad1/src/main.adb @@ -0,0 +1,55 @@ +with Ada.Numerics.Float_Random; use Ada.Numerics.Float_Random; +with Ada.Text_IO; use Ada.Text_IO; + +procedure Main is + protected type Fork is + entry Grab; + procedure Put_Down; + private + Seized : Boolean := False; + end Fork; + + protected body Fork is + entry Grab when not Seized is + begin + Seized := True; + end Grab; + + procedure Put_Down is + begin + Seized := False; + end Put_Down; + end Fork; + + Life_Span : constant := 20; + + task type Person (ID : Positive; First, Second : not null access Fork); + + task body Person is + Dice : Generator; + begin + Reset (Dice); + for Life_Cycle in 1..Life_Span loop + Put_Line ("Philosopher" & Positive'Image (ID) & " is thinking"); + delay Duration (Random (Dice) * 0.100); + Put_Line ("Philosopher" & Positive'Image (ID) & " is hungry"); + First.Grab; + Second.Grab; + Put_Line ("Philosopher" & Positive'Image (ID) & " is eating"); + delay Duration (Random (Dice) * 0.100); + Second.Put_Down; + First.Put_Down; + end loop; + Put_Line ("Philosopher" & Positive'Image (ID) & " is leaving"); + end Person; + + Forks : array (1..5) of aliased Fork; + + Ph_1 : Person (1, Forks (1)'Access, Forks (2)'Access); + Ph_2 : Person (2, Forks (2)'Access, Forks (3)'Access); + Ph_3 : Person (3, Forks (3)'Access, Forks (4)'Access); + Ph_4 : Person (4, Forks (4)'Access, Forks (5)'Access); + Ph_5 : Person (5, Forks (1)'Access, Forks (5)'Access); +begin + null; +end Main; diff --git a/lab4/zad1/zad1.gpr b/lab4/zad1/zad1.gpr new file mode 100644 index 0000000..6dd5483 --- /dev/null +++ b/lab4/zad1/zad1.gpr @@ -0,0 +1,22 @@ +with "config/zad1_config.gpr"; +project Zad1 is + + for Source_Dirs use ("src/", "config/"); + for Object_Dir use "obj/" & Zad1_Config.Build_Profile; + for Create_Missing_Dirs use "True"; + for Exec_Dir use "bin"; + for Main use ("main.adb"); + + package Compiler is + for Default_Switches ("Ada") use Zad1_Config.Ada_Compiler_Switches; + end Compiler; + + package Binder is + for Switches ("Ada") use ("-Es"); -- Symbolic traceback + end Binder; + + package Install is + for Artifacts (".") use ("share"); + end Install; + +end Zad1; diff --git a/lab4/zad2/main.go b/lab4/zad2/main.go new file mode 100644 index 0000000..9a7eb24 --- /dev/null +++ b/lab4/zad2/main.go @@ -0,0 +1,69 @@ +package main + +import ( + "hash/fnv" + "math/rand" + "sync" + "time" + "fmt" +) + +const hunger = 20 +const think = time.Second / 10 +const eat = time.Second / 10 + +var dining sync.WaitGroup + +func philosopher(name string, leftFork, rightFork *sync.Mutex) { + fmt.Println(name, "seated") + + h := fnv.New64a() + h.Write([]byte(name)) + rg := rand.New(rand.NewSource(int64(h.Sum64()))) + + sleepRand := func(t time.Duration) { + time.Sleep(t/2 + time.Duration(rg.Int63n(int64(t)))) + } + + for h := hunger; h > 0; h-- { + fmt.Println(name, "is hungry") + leftFork.Lock() + rightFork.Lock() + + fmt.Println(name, "is eating") + sleepRand(eat) + + leftFork.Unlock() + rightFork.Unlock() + + fmt.Println(name, "is thinking") + sleepRand(think) + } + + fmt.Println(name, "finished eating") + + dining.Done() + + fmt.Println(name, "left the table") +} + +func main() { + fmt.Println("table empty") + + dining.Add(5) + + fork0 := &sync.Mutex{} + leftFork := fork0 + + for i := 1; i < 5; i++ { + rightFork := &sync.Mutex{} + go philosopher(fmt.Sprintf("Philosopher %d", i), leftFork, rightFork) + leftFork = rightFork + } + + go philosopher("Philosopher 1", fork0, leftFork) + + dining.Wait() + + fmt.Println("table empty") +} diff --git a/lab4/zad3/main.jl b/lab4/zad3/main.jl new file mode 100644 index 0000000..e19b7f6 --- /dev/null +++ b/lab4/zad3/main.jl @@ -0,0 +1,95 @@ +mutable struct Philosopher + name::String + righthanded::Bool + rightfork::Channel + leftfork::Channel + + function Philosopher(name, leftfork, rightfork, righthanded) + this = new() + this.name = name + this.righthanded = righthanded + this.leftfork = leftfork + this.rightfork = rightfork + this + end +end + +mutable struct Table + fork0::Channel + fork1::Channel + fork2::Channel + fork3::Channel + fork4::Channel + function Table() + this = new() + this.fork0 = Channel(1) + put!(this.fork0, "fork") + + this.fork1 = Channel(1) + put!(this.fork1, "fork") + + this.fork2 = Channel(1) + put!(this.fork2, "fork") + + this.fork3 = Channel(1) + put!(this.fork3, "fork") + + this.fork4 = Channel(1) + put!(this.fork4, "fork") + this + end +end + +table = Table(); +tasks = [ + Philosopher("Philosopher 1", table.fork0, table.fork1, false), + Philosopher("Philosopher 2", table.fork1, table.fork2, true), + Philosopher("Philosopher 3", table.fork2, table.fork3, true), + Philosopher("Philosopher 4", table.fork3, table.fork4, true), + Philosopher("Philosopher 5", table.fork4, table.fork0, true) +] + +hunger = 20 +thinktime = 0.1 +eattime = 0.1 + +function philosopher(p, t) + println("$(p.name) has seated") + for _ in hunger:-1:0 + println("$(p.name) is hungry") + + if p.righthanded + take!(p.rightfork); + take!(p.leftfork); + else + take!(p.leftfork); + take!(p.rightfork); + end + + println("$(p.name) is eating") + sleep(eattime * rand()) + + put!(p.rightfork, "fork") + put!(p.leftfork, "fork") + + println("$(p.name) is thinking") + sleep(thinktime * rand()) + end + println("$(p.name) is satisfied") + + println("$(p.name) left the table") +end + +function runall(tasklist) + c = Condition() + + for p in tasklist + @async (philosopher(p, table); notify(c)) + end + + for p in tasklist + wait(c) + end +end + +runall(tasks)