Skip to content

Commit

Permalink
Example programs using threads
Browse files Browse the repository at this point in the history
Just some examples to show how Tasks and threads might be used.
  • Loading branch information
niner committed Mar 23, 2012
1 parent e46e799 commit a63fd3f
Show file tree
Hide file tree
Showing 3 changed files with 417 additions and 0 deletions.
261 changes: 261 additions & 0 deletions examples/threads/chameneos.pir
Original file line number Diff line number Diff line change
@@ -0,0 +1,261 @@
# Copyright (C) 2011 Parrot Foundation.

.sub 'main' :main
.local pmc colors, start_colors, at_most_two, mutex, sem_priv, first_call, a_color, b_color, chameneos, chameneo, code, data, number, color, dummy
.local int i

dummy = new ['Continuation'] # workaround, see TODO in Proxy instantiate

colors = new ['ResizableStringArray']
colors = 3
colors[0] = 'Blue'
colors[1] = 'Red'
colors[2] = 'Yellow'

start_colors = new ['ResizableIntegerArray']
start_colors = 4
start_colors[0] = 2
start_colors[1] = 0
start_colors[2] = 1
start_colors[3] = 0

# init cooperation
at_most_two = new ['Integer']
at_most_two = 2
mutex = new ['Integer']
mutex = 1
sem_priv = new ['Integer']
sem_priv = 0
first_call = new ['Integer']
first_call = 1
a_color = new ['Integer']
b_color = new ['Integer']

code = get_global 'chameneos_code'
chameneos = new ['ResizablePMCArray']
chameneos = 4
i = 0
init_chameneos:
chameneo = new ['Task']
chameneos[i] = chameneo
data = new ['FixedPMCArray']
data = 2
number = new ['Integer']
number = i
data[0] = number
color = new ['Integer']
color = start_colors[i]
data[1] = color
setattribute chameneo, 'code', code
setattribute chameneo, 'data', data
push chameneo, b_color
push chameneo, a_color
push chameneo, first_call
push chameneo, at_most_two
push chameneo, mutex
push chameneo, sem_priv
push chameneo, colors
schedule chameneo

inc i
if i < 4 goto init_chameneos

say "going to sleep"
sleep 10
say "woke up just in time for exit"
.end

.sub chameneos_code
.param pmc data
.local pmc interp, task, number, color, colors, at_most_two, mutex, sem_priv, cooperation, first_call, a_color, b_color, other_color
.local int old_color, other_color_int, color_int
.local string color_name

interp = getinterp
task = interp.'current_task'()
colors = pop task
sem_priv = pop task
mutex = pop task
at_most_two = pop task
first_call = pop task
a_color = pop task
b_color = pop task

number = data[0]
color = data[1]
color_int = color
color = new ['Integer']
color = color_int
cooperation = get_global 'cooperation'

start:
color_name = colors[color]
print 'This is '
print number
print " and I'm "
say color_name

other_color = cooperation(number, color, sem_priv, mutex, at_most_two, first_call, a_color, b_color)
other_color_int = other_color

color_int = color

if color_int == other_color_int goto start

color_int = 3 - color_int
color_int = color_int - other_color_int

color = color_int

goto start
.end

.sub cooperation
.param pmc id
.param pmc color
.param pmc sem_priv
.param pmc mutex
.param pmc at_most_two
.param pmc first_call
.param pmc a_color
.param pmc b_color
.local pmc interp, sem_wait, sem_unlock, call_core, call_task, other_color

interp = getinterp
sem_wait = get_global 'sem_wait'
sem_unlock = get_global 'sem_unlock'

sem_wait(at_most_two)
sem_wait(mutex)

if first_call == 1 goto first
call_core = get_global 'second_call_core'
call_task = new ['Task']
push call_task, first_call
push call_task, b_color
setattribute call_task, 'code', call_core
setattribute call_task, 'data', color
interp.'schedule_proxied'(call_task, b_color)
sleep 0.1
other_color = a_color
sem_unlock(sem_priv)
goto done
first:
call_core = get_global 'first_call_core'
call_task = new ['Task']
push call_task, first_call
push call_task, a_color
setattribute call_task, 'code', call_core
setattribute call_task, 'data', color
interp.'schedule_proxied'(call_task, a_color)
sleep 0.1

sem_unlock(mutex)
sem_wait(sem_priv)
other_color = b_color
sem_unlock(mutex)
sem_unlock(at_most_two)
sem_unlock(at_most_two)
done:
.return(other_color)
.end

