Skip to content

Instantly share code, notes, and snippets.

@jocelyn
Last active October 31, 2016 14:28
Show Gist options
  • Select an option

  • Save jocelyn/bbb3091d064a461c5de877e4c58b4c6f to your computer and use it in GitHub Desktop.

Select an option

Save jocelyn/bbb3091d064a461c5de877e4c58b4c6f to your computer and use it in GitHub Desktop.
Example of SCOOP pool.
note
description: "[
Enter class description here!
]"
class
APP
create
make
feature {NONE} -- Initialization
make
-- Instantiate Current object.
local
pool: separate CONCURRENT_POOL [APP_JOB]
fac: separate APP_JOB_FACTORY
i: INTEGER
do
create pool.make (pool_capacity)
create fac
from
i := 1
until
i > job_count
loop
if attached new_job (pool, fac) as l_item then
process_job (l_item, i)
end
i := i + 1
end
end
feature -- Access
pool_capacity: INTEGER = 5
job_count: INTEGER = 25
job_loop_count: INTEGER = 100
feature -- Execution
new_job (a_pool: separate CONCURRENT_POOL [APP_JOB]; fac: separate APP_JOB_FACTORY): detachable separate APP_JOB
require
wait_for_available_processor: not a_pool.is_full -- SCOOP Wait on condition!
do
Result := a_pool.separate_item (fac)
end
process_job (a_job: separate APP_JOB; i: INTEGER)
do
a_job.set_parameters ("Job #" + i.out, job_loop_count)
a_job.execute
end
end
note
description: "Summary description for {APP_JOB}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
APP_JOB
inherit
CONCURRENT_POOL_ITEM
SHARED_EXECUTION_ENVIRONMENT
create
make
feature
make (a_id: INTEGER)
do
id := a_id
name := ""
end
feature -- Access
id: INTEGER
name: STRING
iteration_number: INTEGER
feature -- Execution
set_parameters (a_name: separate STRING; a_iteration_number: INTEGER)
do
iteration_number := a_iteration_number
create name.make_from_separate (a_name)
end
execute
local
i: INTEGER
s: STRING
do
s := name
from
i := 1
until
i > iteration_number
loop
print ("[Proc#" + id.out + "] -> " + s + " i_th=" + i.out + "%N")
execution_environment.sleep (100_000)
i := i + 1
end
release
end
end
note
description: "Summary description for {APP_JOB_FACTORY}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
APP_JOB_FACTORY
inherit
CONCURRENT_POOL_FACTORY [APP_JOB]
feature -- Factory
new_separate_item: separate APP_JOB
do
create Result.make (new_id)
end
new_id: INTEGER
do
Result := counter + 1
counter := Result
end
counter: INTEGER
end
note
description: "Concurrent pool for SCOOP concurrency mode."
date: "$Date$"
revision: "$Revision$"
class
CONCURRENT_POOL [G -> CONCURRENT_POOL_ITEM]
create
make
feature {NONE} -- Initialization
make (n: INTEGER)
do
capacity := n
create items.make_empty (n)
create busy_items.make_empty (n)
set_count (n)
end
feature -- Access
count: INTEGER
-- Number of concurrent items managed by Current pool.
capacity: INTEGER
-- Maximum number of concurrent items managed by Current pool.
feature -- Status report
is_full: BOOLEAN
-- Pool is full?
do
Result := count >= capacity
end
is_empty: BOOLEAN
-- No concurrent item waiting in current pool.
do
Result := count = 0
end
stop_requested: BOOLEAN
-- Current pool received a request to terminate.
feature -- Access
separate_item (a_factory: separate CONCURRENT_POOL_FACTORY [G]): detachable separate G
-- Reused, or new separate item of type {G} created by `a_factory'.
require
is_not_full: not is_full
local
i,n,pos: INTEGER
lst: like busy_items
l_item: detachable separate G
do
if not stop_requested then
from
lst := busy_items
pos := -1
i := 0
n := lst.count - 1
until
i > n or l_item /= Void or pos >= 0
loop
if not lst [i] then -- is free (i.e not busy)
pos := i
if items.valid_index (pos) then
l_item := items [pos]
if l_item /= Void then
busy_items [pos] := True
end
end
if l_item = Void then
-- Empty, then let's create one.
l_item := a_factory.new_separate_item
register_item (l_item)
items [pos] := l_item
end
end
i := i + 1
end
if l_item = Void then
-- Pool is FULL ...
check overcapacity: False end
else
debug ("pool", "dbglog")
dbglog ("Lock pool item #" + pos.out + " (free:"+ (capacity - count).out +"))")
end
count := count + 1
busy_items [pos] := True
Result := l_item
a_factory.update_item (l_item)
end
end
end
feature -- Basic operation
gracefull_stop
-- Request the Current pool to terminate.
do
stop_requested := True
end
feature {NONE} -- Internal
dbglog (m: READABLE_STRING_8)
do
io.error.put_string (m + "%N")
end
items: SPECIAL [detachable separate G]
-- List of concurrent items.
busy_items: SPECIAL [BOOLEAN]
-- Map of items being proceed.
feature {CONCURRENT_POOL_ITEM} -- Change
release_item (a_item: separate G)
-- Unregister `a_item' from Current pool.
require
count > 0
local
i,n,pos: INTEGER
lst: like items
do
-- release handler for reuse
from
lst := items
i := 0
n := lst.count - 1
until
i > n or lst [i] = a_item
loop
i := i + 1
end
if i <= n then
pos := i
busy_items [pos] := False
count := count - 1
--reuse items [pos] := Void
debug ("pool", "dbglog")
dbglog ("Released pool item #" + i.out + " (free:"+ (capacity - count).out +"))")
end
else
check known_item: False end
end
end
feature -- Change
set_count (n: INTEGER)
-- Set capacity of Current pool to `n'.
local
g: detachable separate G
do
capacity := n
items.fill_with (g, 0, n - 1)
busy_items.fill_with (False, 0, n - 1)
end
terminate
-- Terminate current pool.
local
l_items: like items
do
l_items := items
l_items.wipe_out
end
feature {NONE} -- Implementation
register_item (a_item: separate G)
-- Adopt `a_item' in current pool.
do
a_item.set_pool (Current)
end
note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end
note
description: "Factory in charge of creating new concurrent pool item."
date: "$Date$"
revision: "$Revision$"
deferred class
CONCURRENT_POOL_FACTORY [G -> CONCURRENT_POOL_ITEM]
feature -- Access
update_item (a_item: separate G)
-- Update `a_item' for optionally purpose.
do
end
new_separate_item: separate G
-- New separated object of type {G}.
deferred
end
note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end
note
description: "[
Item create by the CONCURRENT_POOL_FACTORY, and managed by the CONCURRENT_POOL
for SCOOP concurrency mode.
]"
date: "$Date$"
revision: "$Revision$"
deferred class
CONCURRENT_POOL_ITEM
feature {NONE} -- Access
pool: detachable separate CONCURRENT_POOL [CONCURRENT_POOL_ITEM]
-- Associated concurrent pool component.
feature {CONCURRENT_POOL} -- Change
set_pool (p: like pool)
-- Set associated `pool' to `p'.
do
pool := p
end
feature {CONCURRENT_POOL} -- Basic operation
release
-- Release Current pool item from associated pool.
do
if attached pool as p then
pool_release (p)
end
end
feature {NONE} -- Implementation
pool_release (p: separate CONCURRENT_POOL [CONCURRENT_POOL_ITEM])
do
p.release_item (Current)
end
note
copyright: "2011-2016, Jocelyn Fiat, Javier Velilla, Eiffel Software and others"
license: "Eiffel Forum License v2 (see http://www.eiffel.com/licensing/forum.txt)"
source: "[
Eiffel Software
5949 Hollister Ave., Goleta, CA 93117 USA
Telephone 805-685-1006, Fax 805-685-6869
Website http://www.eiffel.com
Customer support http://support.eiffel.com
]"
end
<?xml version="1.0" encoding="ISO-8859-1"?>
<system xmlns="http://www.eiffel.com/developers/xml/configuration-1-13-0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.eiffel.com/developers/xml/configuration-1-13-0 http://www.eiffel.com/developers/xml/configuration-1-13-0.xsd" name="scoop_pool" uuid="652A724F-0A62-44F1-AC2F-C892CB16ECE9">
<target name="scoop_pool">
<root class="APP" feature="make"/>
<setting name="console_application" value="true"/>
<setting name="concurrency" value="scoop"/>
<library name="base" location="$ISE_LIBRARY\library\base\base-safe.ecf"/>
<cluster name="src" location=".\" recursive="false"/>
</target>
</system>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment