emit 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/README.md +1 -0
- data/benchmarks/choice.rb +22 -0
- data/benchmarks/commstime.rb +1 -1
- data/benchmarks/deadlock.rb +14 -0
- data/benchmarks/starvation.rb +2 -4
- data/lib/emit.rb +7 -6
- data/lib/emit/alternation.rb +19 -27
- data/lib/emit/input_guard.rb +14 -5
- data/lib/emit/output_guard.rb +15 -6
- data/lib/emit/version.rb +1 -1
- metadata +4 -4
- data/benchmarks/select.rb +0 -30
- data/lib/emit/choice.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: a43400e02ac71c9a0c9568be319833e69c9e0b18
|
4
|
+
data.tar.gz: b28b6b8e6a01ef1b84e6e5fa797e5c404e387012
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c0597efaa0e69f35a94244698b5b038788e5210c780166af65068e254c04e47c3fa6717d215e680dde058167f63b7b264d2ab0de00a6b9b344974d0109023609
|
7
|
+
data.tar.gz: 68af9bef63afdce8f990890fd4a55dae5e3fe6cf0df86449d17a4c17bd8c603d962b5b0cb922d6851de3f84f36ea8b62cc5f40ee4602459b2754e720a391b0f8
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -0,0 +1,22 @@
|
|
1
|
+
require "emit"
|
2
|
+
|
3
|
+
$result = []
|
4
|
+
|
5
|
+
def selector(cin1, cin2, n)
|
6
|
+
n.times do
|
7
|
+
_, msg = Emit.choice(cin1, cin2)
|
8
|
+
$result << msg
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
ch1 = Emit.channel
|
13
|
+
ch2 = Emit.channel
|
14
|
+
|
15
|
+
n = 100
|
16
|
+
Emit.parallel(
|
17
|
+
Emit.process { n.times { -ch1 << 0 } },
|
18
|
+
Emit.process { n.times { -ch2 << 1 } },
|
19
|
+
Emit.selector(+ch1, +ch2, 2*n)
|
20
|
+
)
|
21
|
+
|
22
|
+
puts $result.inspect
|
data/benchmarks/commstime.rb
CHANGED
data/benchmarks/starvation.rb
CHANGED
data/lib/emit.rb
CHANGED
@@ -16,11 +16,10 @@ require "emit/input_guard"
|
|
16
16
|
require "emit/output_guard"
|
17
17
|
|
18
18
|
require "emit/alternation"
|
19
|
-
require "emit/choice"
|
20
19
|
|
21
20
|
module Emit
|
22
21
|
class << self
|
23
|
-
def parallel(*processes)
|
22
|
+
def parallel(*processes, run: true)
|
24
23
|
processes.flatten!
|
25
24
|
|
26
25
|
processes.each do |process|
|
@@ -28,8 +27,10 @@ module Emit
|
|
28
27
|
Scheduler.enqueue(process)
|
29
28
|
end
|
30
29
|
|
31
|
-
|
32
|
-
|
30
|
+
if run
|
31
|
+
Scheduler.join(processes)
|
32
|
+
processes.map(&:return_value)
|
33
|
+
end
|
33
34
|
end
|
34
35
|
|
35
36
|
def sequence(*processes)
|
@@ -52,8 +53,8 @@ module Emit
|
|
52
53
|
channel_ends.each(&:retire)
|
53
54
|
end
|
54
55
|
|
55
|
-
def
|
56
|
-
Alternation.new(guards
|
56
|
+
def choice(*guards)
|
57
|
+
Alternation.new(guards).execute
|
57
58
|
end
|
58
59
|
|
59
60
|
def method_missing(name, *args, **kwargs)
|
data/lib/emit/alternation.rb
CHANGED
@@ -1,30 +1,26 @@
|
|
1
1
|
module Emit
|
2
2
|
class Alternation
|
3
3
|
def initialize(guards)
|
4
|
-
@guards = guards
|
4
|
+
@guards = guards.map do |guard|
|
5
|
+
case guard
|
6
|
+
when InputGuard then guard
|
7
|
+
when OutputGuard then guard
|
8
|
+
else
|
9
|
+
InputGuard.new(guard)
|
10
|
+
end
|
11
|
+
end
|
5
12
|
end
|
6
13
|
|
7
14
|
def execute
|
8
15
|
idx, request, channel, operation = choose
|
9
16
|
|
10
17
|
if @guards[idx]
|
11
|
-
action = @guards[idx].
|
18
|
+
action = @guards[idx].action
|
19
|
+
fail "Failed executing action in alternation." unless [Proc, Method].include?(action.class)
|
12
20
|
|
13
|
-
case
|
14
|
-
when
|
15
|
-
|
16
|
-
when :write then action.invoke_on_output
|
17
|
-
when :read then action.invoke_on_input(request.message)
|
18
|
-
end
|
19
|
-
when Proc, Method
|
20
|
-
case operation
|
21
|
-
when :write then action.()
|
22
|
-
when :read then action.(message: request.message)
|
23
|
-
end
|
24
|
-
when nil
|
25
|
-
# no-op
|
26
|
-
else
|
27
|
-
fail "Failed executing action: #{action}."
|
21
|
+
case operation
|
22
|
+
when :write then action.()
|
23
|
+
when :read then action.(request.message)
|
28
24
|
end
|
29
25
|
end
|
30
26
|
|
@@ -36,29 +32,25 @@ module Emit
|
|
36
32
|
def choose
|
37
33
|
requests = {}
|
38
34
|
act = nil
|
39
|
-
poison = false
|
40
|
-
retire = false
|
41
35
|
|
42
36
|
Scheduler.current.state = :active
|
43
37
|
|
44
38
|
begin
|
45
39
|
idx = 0
|
46
40
|
@guards.each do |guard|
|
47
|
-
if
|
41
|
+
if OutputGuard === guard
|
48
42
|
operation = :write
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
elsif guard.size == 2 # read
|
43
|
+
request = ChannelRequest.new(Scheduler.current, guard.message)
|
44
|
+
guard.channel_end.send(:post_write, request)
|
45
|
+
elsif InputGuard === guard
|
53
46
|
operation = :read
|
54
|
-
channel, action = guard
|
55
47
|
request = ChannelRequest.new(Scheduler.current)
|
56
|
-
|
48
|
+
guard.channel_end.send(:post_read, request)
|
57
49
|
else
|
58
50
|
fail "Guard was neither write or read."
|
59
51
|
end
|
60
52
|
|
61
|
-
requests[request] = [idx,
|
53
|
+
requests[request] = [idx, guard.channel_end, operation]
|
62
54
|
idx += 1
|
63
55
|
end
|
64
56
|
rescue ChannelPoisonedException, ChannelRetiredException
|
data/lib/emit/input_guard.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
module Emit
|
2
2
|
class InputGuard
|
3
|
-
attr_reader :
|
3
|
+
attr_reader :channel_end, :action
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(argument, action=->(msg) {msg})
|
6
|
+
case argument
|
7
|
+
when InputGuard
|
8
|
+
@channel_end, @action = argument.channel_end, argument.action
|
9
|
+
when ChannelEndRead
|
10
|
+
@channel_end, @action = argument, action
|
11
|
+
when Array
|
12
|
+
fail "Wrong number of arguments" unless argument.size == 2
|
13
|
+
@channel_end, @action = argument
|
8
14
|
else
|
9
|
-
fail "
|
15
|
+
fail "Unknown input guard type"
|
10
16
|
end
|
17
|
+
|
18
|
+
fail "InputGuard must have a reading channel end." unless ChannelEndRead === @channel_end
|
19
|
+
fail "InputGuard action cannot be nil" if @action.nil?
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
data/lib/emit/output_guard.rb
CHANGED
@@ -1,13 +1,22 @@
|
|
1
1
|
module Emit
|
2
|
-
class
|
3
|
-
attr_reader :
|
2
|
+
class OutputGuard
|
3
|
+
attr_reader :channel_end, :message, :action
|
4
4
|
|
5
|
-
def initialize(
|
6
|
-
|
7
|
-
|
5
|
+
def initialize(argument, message, action=nil)
|
6
|
+
case argument
|
7
|
+
when OutputGuard
|
8
|
+
@channel_end, @message, @action = argument.channel_end, argument.message, argument.action
|
9
|
+
when ChannelEndWrite
|
10
|
+
@channel_end, @message, @action = argument, message, action
|
11
|
+
when Array
|
12
|
+
fail "Wrong number of arguments" unless argument.size == 3
|
13
|
+
@channel_end, @message, @action = argument
|
8
14
|
else
|
9
|
-
fail "
|
15
|
+
fail "Unknown output guard type"
|
10
16
|
end
|
17
|
+
|
18
|
+
fail "OutputGuard must have a writing channel end." unless ChannelEndWrite === channel_end
|
19
|
+
fail "OutputGuard action cannot be nil" if @action.nil?
|
11
20
|
end
|
12
21
|
end
|
13
22
|
end
|
data/lib/emit/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: emit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Mads Ohm Larsen
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05
|
11
|
+
date: 2018-12-05 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -66,10 +66,11 @@ files:
|
|
66
66
|
- LICENSE.txt
|
67
67
|
- README.md
|
68
68
|
- Rakefile
|
69
|
+
- benchmarks/choice.rb
|
69
70
|
- benchmarks/commstime.rb
|
71
|
+
- benchmarks/deadlock.rb
|
70
72
|
- benchmarks/many_processes.rb
|
71
73
|
- benchmarks/montecarlopi.rb
|
72
|
-
- benchmarks/select.rb
|
73
74
|
- benchmarks/starvation.rb
|
74
75
|
- bin/console
|
75
76
|
- bin/setup
|
@@ -81,7 +82,6 @@ files:
|
|
81
82
|
- lib/emit/channel_end_read.rb
|
82
83
|
- lib/emit/channel_end_write.rb
|
83
84
|
- lib/emit/channel_request.rb
|
84
|
-
- lib/emit/choice.rb
|
85
85
|
- lib/emit/exceptions.rb
|
86
86
|
- lib/emit/input_guard.rb
|
87
87
|
- lib/emit/output_guard.rb
|
data/benchmarks/select.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
require "emit"
|
2
|
-
|
3
|
-
@result = []
|
4
|
-
def action(message: nil)
|
5
|
-
@result << message
|
6
|
-
end
|
7
|
-
|
8
|
-
def p1(cout, n)
|
9
|
-
n.times { |i| cout << i }
|
10
|
-
end
|
11
|
-
|
12
|
-
def p2(cin1, cin2, n)
|
13
|
-
n.times do
|
14
|
-
Emit.select(
|
15
|
-
Emit::InputGuard.new(cin1, action: method(:action)),
|
16
|
-
Emit::InputGuard.new(cin2, action: method(:action))
|
17
|
-
)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
ch1 = Emit.channel
|
22
|
-
ch2 = Emit.channel
|
23
|
-
|
24
|
-
Emit.parallel(
|
25
|
-
Emit.process(-ch1, 50, &method(:p1)),
|
26
|
-
Emit.process(-ch2, 50, &method(:p1)),
|
27
|
-
Emit.process(+ch1, +ch2, 100, &method(:p2))
|
28
|
-
)
|
29
|
-
|
30
|
-
puts @result.inspect
|
data/lib/emit/choice.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Emit
|
2
|
-
class Choice
|
3
|
-
def initialize(*args, **kwargs, &block)
|
4
|
-
@block = block
|
5
|
-
@args = args
|
6
|
-
@kwargs = kwargs
|
7
|
-
end
|
8
|
-
|
9
|
-
def invoke_on_output
|
10
|
-
@block.call(*@args, **@kwargs)
|
11
|
-
end
|
12
|
-
|
13
|
-
def invoke_on_input(message)
|
14
|
-
@kwargs[:message] = message
|
15
|
-
@block.call(*@args, **@kwargs)
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|