.sub first_call_core
.param pmc data
.local pmc interp, task, a_color, first_call
.local int a_color_int
interp = getinterp
task = interp.'current_task'()

a_color = pop task
first_call = pop task

a_color_int = data
a_color = a_color_int
first_call = 0
.end

.sub second_call_core
.param pmc data
.local pmc interp, task, b_color, first_call
.local int b_color_int
interp = getinterp
task = interp.'current_task'()

b_color = pop task
first_call = pop task

first_call = 1
b_color_int = data
b_color = b_color_int
.end

.sub sem_unlock
.param pmc sem
.local pmc interp, sem_unlock_task, sem_unlock_core

interp = getinterp
sem_unlock_core = get_global 'sem_unlock_core'
sem_unlock_task = new ['Task']
setattribute sem_unlock_task, 'code', sem_unlock_core
setattribute sem_unlock_task, 'data', sem

interp.'schedule_proxied'(sem_unlock_task, sem)
.end

.sub sem_wait
.param pmc sem
.local pmc interp, waiter, sem_wait_task, sem_wait_core

interp = getinterp
sem_wait_core = get_global 'sem_wait_core'

waiter = new ['Continuation']
set_label waiter, got_lock

sem_wait_task = new ['Task']
setattribute sem_wait_task, 'code', sem_wait_core
setattribute sem_wait_task, 'data', sem
push sem_wait_task, waiter
interp.'schedule_proxied'(sem_wait_task, sem)
terminate
got_lock:
returncc
.end

.sub sem_wait_core
.param pmc data
.local pmc interp, task, sem, waiter, resume_task
interp = getinterp
task = interp.'current_task'()

sem = data
waiter = pop task
test:
#disablepreemption
if sem > 0 goto lock
#enablepreemption
pass
goto test
lock:
dec sem
#enablepreemption

resume_task = new ['Task']
setattribute resume_task, 'code', waiter
interp.'schedule_proxied'(resume_task, waiter)
.end

.sub sem_unlock_core
.param pmc data
.local pmc sem
sem = data
inc sem
.end

# Local Variables:
# mode: pir
# fill-column: 100
# End:
# vim: expandtab shiftwidth=4 ft=pir:

125 changes: 125 additions & 0 deletions examples/threads/moretasks.pir
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
#!./parrot
# Copyright (C) 2011, Parrot Foundation.

.sub main :main
.local pmc task, sayer, starter, number, interp, tasks, results
.local int i, num_results
interp = getinterp
sayer = get_global 'sayer'
init:
starter = new ['Integer']
i = 1
starter = 0
say "1..100"
tasks = new ['ResizablePMCArray']
results = new ['ResizablePMCArray']
start:
number = new ['String']
number = i
task = new ['Task']
push task, results
push task, starter
setattribute task, 'code', sayer
setattribute task, 'data', number
print "ok "
say number
push tasks, task
schedule task
inc i
if i > 5000 goto run
goto start
run:
starter = 1
check_results:
pass
num_results = results
say num_results
if num_results >= 5000 goto end
goto check_results
end:
goto init
.end

.sub sayer
.param pmc name
.local pmc interp, task, starter, results, result_sub, result_task
.local int i
interp = getinterp
task = interp.'current_task'()
starter = pop task
results = pop task
result_sub = get_global 'push_result'
start:
if starter > 0 goto run
sleep 0.1
goto start
run:
result_task = new ['Task']
setattribute result_task, 'code', result_sub
setattribute result_task, 'data', results
push result_task, name
interp.'schedule_proxied'(result_task, results)
#say name
.end

.sub push_result
.param pmc results
.local pmc interp, task, number
interp = getinterp
task = interp.'current_task'()
number = pop task
push results, number
.end

.sub passing_sayer
.param pmc name
.local pmc interp, task, starter
interp = getinterp
task = interp.'current_task'()
starter = pop task
start:
if starter > 0 goto run
pass
goto start
run:
say name
.end

.sub busy_waiting_sayer
.param pmc name
.local pmc interp, task, starter
.local int i
interp = getinterp
task = interp.'current_task'()
starter = pop task
start:
if starter > 0 goto run
i = 0
loop:
inc i
if i >= 10000 goto start
goto loop
run:
say name
.end

.sub sleeping_sayer
.param pmc name
start:
say name
sleep 0.1
goto start
.end

.sub busy_sayer
.param pmc name
.local pmc starter
.local int i
start:
i = 0
say name
loop:
inc i
if i >= 1000000 goto start
goto loop
.end
Loading

0 comments on commit a63fd3f

Please sign in to comment.