From adaa36dbec1ce9aaafd61873b9d3d898a8c240cf Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Thu, 11 Apr 2024 15:14:52 +0200 Subject: Bring all interesting fixes from the C++ implementation back into the C implementation --- tests/basic.lua | 14 +-- tests/cancel.lua | 212 +++++++++++++++++++++++++------------------- tests/errhangtest.lua | 15 +++- tests/fifo.lua | 42 +++++++-- tests/keeper.lua | 63 +++++++++++-- tests/linda_perf.lua | 165 +++++++++++++++++----------------- tests/protect_allocator.lua | 3 + tests/timer.lua | 12 +-- 8 files changed, 332 insertions(+), 194 deletions(-) (limited to 'tests') diff --git a/tests/basic.lua b/tests/basic.lua index 385e22f..4b4fae6 100644 --- a/tests/basic.lua +++ b/tests/basic.lua @@ -154,7 +154,7 @@ PRINT(" "..st) assert( st == "cancelled" ) -- cancellation of lanes waiting on a linda -local limited = lanes.linda() +local limited = lanes.linda("limited") limited:limit( "key", 1) -- [[################################################ limited:send( "key", "hello") -- saturate linda @@ -234,7 +234,7 @@ local chunk= function( linda ) WR( "Lane ends!\n" ) end -local linda= lanes_linda() +local linda= lanes_linda("communications") assert( type(linda) == "userdata" ) -- -- ["->"] master -> slave @@ -278,10 +278,12 @@ local complex_table = RECEIVE(); WR( type(complex_table).." received\n" ) assert( complex_table[1] == complex_table[3] and complex_table[2] == complex_table[4]) WR( table.concat( {complex_table[1][1],complex_table[2][1],complex_table[3][1],complex_table[4][1]},", ")) +WR("collectgarbage") t = nil collectgarbage() -- wait -linda: receive( 1, "wait") +WR("waiting 1s") +linda:receive( 1, "wait") --############################################################## --############################################################## @@ -336,6 +338,7 @@ for _, t in ipairs( stdlib_naming_tests) do assert( f(t[1])[1] ) end +WR("collectgarbage") collectgarbage() --############################################################## @@ -361,12 +364,13 @@ local tc= lanes_gen( "io", {gc_cb = gc_cb}, end ) -local linda= lanes_linda() +local linda= lanes_linda("criss cross") local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twisted comms local _= a[1],b[1] -- waits until they are both ready +WR("collectgarbage") a, b = nil collectgarbage() @@ -408,7 +412,7 @@ local function chunk2( linda ) linda:send( "up", function() return ":)" end, "ok2" ) end -local linda= lanes.linda() +local linda= lanes.linda("linda") local t2= lanes_gen( "debug,string,io", {gc_cb = gc_cb}, chunk2 )(linda) -- prepare & launch linda:send( "down", function(linda) linda:send( "up", "ready!" ) end, "ok" ) diff --git a/tests/cancel.lua b/tests/cancel.lua index 0d9d143..4e57184 100644 --- a/tests/cancel.lua +++ b/tests/cancel.lua @@ -1,36 +1,47 @@ -local lanes = require "lanes" .configure{ with_timers = false} - -local linda = lanes.linda() +local which_tests, remaining_tests = {}, {} +for k,v in ipairs{...} do + print("got arg:", type(v), tostring(v)) + which_tests[v] = true + remaining_tests[v] = true +end --#################################################################### -print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" - --- get a lock and a atomic operator -local lock = lanes.genlock( linda, "lock", 1) -local atomic = lanes.genatomic( linda, "atomic") - --- check that cancelled lindas give cancel_error as they should -linda:cancel() -assert( linda:get( "empty") == lanes.cancel_error) -assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) -assert( lanes.genatomic( linda, "any") == lanes.cancel_error) - --- check that lock and atomic functions return cancel_error if the linda was cancelled -assert( lock( 1) == lanes.cancel_error) -assert( lock( -1) == lanes.cancel_error) -assert( atomic( 1) == lanes.cancel_error) - --- reset the linda so that the other tests work -linda:cancel( "none") -linda:limit( "lock", -1) -linda:set( "lock") -linda:limit( "atomic", -1) -linda:set( "atomic") +local lanes = require "lanes" .configure{ with_timers = false} + +local linda = lanes.linda() -- a numeric value to read linda:set( "val", 33.0) -print "test OK" +--#################################################################### +if not next(which_tests) or which_tests.genlock then + remaining_tests.genlock = nil + print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" + + -- get a lock and a atomic operator + local lock = lanes.genlock( linda, "lock", 1) + local atomic = lanes.genatomic( linda, "atomic") + + -- check that cancelled lindas give cancel_error as they should + linda:cancel() + assert( linda:get( "empty") == lanes.cancel_error) + assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) + assert( lanes.genatomic( linda, "any") == lanes.cancel_error) + + -- check that lock and atomic functions return cancel_error if the linda was cancelled + assert( lock( 1) == lanes.cancel_error) + assert( lock( -1) == lanes.cancel_error) + assert( atomic( 1) == lanes.cancel_error) + + -- reset the linda so that the other tests work + linda:cancel( "none") + linda:limit( "lock", -1) + linda:set( "lock") + linda:limit( "atomic", -1) + linda:set( "atomic") + + print "test OK" +end --#################################################################### local waitCancellation = function( h, expected_status) @@ -119,92 +130,115 @@ end --#################################################################### --#################################################################### -print "\n\n####################################################################\nbegin linda cancel test\n" -h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda - -print "wait 1s" -linda:receive( 1, "yeah") - --- linda cancel: linda:receive() returns cancel_error immediately -linda:cancel( "both") +if not next(which_tests) or which_tests.linda then + remaining_tests.linda = nil + print "\n\n####################################################################\nbegin linda cancel test\n" + h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda --- wait until cancellation is effective. -waitCancellation( h, "done") + print "wait 1s" + linda:receive( 1, "yeah") --- reset the linda so that the other tests work -linda:cancel( "none") + -- linda cancel: linda:receive() returns cancel_error immediately + print "cancelling" + linda:cancel( "both") -print "\n\n####################################################################\nbegin soft cancel test\n" -h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda + -- wait until cancellation is effective. + waitCancellation( h, "done") -print "wait 1s" -linda:receive( 1, "yeah") + -- reset the linda so that the other tests work + linda:cancel( "none") +end --- soft cancel, no awakening of waiting linda operations, should timeout -local a, b = h:cancel( "soft", 1, false) --- cancellation should fail as the lane is still waiting on its linda -assert( a == false and b == "timeout") -waitCancellation( h, "waiting") +if not next(which_tests) or which_tests.soft then + remaining_tests.soft = nil + print "\n\n####################################################################\nbegin soft cancel test\n" + h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda --- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. -h:cancel( "soft", true) + print "wait 1s" + linda:receive( 1, "yeah") --- wait until cancellation is effective. the lane will interrupt its loop and print the exit message -waitCancellation( h, "done") + -- soft cancel, no awakening of waiting linda operations, should timeout + local a, b = h:cancel( "soft", 1, false) + -- cancellation should fail as the lane is still waiting on its linda + assert( a == false and b == "timeout") + waitCancellation( h, "waiting") --- do return end + -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. + print "cancelling" + h:cancel( "soft", true) -print "\n\n####################################################################\nbegin hook cancel test\n" -h = lanes.gen( "*", protectedBody)( "get", 300000) -print "wait 2s" -linda:receive( 2, "yeah") + -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message + waitCancellation( h, "done") +end --- count hook cancel after 3 instructions -h:cancel( "count", 300, 5.0) +if not next(which_tests) or which_tests.hook then + remaining_tests.hook = nil + print "\n\n####################################################################\nbegin hook cancel test\n" + h = lanes.gen( "*", protectedBody)( "get", 300000) + print "wait 2s" + linda:receive( 2, "yeah") --- wait until cancellation is effective. the lane will interrupt its loop and print the exit message -waitCancellation( h, "cancelled") + -- count hook cancel after some instruction instructions + print "cancelling" + h:cancel( "line", 300, 5.0) -print "\n\n####################################################################\nbegin hard cancel test\n" -h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout + -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message + waitCancellation( h, "cancelled") +end --- wait 2s before cancelling the lane -print "wait 2s" -linda:receive( 2, "yeah") +if not next(which_tests) or which_tests.hard then + remaining_tests.hard = nil + print "\n\n####################################################################\nbegin hard cancel test\n" + h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout --- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it -h:cancel() + -- wait 2s before cancelling the lane + print "wait 2s" + linda:receive( 2, "yeah") --- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error -waitCancellation( h, "cancelled") + -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it + print "cancelling" + h:cancel() -print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" -h = lanes.gen( "*", laneBody)( "receive", nil) + -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error + waitCancellation( h, "cancelled") +end --- wait 2s before cancelling the lane -print "wait 2s" -linda:receive( 2, "yeah") +if not next(which_tests) or which_tests.hard_unprotected then + remaining_tests.hard_unprotected = nil + print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" + h = lanes.gen( "*", laneBody)( "receive", nil) --- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it -h:cancel() + -- wait 2s before cancelling the lane + print "wait 2s" + linda:receive( 2, "yeah") --- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error -waitCancellation( h, "cancelled") + -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it + print "cancelling" + h:cancel() -print "\n\n####################################################################\nbegin kill cancel test\n" -h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane + -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error + waitCancellation( h, "cancelled") +end --- wait 1/3s before cancelling the lane, before the busy loop can finish -print "wait 0.3s" -linda:receive( 0.3, "yeah") +if not next(which_tests) or which_tests.kill then + remaining_tests.kill = nil + print "\n\n####################################################################\nbegin kill cancel test\n" + h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane --- hard cancel with kill: the lane thread will be forcefully terminated -h:cancel( true) + -- wait 1/3s before cancelling the lane, before the busy loop can finish + print "wait 0.3s" + linda:receive( 0.3, "yeah") --- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error -waitCancellation( h, "killed") + -- hard cancel with kill: the lane thread will be forcefully terminated. kill timeout is pthread-specific + print "cancelling" + h:cancel( true, 1.0) + -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error + waitCancellation( h, "killed") +end --#################################################################### -print "\ndone" +local unknown_test, val = next(remaining_tests) +assert(not unknown_test, tostring(unknown_test) .. " test is unknown") +print "\nTHE END" diff --git a/tests/errhangtest.lua b/tests/errhangtest.lua index 7286fa5..d26dcef 100644 --- a/tests/errhangtest.lua +++ b/tests/errhangtest.lua @@ -4,10 +4,19 @@ local linda = lanes.linda() local coro = coroutine.create(function() end) +local fun = function() print "fun" end +local t_in = { [fun] = fun, fun = fun } + +-- send a string +print( pcall(linda.send,linda, 'test', "oh boy")) +-- send a table that contains a function +print( pcall(linda.send,linda, 'test', t_in)) -- we are not allowed to send coroutines through a lanes -- however, this should raise an error, not hang the program... -print( pcall(linda.send,linda, 'test', "oh boy")) print( pcall(linda.send,linda, 'test', coro)) -k,res = linda:receive('test') -print( res) +k,str = linda:receive('test') -- read the contents successfully sent +print( str) -- "oh boy" +k,t_out = linda:receive('test') -- read the contents successfully sent +t_out.fun() -- "fun" -- linda:send( 'test', coro) +print "SUCCESS" \ No newline at end of file diff --git a/tests/fifo.lua b/tests/fifo.lua index bef60d5..498f540 100644 --- a/tests/fifo.lua +++ b/tests/fifo.lua @@ -6,24 +6,27 @@ local lanes = require "lanes".configure{shutdown_timeout=3,with_timers=true} -local linda = lanes.linda( "atom") -local atomic_inc= lanes.genatomic( linda, "FIFO_n") +local atomic_linda = lanes.linda( "atom") +local atomic_inc= lanes.genatomic( atomic_linda, "FIFO_n") + +local fifo_linda = lanes.linda( "fifo") assert( atomic_inc()==1) assert( atomic_inc()==2) local function FIFO() - local my_channel= "FIFO"..atomic_inc() + local my_channel= "FIFO_"..atomic_inc() return { -- Giving explicit 'nil' timeout allows numbers to be used as 'my_channel' -- send = function(self, ...) - linda:send( nil, my_channel, ...) + fifo_linda:send( nil, my_channel, ...) end, receive = function(self, timeout) - return linda:receive( timeout, my_channel) - end + return fifo_linda:receive( timeout, my_channel) + end, + channel = my_channel } end @@ -36,11 +39,38 @@ A:send( 1,2,3,4,5) print "Sending to B.." B:send( 'a','b','c') +print "Dumping linda stats.. [1]" -- count everything +for key,count in pairs(fifo_linda:count()) do + print("channel " .. key .. " contains " .. count .. " entries.") + -- print(i, key_count[1], key_count[2]) +end +print "Dumping linda stats.. [2]" -- query count for known channels one at a time +print("channel " .. A.channel .. " contains " .. fifo_linda:count(A.channel) .. " entries.") +print("channel " .. B.channel .. " contains " .. fifo_linda:count(B.channel) .. " entries.") +print "Dumping linda stats.. [3]" -- query counts for a predefined list of keys +for key,count in pairs(fifo_linda:count(A.channel, B.channel)) do + print("channel " .. key .. " contains " .. count .. " entries.") + -- print(i, key_count[1], key_count[2]) +end +print "Dumping linda stats.. [4]" -- count everything +for key,contents in pairs(fifo_linda:dump()) do + print("channel " .. key .. ": limit=".. contents.limit, " first=" .. contents.first, " count=" .. contents.count) + for k,v in pairs(contents.fifo) do + print("[".. k.."] = " .. v) + end +end + print "Reading A.." print( A:receive( 1.0)) +print( A:receive( 1.0)) +print( A:receive( 1.0)) +print( A:receive( 1.0)) +print( A:receive( 1.0)) print "Reading B.." print( B:receive( 2.0)) +print( B:receive( 2.0)) +print( B:receive( 2.0)) -- Note: A and B can be passed between threads, or used as upvalues -- by multiple threads (other parts will be copied but the 'linda' diff --git a/tests/keeper.lua b/tests/keeper.lua index f8c915d..3333938 100644 --- a/tests/keeper.lua +++ b/tests/keeper.lua @@ -4,7 +4,34 @@ -- Test program for Lua Lanes -- -local lanes = require "lanes".configure{ with_timers = false, nb_keepers = 200} +local lanes = require "lanes".configure{ with_timers = false, nb_keepers = 1, keepers_gc_threshold = 500} + +do + print "Linda names test:" + local unnamedLinda = lanes.linda() + local unnamedLinda2 = lanes.linda("") + local veeeerrrryyyylooongNamedLinda= lanes.linda( "veeeerrrryyyylooongNamedLinda", 1) + print(unnamedLinda, unnamedLinda2, veeeerrrryyyylooongNamedLinda) + print "GC deadlock test start" + -- store a linda in another linda (-> in a keeper) + unnamedLinda:set("here", lanes.linda("temporary linda")) + -- repeatedly add and remove stuff in the linda so that a GC happens during the keeper operation + for i = 1, 1000 do + for j = 1, 1000 do -- send 1000 tables + unnamedLinda:send("here", {"a", "table", "with", "some", "stuff"}) + end + unnamedLinda:set("here") -- clear everything + end +end +print "collecting garbage" +collectgarbage() +print "GC deadlock test done" + +local print_id = 0 +local PRINT = function(...) + print_id = print_id + 1 + print("main", print_id .. ".", ...) +end local function keeper(linda) local mt= { @@ -25,23 +52,49 @@ local A= keeper( lindaA ) local lindaB= lanes.linda( "B", 2) local B= keeper( lindaB ) +local lindaC= lanes.linda( "C", 3) +local C= keeper( lindaC ) +print("Created", lindaA, lindaB, lindaC) + A.some= 1 -print( A.some ) +PRINT("A.some == " .. A.some ) assert( A.some==1 ) B.some= "hoo" +PRINT("B.some == " .. B.some ) assert( B.some=="hoo" ) assert( A.some==1 ) +assert( C.some==nil ) function lane() + local print_id = 0 + local PRINT = function(...) + print_id = print_id + 1 + print("lane", print_id .. ".", ...) + end + local a= keeper(lindaA) - print( a.some ) + PRINT("a.some == " .. a.some ) assert( a.some==1 ) a.some= 2 + assert( a.some==2 ) + PRINT("a.some == " .. a.some ) + + local c = keeper(lindaC) + assert( c.some==nil ) + PRINT("c.some == " .. tostring(c.some)) + c.some= 3 + assert( c.some==3 ) + PRINT("c.some == " .. c.some) end +PRINT("lane started") local h= lanes.gen( "io", lane )() -h:join() +PRINT("lane joined:", h:join()) -print( A.some ) -- 2 +PRINT("A.some = " .. A.some ) assert( A.some==2 ) +PRINT("C.some = " .. C.some ) +assert( C.some==3 ) +lindaC:set("some") +assert( C.some==nil ) \ No newline at end of file diff --git a/tests/linda_perf.lua b/tests/linda_perf.lua index a170b01..61b8f05 100644 --- a/tests/linda_perf.lua +++ b/tests/linda_perf.lua @@ -1,38 +1,62 @@ local lanes = require "lanes" -lanes.configure{ with_timers = false} +lanes.configure{ with_timers = false, keepers_gc_threshold=30000 } + +-- set TEST1, PREFILL1, FILL1, TEST2, PREFILL2, FILL2 from the command line -- Lua 5.1/5.2 compatibility local table_unpack = unpack or table.unpack +local finalizer = function(err, stk) + if err == lanes.cancel_error then + -- note that we don't get the cancel_error when running wrapped inside a protected call if it doesn't rethrow it + print(" laneBody after cancel" ) + elseif err then + print(" laneBody error: "..tostring(err)) + else + print(" laneBody finalized") + end +end + +--################################################################################################## + -- this lane eats items in the linda one by one local eater = function( l, loop) + set_finalizer(finalizer) -- wait for start signal l:receive( "go") -- eat data one by one for i = 1, loop do - local val, key = l:receive( "key") - --print( val) + local key, val = l:receive( "key") + -- print("eater:", val) end -- print "loop is over" key, val = l:receive( "done") - -- print( val) + print("eater: done ("..val..")") end +--################################################################################################## + -- this lane eats items in the linda in batches -local batched = function( l, loop, batch) +local gobbler = function( l, loop, batch) + set_finalizer(finalizer) -- wait for start signal l:receive( "go") -- eat data in batches for i = 1, loop/batch do l:receive( l.batched, "key", batch) + -- print("gobbler:", batch) end print "loop is over" key, val = l:receive( "done") - print( val) + print("gobbler: done ("..val..")") end +--################################################################################################## + local lane_eater_gen = lanes.gen( "*", {priority = 3}, eater) -local lane_batched_gen = lanes.gen( "*", {priority = 3}, batched) +local lane_gobbler_gen = lanes.gen( "*", {priority = 3}, gobbler) + +--################################################################################################## -- main thread writes data while a lane reads it local function ziva( preloop, loop, batch) @@ -46,7 +70,7 @@ local function ziva( preloop, loop, batch) print( "stored " .. l:count( "key") .. " items in the linda before starting consumer lane") if batch > 0 then if l.batched then - lane = lane_batched_gen( l, top, batch) + lane = lane_gobbler_gen( l, top, batch) else print "no batch support in this version of Lanes" lane = lane_eater_gen( l, top) @@ -63,7 +87,9 @@ local function ziva( preloop, loop, batch) for i = 1, batch do table.insert( batch_values, i) end + local batch_send_log = "main: sending "..batch.." values" local batch_send = function() + -- print(batch_send_log) l:send( "key", table_unpack( batch_values)) end if loop > preloop then @@ -76,57 +102,35 @@ local function ziva( preloop, loop, batch) return lanes.now_secs() - t1 end +--################################################################################################## + +TEST1 = TEST1 or 1000 +PREFILL1 = PREFILL1 or 10000 +FILL1 = FILL1 or 2000000 + local tests1 = { - { 10000, 2000000, 0}, - { 10000, 2000000, 1}, - { 10000, 2000000, 2}, - { 10000, 2000000, 3}, - { 10000, 2000000, 5}, - { 10000, 2000000, 8}, - { 10000, 2000000, 13}, - { 10000, 2000000, 21}, - { 10000, 2000000, 44}, + { PREFILL1, FILL1, 0}, + { PREFILL1, FILL1, 1}, + { PREFILL1, FILL1, 2}, + { PREFILL1, FILL1, 3}, + { PREFILL1, FILL1, 5}, + { PREFILL1, FILL1, 8}, + { PREFILL1, FILL1, 13}, + { PREFILL1, FILL1, 21}, + { PREFILL1, FILL1, 44}, + { PREFILL1, FILL1, 65}, } -print "############################################\ntests #1" -for k, v in pairs( tests1) do +print "############################################ tests #1" +for i, v in ipairs( tests1) do + if i > TEST1 then break end local pre, loop, batch = v[1], v[2], v[3] - print( "testing", pre, loop, batch) - print( pre, loop, batch, "duration = " .. ziva( pre, loop, batch) .. "\n") + print("-------------------------------------------------\n") + print("START", "prefill="..pre, "fill="..loop, "batch="..batch) + print("DURATION = " .. ziva( pre, loop, batch) .. "\n") end ---[[ - V 2.1.0: - ziva( 20000, 0) -> 4s ziva( 10000, 20000) -> 3s - ziva( 30000, 0) -> 8s ziva( 20000, 30000) -> 7s - ziva( 40000, 0) -> 15s ziva( 30000, 40000) -> 15s - ziva( 50000, 0) -> 24s ziva( 40000, 50000) -> 23s - ziva( 60000, 0) -> 34s ziva( 50000, 60000) -> 33s - - SIMPLIFIED: - ziva( 20000, 0) -> 4s ziva( 10000, 20000) -> 3s - ziva( 30000, 0) -> 9s ziva( 20000, 30000) -> 8s - ziva( 40000, 0) -> 15s ziva( 30000, 40000) -> 15s - ziva( 50000, 0) -> 25s ziva( 40000, 50000) -> 24s - ziva( 60000, 0) -> 35s ziva( 50000, 60000) -> 35s - - FIFO: - ziva( 2000000, 0) -> 9s ziva( 1000000, 2000000) -> 33s - ziva( 3000000, 0) -> 14s ziva( 2000000, 3000000) -> 40s - ziva( 4000000, 0) -> 20s ziva( 3000000, 4000000) -> 27s - ziva( 5000000, 0) -> 24s ziva( 4000000, 5000000) -> 42s - ziva( 6000000, 0) -> 29s ziva( 5000000, 6000000) -> 55s - - FIFO BATCHED: - ziva( 4000000, 0, 1) -> 20s - ziva( 4000000, 0, 2) -> 11s - ziva( 4000000, 0, 3) -> 7s - ziva( 4000000, 0, 5) -> 5s - ziva( 4000000, 0, 8) -> 3s - ziva( 4000000, 0, 13) -> 3s - ziva( 4000000, 0, 21) -> 3s - ziva( 4000000, 0, 44) -> 2s -]] +--################################################################################################## -- sequential write/read (no parallelization involved) local function ziva2( preloop, loop, batch) @@ -159,7 +163,7 @@ local function ziva2( preloop, loop, batch) for i = 1, preloop, step do batch_send() end - print( "stored " .. (l:count( "key") or 0) .. " items in the linda before starting consumer lane") + print( "stored " .. (l:count( "key") or 0) .. " items in the linda before starting the alternating reads and writes") -- loop that alternatively sends and reads data off the linda if loop > preloop then for i = preloop + 1, loop, step do @@ -169,40 +173,39 @@ local function ziva2( preloop, loop, batch) end -- here, we have preloop elements still waiting inside the linda for i = 1, preloop, step do - batch_read() + batch_read() end return lanes.now_secs() - t1 end +--################################################################################################## + +TEST2 = TEST2 or 1000 +PREFILL2 = PREFILL2 or 0 +FILL2 = FILL2 or 4000000 + local tests2 = { - -- prefill, then consume everything - --[[ - { 4000000, 0}, - { 4000000, 0, 1}, - { 4000000, 0, 2}, - { 4000000, 0, 3}, - { 4000000, 0, 5}, - { 4000000, 0, 8}, - { 4000000, 0, 13}, - { 4000000, 0, 21}, - { 4000000, 0, 44}, - --]] - -- alternatively fill and consume - { 0, 4000000}, - { 0, 4000000, 1}, - { 0, 4000000, 2}, - { 0, 4000000, 3}, - { 0, 4000000, 5}, - { 0, 4000000, 8}, - { 0, 4000000, 13}, - { 0, 4000000, 21}, - { 0, 4000000, 44}, + { PREFILL2, FILL2}, + { PREFILL2, FILL2, 1}, + { PREFILL2, FILL2, 2}, + { PREFILL2, FILL2, 3}, + { PREFILL2, FILL2, 5}, + { PREFILL2, FILL2, 8}, + { PREFILL2, FILL2, 13}, + { PREFILL2, FILL2, 21}, + { PREFILL2, FILL2, 44}, + { PREFILL2, FILL2, 65}, } -print "\n############################################\ntests #2" -for k, v in pairs( tests2) do +print "############################################ tests #2" +for i, v in ipairs( tests2) do + if i > TEST2 then break end local pre, loop, batch = v[1], v[2], v[3] - print( "testing", pre, loop, batch) - print( pre, loop, batch, "duration = " .. ziva2( pre, loop, batch) .. "\n") + print("-------------------------------------------------\n") + print("START", "prefill="..pre, "fill="..loop, "batch="..(batch or "no")) + print("DURATION = " .. ziva2( pre, loop, batch) .. "\n") end + +print "############################################" +print "THE END" \ No newline at end of file diff --git a/tests/protect_allocator.lua b/tests/protect_allocator.lua index 593261e..5cbb1d8 100644 --- a/tests/protect_allocator.lua +++ b/tests/protect_allocator.lua @@ -46,5 +46,8 @@ for i = 1, COUNT do end -- wait for completion +print "wait for completion" linda:receive( linda.batched, "key", COUNT) +print "waiting a bit more ..." +linda:receive( 1, "foo") print "SUCCESS" diff --git a/tests/timer.lua b/tests/timer.lua index ec23cee..73ecb93 100644 --- a/tests/timer.lua +++ b/tests/timer.lua @@ -18,13 +18,14 @@ end local T1= "1s" -- these keys can be anything... local T2= "5s" +local PING_DURATION = 20 local step= {} lanes.timer( linda, T1, 1.0, 1.0 ) step[T1]= 1.0 -PRINT( "\n*** Timers every second (not synced to wall clock) ***\n" ) +PRINT( "\n*** Starting 1s Timer (not synced to wall clock) ***\n" ) local v_first local v_last= {} -- { [channel]= num } @@ -46,14 +47,15 @@ while true do -- do not make measurements, first round is not 5secs due to wall clock adjustment T2_first_round= false else - assert( math.abs(v-v_last[channel]- step[channel]) < 0.02 ) + local dt = math.abs(v-v_last[channel]- step[channel]) + assert( dt < 0.02, "channel " .. channel .. " is late: " .. dt) end end if not v_first then v_first= v elseif v-v_first > 3.0 and (not step[T2]) then - PRINT( "\n*** Adding timers every 5 second (synced to wall clock) ***\n" ) + PRINT( "\n*** Starting 5s timer (synced to wall clock) ***\n" ) -- The first event can be in the past (just cut seconds down to 5s) -- @@ -63,7 +65,7 @@ while true do lanes.timer( linda, T2, date, 5.0 ) step[T2]= 5.0 - elseif v-v_first > 10 then -- exit condition + elseif v-v_first > PING_DURATION then -- exit condition break end v_last[channel]= v @@ -80,7 +82,7 @@ PRINT( "\n*** Listing timers ***\n" ) local r = lanes.timers() -- list of {linda, key, {}} for _,t in ipairs( r) do local linda, key, timer = t[1], t[2], t[3] - print( tostring( linda), key, timer[1], timer[2]) + print( tostring( linda), key, timer[1], timer[2]) end -- cgit v1.2.3-55-g6feb