diff options
| author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-11 15:14:52 +0200 |
|---|---|---|
| committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-11 15:14:52 +0200 |
| commit | adaa36dbec1ce9aaafd61873b9d3d898a8c240cf (patch) | |
| tree | 4c81e8f5983c3d696a636e2cc433ce7c0a9c3dd8 /tests | |
| parent | 1d310e6ecb6e156598337612f16573d9cd284f5e (diff) | |
| download | lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.gz lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.tar.bz2 lanes-adaa36dbec1ce9aaafd61873b9d3d898a8c240cf.zip | |
Bring all interesting fixes from the C++ implementation back into the C implementation
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/basic.lua | 14 | ||||
| -rw-r--r-- | tests/cancel.lua | 212 | ||||
| -rw-r--r-- | tests/errhangtest.lua | 15 | ||||
| -rw-r--r-- | tests/fifo.lua | 42 | ||||
| -rw-r--r-- | tests/keeper.lua | 63 | ||||
| -rw-r--r-- | tests/linda_perf.lua | 165 | ||||
| -rw-r--r-- | tests/protect_allocator.lua | 3 | ||||
| -rw-r--r-- | tests/timer.lua | 12 |
8 files changed, 332 insertions, 194 deletions
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) | |||
| 154 | assert( st == "cancelled" ) | 154 | assert( st == "cancelled" ) |
| 155 | 155 | ||
| 156 | -- cancellation of lanes waiting on a linda | 156 | -- cancellation of lanes waiting on a linda |
| 157 | local limited = lanes.linda() | 157 | local limited = lanes.linda("limited") |
| 158 | limited:limit( "key", 1) | 158 | limited:limit( "key", 1) |
| 159 | -- [[################################################ | 159 | -- [[################################################ |
| 160 | limited:send( "key", "hello") -- saturate linda | 160 | limited:send( "key", "hello") -- saturate linda |
| @@ -234,7 +234,7 @@ local chunk= function( linda ) | |||
| 234 | WR( "Lane ends!\n" ) | 234 | WR( "Lane ends!\n" ) |
| 235 | end | 235 | end |
| 236 | 236 | ||
| 237 | local linda= lanes_linda() | 237 | local linda= lanes_linda("communications") |
| 238 | assert( type(linda) == "userdata" ) | 238 | assert( type(linda) == "userdata" ) |
| 239 | -- | 239 | -- |
| 240 | -- ["->"] master -> slave | 240 | -- ["->"] master -> slave |
| @@ -278,10 +278,12 @@ local complex_table = RECEIVE(); WR( type(complex_table).." received\n" ) | |||
| 278 | assert( complex_table[1] == complex_table[3] and complex_table[2] == complex_table[4]) | 278 | assert( complex_table[1] == complex_table[3] and complex_table[2] == complex_table[4]) |
| 279 | WR( table.concat( {complex_table[1][1],complex_table[2][1],complex_table[3][1],complex_table[4][1]},", ")) | 279 | WR( table.concat( {complex_table[1][1],complex_table[2][1],complex_table[3][1],complex_table[4][1]},", ")) |
| 280 | 280 | ||
| 281 | WR("collectgarbage") | ||
| 281 | t = nil | 282 | t = nil |
| 282 | collectgarbage() | 283 | collectgarbage() |
| 283 | -- wait | 284 | -- wait |
| 284 | linda: receive( 1, "wait") | 285 | WR("waiting 1s") |
| 286 | linda:receive( 1, "wait") | ||
| 285 | 287 | ||
| 286 | --############################################################## | 288 | --############################################################## |
| 287 | --############################################################## | 289 | --############################################################## |
| @@ -336,6 +338,7 @@ for _, t in ipairs( stdlib_naming_tests) do | |||
| 336 | assert( f(t[1])[1] ) | 338 | assert( f(t[1])[1] ) |
| 337 | end | 339 | end |
| 338 | 340 | ||
| 341 | WR("collectgarbage") | ||
| 339 | collectgarbage() | 342 | collectgarbage() |
| 340 | 343 | ||
| 341 | --############################################################## | 344 | --############################################################## |
| @@ -361,12 +364,13 @@ local tc= lanes_gen( "io", {gc_cb = gc_cb}, | |||
| 361 | end | 364 | end |
| 362 | ) | 365 | ) |
| 363 | 366 | ||
| 364 | local linda= lanes_linda() | 367 | local linda= lanes_linda("criss cross") |
| 365 | 368 | ||
| 366 | local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twisted comms | 369 | local a,b= tc(linda, "A","B"), tc(linda, "B","A") -- launching two lanes, twisted comms |
| 367 | 370 | ||
| 368 | local _= a[1],b[1] -- waits until they are both ready | 371 | local _= a[1],b[1] -- waits until they are both ready |
| 369 | 372 | ||
| 373 | WR("collectgarbage") | ||
| 370 | a, b = nil | 374 | a, b = nil |
| 371 | collectgarbage() | 375 | collectgarbage() |
| 372 | 376 | ||
| @@ -408,7 +412,7 @@ local function chunk2( linda ) | |||
| 408 | linda:send( "up", function() return ":)" end, "ok2" ) | 412 | linda:send( "up", function() return ":)" end, "ok2" ) |
| 409 | end | 413 | end |
| 410 | 414 | ||
| 411 | local linda= lanes.linda() | 415 | local linda= lanes.linda("linda") |
| 412 | local t2= lanes_gen( "debug,string,io", {gc_cb = gc_cb}, chunk2 )(linda) -- prepare & launch | 416 | local t2= lanes_gen( "debug,string,io", {gc_cb = gc_cb}, chunk2 )(linda) -- prepare & launch |
| 413 | linda:send( "down", function(linda) linda:send( "up", "ready!" ) end, | 417 | linda:send( "down", function(linda) linda:send( "up", "ready!" ) end, |
| 414 | "ok" ) | 418 | "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 @@ | |||
| 1 | local lanes = require "lanes" .configure{ with_timers = false} | 1 | local which_tests, remaining_tests = {}, {} |
| 2 | 2 | for k,v in ipairs{...} do | |
| 3 | local linda = lanes.linda() | 3 | print("got arg:", type(v), tostring(v)) |
| 4 | which_tests[v] = true | ||
| 5 | remaining_tests[v] = true | ||
| 6 | end | ||
| 4 | 7 | ||
| 5 | --#################################################################### | 8 | --#################################################################### |
| 6 | print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" | ||
| 7 | |||
| 8 | -- get a lock and a atomic operator | ||
| 9 | local lock = lanes.genlock( linda, "lock", 1) | ||
| 10 | local atomic = lanes.genatomic( linda, "atomic") | ||
| 11 | |||
| 12 | -- check that cancelled lindas give cancel_error as they should | ||
| 13 | linda:cancel() | ||
| 14 | assert( linda:get( "empty") == lanes.cancel_error) | ||
| 15 | assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) | ||
| 16 | assert( lanes.genatomic( linda, "any") == lanes.cancel_error) | ||
| 17 | |||
| 18 | -- check that lock and atomic functions return cancel_error if the linda was cancelled | ||
| 19 | assert( lock( 1) == lanes.cancel_error) | ||
| 20 | assert( lock( -1) == lanes.cancel_error) | ||
| 21 | assert( atomic( 1) == lanes.cancel_error) | ||
| 22 | |||
| 23 | -- reset the linda so that the other tests work | ||
| 24 | linda:cancel( "none") | ||
| 25 | linda:limit( "lock", -1) | ||
| 26 | linda:set( "lock") | ||
| 27 | linda:limit( "atomic", -1) | ||
| 28 | linda:set( "atomic") | ||
| 29 | 9 | ||
| 10 | local lanes = require "lanes" .configure{ with_timers = false} | ||
| 11 | |||
| 12 | local linda = lanes.linda() | ||
| 30 | -- a numeric value to read | 13 | -- a numeric value to read |
| 31 | linda:set( "val", 33.0) | 14 | linda:set( "val", 33.0) |
| 32 | 15 | ||
| 33 | print "test OK" | 16 | --#################################################################### |
| 17 | if not next(which_tests) or which_tests.genlock then | ||
| 18 | remaining_tests.genlock = nil | ||
| 19 | print "\n\n####################################################################\nbegin genlock & genatomic cancel test\n" | ||
| 20 | |||
| 21 | -- get a lock and a atomic operator | ||
| 22 | local lock = lanes.genlock( linda, "lock", 1) | ||
| 23 | local atomic = lanes.genatomic( linda, "atomic") | ||
| 24 | |||
| 25 | -- check that cancelled lindas give cancel_error as they should | ||
| 26 | linda:cancel() | ||
| 27 | assert( linda:get( "empty") == lanes.cancel_error) | ||
| 28 | assert( lanes.genlock( linda, "any", 1) == lanes.cancel_error) | ||
| 29 | assert( lanes.genatomic( linda, "any") == lanes.cancel_error) | ||
| 30 | |||
| 31 | -- check that lock and atomic functions return cancel_error if the linda was cancelled | ||
| 32 | assert( lock( 1) == lanes.cancel_error) | ||
| 33 | assert( lock( -1) == lanes.cancel_error) | ||
| 34 | assert( atomic( 1) == lanes.cancel_error) | ||
| 35 | |||
| 36 | -- reset the linda so that the other tests work | ||
| 37 | linda:cancel( "none") | ||
| 38 | linda:limit( "lock", -1) | ||
| 39 | linda:set( "lock") | ||
| 40 | linda:limit( "atomic", -1) | ||
| 41 | linda:set( "atomic") | ||
| 42 | |||
| 43 | print "test OK" | ||
| 44 | end | ||
| 34 | --#################################################################### | 45 | --#################################################################### |
| 35 | 46 | ||
| 36 | local waitCancellation = function( h, expected_status) | 47 | local waitCancellation = function( h, expected_status) |
| @@ -119,92 +130,115 @@ end | |||
| 119 | --#################################################################### | 130 | --#################################################################### |
| 120 | --#################################################################### | 131 | --#################################################################### |
| 121 | 132 | ||
| 122 | print "\n\n####################################################################\nbegin linda cancel test\n" | 133 | if not next(which_tests) or which_tests.linda then |
| 123 | h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda | 134 | remaining_tests.linda = nil |
| 124 | 135 | print "\n\n####################################################################\nbegin linda cancel test\n" | |
| 125 | print "wait 1s" | 136 | h = lanes.gen( "*", laneBody)( "receive", nil) -- start an infinite wait on the linda |
| 126 | linda:receive( 1, "yeah") | ||
| 127 | |||
| 128 | -- linda cancel: linda:receive() returns cancel_error immediately | ||
| 129 | linda:cancel( "both") | ||
| 130 | 137 | ||
| 131 | -- wait until cancellation is effective. | 138 | print "wait 1s" |
| 132 | waitCancellation( h, "done") | 139 | linda:receive( 1, "yeah") |
| 133 | 140 | ||
| 134 | -- reset the linda so that the other tests work | 141 | -- linda cancel: linda:receive() returns cancel_error immediately |
| 135 | linda:cancel( "none") | 142 | print "cancelling" |
| 143 | linda:cancel( "both") | ||
| 136 | 144 | ||
| 137 | print "\n\n####################################################################\nbegin soft cancel test\n" | 145 | -- wait until cancellation is effective. |
| 138 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda | 146 | waitCancellation( h, "done") |
| 139 | 147 | ||
| 140 | print "wait 1s" | 148 | -- reset the linda so that the other tests work |
| 141 | linda:receive( 1, "yeah") | 149 | linda:cancel( "none") |
| 150 | end | ||
| 142 | 151 | ||
| 143 | -- soft cancel, no awakening of waiting linda operations, should timeout | 152 | if not next(which_tests) or which_tests.soft then |
| 144 | local a, b = h:cancel( "soft", 1, false) | 153 | remaining_tests.soft = nil |
| 145 | -- cancellation should fail as the lane is still waiting on its linda | 154 | print "\n\n####################################################################\nbegin soft cancel test\n" |
| 146 | assert( a == false and b == "timeout") | 155 | h = lanes.gen( "*", protectedBody)( "receive") -- start an infinite wait on the linda |
| 147 | waitCancellation( h, "waiting") | ||
| 148 | 156 | ||
| 149 | -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. | 157 | print "wait 1s" |
| 150 | h:cancel( "soft", true) | 158 | linda:receive( 1, "yeah") |
| 151 | 159 | ||
| 152 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message | 160 | -- soft cancel, no awakening of waiting linda operations, should timeout |
| 153 | waitCancellation( h, "done") | 161 | local a, b = h:cancel( "soft", 1, false) |
| 162 | -- cancellation should fail as the lane is still waiting on its linda | ||
| 163 | assert( a == false and b == "timeout") | ||
| 164 | waitCancellation( h, "waiting") | ||
| 154 | 165 | ||
| 155 | -- do return end | 166 | -- soft cancel, this time awakens waiting linda operations, which returns cancel_error immediately, no timeout. |
| 167 | print "cancelling" | ||
| 168 | h:cancel( "soft", true) | ||
| 156 | 169 | ||
| 157 | print "\n\n####################################################################\nbegin hook cancel test\n" | 170 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
| 158 | h = lanes.gen( "*", protectedBody)( "get", 300000) | 171 | waitCancellation( h, "done") |
| 159 | print "wait 2s" | 172 | end |
| 160 | linda:receive( 2, "yeah") | ||
| 161 | 173 | ||
| 162 | -- count hook cancel after 3 instructions | 174 | if not next(which_tests) or which_tests.hook then |
| 163 | h:cancel( "count", 300, 5.0) | 175 | remaining_tests.hook = nil |
| 176 | print "\n\n####################################################################\nbegin hook cancel test\n" | ||
| 177 | h = lanes.gen( "*", protectedBody)( "get", 300000) | ||
| 178 | print "wait 2s" | ||
| 179 | linda:receive( 2, "yeah") | ||
| 164 | 180 | ||
| 165 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message | 181 | -- count hook cancel after some instruction instructions |
| 166 | waitCancellation( h, "cancelled") | 182 | print "cancelling" |
| 183 | h:cancel( "line", 300, 5.0) | ||
| 167 | 184 | ||
| 168 | print "\n\n####################################################################\nbegin hard cancel test\n" | 185 | -- wait until cancellation is effective. the lane will interrupt its loop and print the exit message |
| 169 | h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout | 186 | waitCancellation( h, "cancelled") |
| 187 | end | ||
| 170 | 188 | ||
| 171 | -- wait 2s before cancelling the lane | 189 | if not next(which_tests) or which_tests.hard then |
| 172 | print "wait 2s" | 190 | remaining_tests.hard = nil |
| 173 | linda:receive( 2, "yeah") | 191 | print "\n\n####################################################################\nbegin hard cancel test\n" |
| 192 | h = lanes.gen( "*", protectedBody)( "receive", nil) -- infinite timeout | ||
| 174 | 193 | ||
| 175 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it | 194 | -- wait 2s before cancelling the lane |
| 176 | h:cancel() | 195 | print "wait 2s" |
| 196 | linda:receive( 2, "yeah") | ||
| 177 | 197 | ||
| 178 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 198 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it |
| 179 | waitCancellation( h, "cancelled") | 199 | print "cancelling" |
| 200 | h:cancel() | ||
| 180 | 201 | ||
| 181 | print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" | 202 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error |
| 182 | h = lanes.gen( "*", laneBody)( "receive", nil) | 203 | waitCancellation( h, "cancelled") |
| 204 | end | ||
| 183 | 205 | ||
| 184 | -- wait 2s before cancelling the lane | 206 | if not next(which_tests) or which_tests.hard_unprotected then |
| 185 | print "wait 2s" | 207 | remaining_tests.hard_unprotected = nil |
| 186 | linda:receive( 2, "yeah") | 208 | print "\n\n####################################################################\nbegin hard cancel test with unprotected lane body\n" |
| 209 | h = lanes.gen( "*", laneBody)( "receive", nil) | ||
| 187 | 210 | ||
| 188 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it | 211 | -- wait 2s before cancelling the lane |
| 189 | h:cancel() | 212 | print "wait 2s" |
| 213 | linda:receive( 2, "yeah") | ||
| 190 | 214 | ||
| 191 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 215 | -- hard cancel: the lane will be interrupted from inside its current linda:receive() and won't return from it |
| 192 | waitCancellation( h, "cancelled") | 216 | print "cancelling" |
| 217 | h:cancel() | ||
| 193 | 218 | ||
| 194 | print "\n\n####################################################################\nbegin kill cancel test\n" | 219 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error |
| 195 | h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane | 220 | waitCancellation( h, "cancelled") |
| 221 | end | ||
| 196 | 222 | ||
| 197 | -- wait 1/3s before cancelling the lane, before the busy loop can finish | 223 | if not next(which_tests) or which_tests.kill then |
| 198 | print "wait 0.3s" | 224 | remaining_tests.kill = nil |
| 199 | linda:receive( 0.3, "yeah") | 225 | print "\n\n####################################################################\nbegin kill cancel test\n" |
| 226 | h = lanes.gen( "*", laneBody)( "busy", 50000000) -- start a pure Lua busy loop lane | ||
| 200 | 227 | ||
| 201 | -- hard cancel with kill: the lane thread will be forcefully terminated | 228 | -- wait 1/3s before cancelling the lane, before the busy loop can finish |
| 202 | h:cancel( true) | 229 | print "wait 0.3s" |
| 230 | linda:receive( 0.3, "yeah") | ||
| 203 | 231 | ||
| 204 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | 232 | -- hard cancel with kill: the lane thread will be forcefully terminated. kill timeout is pthread-specific |
| 205 | waitCancellation( h, "killed") | 233 | print "cancelling" |
| 234 | h:cancel( true, 1.0) | ||
| 206 | 235 | ||
| 236 | -- wait until cancellation is effective. the lane will be stopped by the linda operation throwing an error | ||
| 237 | waitCancellation( h, "killed") | ||
| 238 | end | ||
| 207 | --#################################################################### | 239 | --#################################################################### |
| 208 | 240 | ||
| 209 | print "\ndone" | 241 | local unknown_test, val = next(remaining_tests) |
| 242 | assert(not unknown_test, tostring(unknown_test) .. " test is unknown") | ||
| 210 | 243 | ||
| 244 | 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() | |||
| 4 | 4 | ||
| 5 | local coro = coroutine.create(function() end) | 5 | local coro = coroutine.create(function() end) |
| 6 | 6 | ||
| 7 | local fun = function() print "fun" end | ||
| 8 | local t_in = { [fun] = fun, fun = fun } | ||
| 9 | |||
| 10 | -- send a string | ||
| 11 | print( pcall(linda.send,linda, 'test', "oh boy")) | ||
| 12 | -- send a table that contains a function | ||
| 13 | print( pcall(linda.send,linda, 'test', t_in)) | ||
| 7 | -- we are not allowed to send coroutines through a lanes | 14 | -- we are not allowed to send coroutines through a lanes |
| 8 | -- however, this should raise an error, not hang the program... | 15 | -- however, this should raise an error, not hang the program... |
| 9 | print( pcall(linda.send,linda, 'test', "oh boy")) | ||
| 10 | print( pcall(linda.send,linda, 'test', coro)) | 16 | print( pcall(linda.send,linda, 'test', coro)) |
| 11 | k,res = linda:receive('test') | 17 | k,str = linda:receive('test') -- read the contents successfully sent |
| 12 | print( res) | 18 | print( str) -- "oh boy" |
| 19 | k,t_out = linda:receive('test') -- read the contents successfully sent | ||
| 20 | t_out.fun() -- "fun" | ||
| 13 | -- linda:send( 'test', coro) | 21 | -- linda:send( 'test', coro) |
| 22 | 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 @@ | |||
| 6 | 6 | ||
| 7 | local lanes = require "lanes".configure{shutdown_timeout=3,with_timers=true} | 7 | local lanes = require "lanes".configure{shutdown_timeout=3,with_timers=true} |
| 8 | 8 | ||
| 9 | local linda = lanes.linda( "atom") | 9 | local atomic_linda = lanes.linda( "atom") |
| 10 | local atomic_inc= lanes.genatomic( linda, "FIFO_n") | 10 | local atomic_inc= lanes.genatomic( atomic_linda, "FIFO_n") |
| 11 | |||
| 12 | local fifo_linda = lanes.linda( "fifo") | ||
| 11 | 13 | ||
| 12 | assert( atomic_inc()==1) | 14 | assert( atomic_inc()==1) |
| 13 | assert( atomic_inc()==2) | 15 | assert( atomic_inc()==2) |
| 14 | 16 | ||
| 15 | local function FIFO() | 17 | local function FIFO() |
| 16 | local my_channel= "FIFO"..atomic_inc() | 18 | local my_channel= "FIFO_"..atomic_inc() |
| 17 | 19 | ||
| 18 | return { | 20 | return { |
| 19 | -- Giving explicit 'nil' timeout allows numbers to be used as 'my_channel' | 21 | -- Giving explicit 'nil' timeout allows numbers to be used as 'my_channel' |
| 20 | -- | 22 | -- |
| 21 | send = function(self, ...) | 23 | send = function(self, ...) |
| 22 | linda:send( nil, my_channel, ...) | 24 | fifo_linda:send( nil, my_channel, ...) |
| 23 | end, | 25 | end, |
| 24 | receive = function(self, timeout) | 26 | receive = function(self, timeout) |
| 25 | return linda:receive( timeout, my_channel) | 27 | return fifo_linda:receive( timeout, my_channel) |
| 26 | end | 28 | end, |
| 29 | channel = my_channel | ||
| 27 | } | 30 | } |
| 28 | end | 31 | end |
| 29 | 32 | ||
| @@ -36,11 +39,38 @@ A:send( 1,2,3,4,5) | |||
| 36 | print "Sending to B.." | 39 | print "Sending to B.." |
| 37 | B:send( 'a','b','c') | 40 | B:send( 'a','b','c') |
| 38 | 41 | ||
| 42 | print "Dumping linda stats.. [1]" -- count everything | ||
| 43 | for key,count in pairs(fifo_linda:count()) do | ||
| 44 | print("channel " .. key .. " contains " .. count .. " entries.") | ||
| 45 | -- print(i, key_count[1], key_count[2]) | ||
| 46 | end | ||
| 47 | print "Dumping linda stats.. [2]" -- query count for known channels one at a time | ||
| 48 | print("channel " .. A.channel .. " contains " .. fifo_linda:count(A.channel) .. " entries.") | ||
| 49 | print("channel " .. B.channel .. " contains " .. fifo_linda:count(B.channel) .. " entries.") | ||
| 50 | print "Dumping linda stats.. [3]" -- query counts for a predefined list of keys | ||
| 51 | for key,count in pairs(fifo_linda:count(A.channel, B.channel)) do | ||
| 52 | print("channel " .. key .. " contains " .. count .. " entries.") | ||
| 53 | -- print(i, key_count[1], key_count[2]) | ||
| 54 | end | ||
| 55 | print "Dumping linda stats.. [4]" -- count everything | ||
| 56 | for key,contents in pairs(fifo_linda:dump()) do | ||
| 57 | print("channel " .. key .. ": limit=".. contents.limit, " first=" .. contents.first, " count=" .. contents.count) | ||
| 58 | for k,v in pairs(contents.fifo) do | ||
| 59 | print("[".. k.."] = " .. v) | ||
| 60 | end | ||
| 61 | end | ||
| 62 | |||
| 39 | print "Reading A.." | 63 | print "Reading A.." |
| 40 | print( A:receive( 1.0)) | 64 | print( A:receive( 1.0)) |
| 65 | print( A:receive( 1.0)) | ||
| 66 | print( A:receive( 1.0)) | ||
| 67 | print( A:receive( 1.0)) | ||
| 68 | print( A:receive( 1.0)) | ||
| 41 | 69 | ||
| 42 | print "Reading B.." | 70 | print "Reading B.." |
| 43 | print( B:receive( 2.0)) | 71 | print( B:receive( 2.0)) |
| 72 | print( B:receive( 2.0)) | ||
| 73 | print( B:receive( 2.0)) | ||
| 44 | 74 | ||
| 45 | -- Note: A and B can be passed between threads, or used as upvalues | 75 | -- Note: A and B can be passed between threads, or used as upvalues |
| 46 | -- by multiple threads (other parts will be copied but the 'linda' | 76 | -- 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 @@ | |||
| 4 | -- Test program for Lua Lanes | 4 | -- Test program for Lua Lanes |
| 5 | -- | 5 | -- |
| 6 | 6 | ||
| 7 | local lanes = require "lanes".configure{ with_timers = false, nb_keepers = 200} | 7 | local lanes = require "lanes".configure{ with_timers = false, nb_keepers = 1, keepers_gc_threshold = 500} |
| 8 | |||
| 9 | do | ||
| 10 | print "Linda names test:" | ||
| 11 | local unnamedLinda = lanes.linda() | ||
| 12 | local unnamedLinda2 = lanes.linda("") | ||
| 13 | local veeeerrrryyyylooongNamedLinda= lanes.linda( "veeeerrrryyyylooongNamedLinda", 1) | ||
| 14 | print(unnamedLinda, unnamedLinda2, veeeerrrryyyylooongNamedLinda) | ||
| 15 | print "GC deadlock test start" | ||
| 16 | -- store a linda in another linda (-> in a keeper) | ||
| 17 | unnamedLinda:set("here", lanes.linda("temporary linda")) | ||
| 18 | -- repeatedly add and remove stuff in the linda so that a GC happens during the keeper operation | ||
| 19 | for i = 1, 1000 do | ||
| 20 | for j = 1, 1000 do -- send 1000 tables | ||
| 21 | unnamedLinda:send("here", {"a", "table", "with", "some", "stuff"}) | ||
| 22 | end | ||
| 23 | unnamedLinda:set("here") -- clear everything | ||
| 24 | end | ||
| 25 | end | ||
| 26 | print "collecting garbage" | ||
| 27 | collectgarbage() | ||
| 28 | print "GC deadlock test done" | ||
| 29 | |||
| 30 | local print_id = 0 | ||
| 31 | local PRINT = function(...) | ||
| 32 | print_id = print_id + 1 | ||
| 33 | print("main", print_id .. ".", ...) | ||
| 34 | end | ||
| 8 | 35 | ||
| 9 | local function keeper(linda) | 36 | local function keeper(linda) |
| 10 | local mt= { | 37 | local mt= { |
| @@ -25,23 +52,49 @@ local A= keeper( lindaA ) | |||
| 25 | local lindaB= lanes.linda( "B", 2) | 52 | local lindaB= lanes.linda( "B", 2) |
| 26 | local B= keeper( lindaB ) | 53 | local B= keeper( lindaB ) |
| 27 | 54 | ||
| 55 | local lindaC= lanes.linda( "C", 3) | ||
| 56 | local C= keeper( lindaC ) | ||
| 57 | print("Created", lindaA, lindaB, lindaC) | ||
| 58 | |||
| 28 | A.some= 1 | 59 | A.some= 1 |
| 29 | print( A.some ) | 60 | PRINT("A.some == " .. A.some ) |
| 30 | assert( A.some==1 ) | 61 | assert( A.some==1 ) |
| 31 | 62 | ||
| 32 | B.some= "hoo" | 63 | B.some= "hoo" |
| 64 | PRINT("B.some == " .. B.some ) | ||
| 33 | assert( B.some=="hoo" ) | 65 | assert( B.some=="hoo" ) |
| 34 | assert( A.some==1 ) | 66 | assert( A.some==1 ) |
| 67 | assert( C.some==nil ) | ||
| 35 | 68 | ||
| 36 | function lane() | 69 | function lane() |
| 70 | local print_id = 0 | ||
| 71 | local PRINT = function(...) | ||
| 72 | print_id = print_id + 1 | ||
| 73 | print("lane", print_id .. ".", ...) | ||
| 74 | end | ||
| 75 | |||
| 37 | local a= keeper(lindaA) | 76 | local a= keeper(lindaA) |
| 38 | print( a.some ) | 77 | PRINT("a.some == " .. a.some ) |
| 39 | assert( a.some==1 ) | 78 | assert( a.some==1 ) |
| 40 | a.some= 2 | 79 | a.some= 2 |
| 80 | assert( a.some==2 ) | ||
| 81 | PRINT("a.some == " .. a.some ) | ||
| 82 | |||
| 83 | local c = keeper(lindaC) | ||
| 84 | assert( c.some==nil ) | ||
| 85 | PRINT("c.some == " .. tostring(c.some)) | ||
| 86 | c.some= 3 | ||
| 87 | assert( c.some==3 ) | ||
| 88 | PRINT("c.some == " .. c.some) | ||
| 41 | end | 89 | end |
| 42 | 90 | ||
| 91 | PRINT("lane started") | ||
| 43 | local h= lanes.gen( "io", lane )() | 92 | local h= lanes.gen( "io", lane )() |
| 44 | h:join() | 93 | PRINT("lane joined:", h:join()) |
| 45 | 94 | ||
| 46 | print( A.some ) -- 2 | 95 | PRINT("A.some = " .. A.some ) |
| 47 | assert( A.some==2 ) | 96 | assert( A.some==2 ) |
| 97 | PRINT("C.some = " .. C.some ) | ||
| 98 | assert( C.some==3 ) | ||
| 99 | lindaC:set("some") | ||
| 100 | 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 @@ | |||
| 1 | local lanes = require "lanes" | 1 | local lanes = require "lanes" |
| 2 | lanes.configure{ with_timers = false} | 2 | lanes.configure{ with_timers = false, keepers_gc_threshold=30000 } |
| 3 | |||
| 4 | -- set TEST1, PREFILL1, FILL1, TEST2, PREFILL2, FILL2 from the command line | ||
| 3 | 5 | ||
| 4 | -- Lua 5.1/5.2 compatibility | 6 | -- Lua 5.1/5.2 compatibility |
| 5 | local table_unpack = unpack or table.unpack | 7 | local table_unpack = unpack or table.unpack |
| 6 | 8 | ||
| 9 | local finalizer = function(err, stk) | ||
| 10 | if err == lanes.cancel_error then | ||
| 11 | -- note that we don't get the cancel_error when running wrapped inside a protected call if it doesn't rethrow it | ||
| 12 | print(" laneBody after cancel" ) | ||
| 13 | elseif err then | ||
| 14 | print(" laneBody error: "..tostring(err)) | ||
| 15 | else | ||
| 16 | print(" laneBody finalized") | ||
| 17 | end | ||
| 18 | end | ||
| 19 | |||
| 20 | --################################################################################################## | ||
| 21 | |||
| 7 | -- this lane eats items in the linda one by one | 22 | -- this lane eats items in the linda one by one |
| 8 | local eater = function( l, loop) | 23 | local eater = function( l, loop) |
| 24 | set_finalizer(finalizer) | ||
| 9 | -- wait for start signal | 25 | -- wait for start signal |
| 10 | l:receive( "go") | 26 | l:receive( "go") |
| 11 | -- eat data one by one | 27 | -- eat data one by one |
| 12 | for i = 1, loop do | 28 | for i = 1, loop do |
| 13 | local val, key = l:receive( "key") | 29 | local key, val = l:receive( "key") |
| 14 | --print( val) | 30 | -- print("eater:", val) |
| 15 | end | 31 | end |
| 16 | -- print "loop is over" | 32 | -- print "loop is over" |
| 17 | key, val = l:receive( "done") | 33 | key, val = l:receive( "done") |
| 18 | -- print( val) | 34 | print("eater: done ("..val..")") |
| 19 | end | 35 | end |
| 20 | 36 | ||
| 37 | --################################################################################################## | ||
| 38 | |||
| 21 | -- this lane eats items in the linda in batches | 39 | -- this lane eats items in the linda in batches |
| 22 | local batched = function( l, loop, batch) | 40 | local gobbler = function( l, loop, batch) |
| 41 | set_finalizer(finalizer) | ||
| 23 | -- wait for start signal | 42 | -- wait for start signal |
| 24 | l:receive( "go") | 43 | l:receive( "go") |
| 25 | -- eat data in batches | 44 | -- eat data in batches |
| 26 | for i = 1, loop/batch do | 45 | for i = 1, loop/batch do |
| 27 | l:receive( l.batched, "key", batch) | 46 | l:receive( l.batched, "key", batch) |
| 47 | -- print("gobbler:", batch) | ||
| 28 | end | 48 | end |
| 29 | print "loop is over" | 49 | print "loop is over" |
| 30 | key, val = l:receive( "done") | 50 | key, val = l:receive( "done") |
| 31 | print( val) | 51 | print("gobbler: done ("..val..")") |
| 32 | end | 52 | end |
| 33 | 53 | ||
| 54 | --################################################################################################## | ||
| 55 | |||
| 34 | local lane_eater_gen = lanes.gen( "*", {priority = 3}, eater) | 56 | local lane_eater_gen = lanes.gen( "*", {priority = 3}, eater) |
| 35 | local lane_batched_gen = lanes.gen( "*", {priority = 3}, batched) | 57 | local lane_gobbler_gen = lanes.gen( "*", {priority = 3}, gobbler) |
| 58 | |||
| 59 | --################################################################################################## | ||
| 36 | 60 | ||
| 37 | -- main thread writes data while a lane reads it | 61 | -- main thread writes data while a lane reads it |
| 38 | local function ziva( preloop, loop, batch) | 62 | local function ziva( preloop, loop, batch) |
| @@ -46,7 +70,7 @@ local function ziva( preloop, loop, batch) | |||
| 46 | print( "stored " .. l:count( "key") .. " items in the linda before starting consumer lane") | 70 | print( "stored " .. l:count( "key") .. " items in the linda before starting consumer lane") |
| 47 | if batch > 0 then | 71 | if batch > 0 then |
| 48 | if l.batched then | 72 | if l.batched then |
| 49 | lane = lane_batched_gen( l, top, batch) | 73 | lane = lane_gobbler_gen( l, top, batch) |
| 50 | else | 74 | else |
| 51 | print "no batch support in this version of Lanes" | 75 | print "no batch support in this version of Lanes" |
| 52 | lane = lane_eater_gen( l, top) | 76 | lane = lane_eater_gen( l, top) |
| @@ -63,7 +87,9 @@ local function ziva( preloop, loop, batch) | |||
| 63 | for i = 1, batch do | 87 | for i = 1, batch do |
| 64 | table.insert( batch_values, i) | 88 | table.insert( batch_values, i) |
| 65 | end | 89 | end |
| 90 | local batch_send_log = "main: sending "..batch.." values" | ||
| 66 | local batch_send = function() | 91 | local batch_send = function() |
| 92 | -- print(batch_send_log) | ||
| 67 | l:send( "key", table_unpack( batch_values)) | 93 | l:send( "key", table_unpack( batch_values)) |
| 68 | end | 94 | end |
| 69 | if loop > preloop then | 95 | if loop > preloop then |
| @@ -76,57 +102,35 @@ local function ziva( preloop, loop, batch) | |||
| 76 | return lanes.now_secs() - t1 | 102 | return lanes.now_secs() - t1 |
| 77 | end | 103 | end |
| 78 | 104 | ||
| 105 | --################################################################################################## | ||
| 106 | |||
| 107 | TEST1 = TEST1 or 1000 | ||
| 108 | PREFILL1 = PREFILL1 or 10000 | ||
| 109 | FILL1 = FILL1 or 2000000 | ||
| 110 | |||
| 79 | local tests1 = | 111 | local tests1 = |
| 80 | { | 112 | { |
| 81 | { 10000, 2000000, 0}, | 113 | { PREFILL1, FILL1, 0}, |
| 82 | { 10000, 2000000, 1}, | 114 | { PREFILL1, FILL1, 1}, |
| 83 | { 10000, 2000000, 2}, | 115 | { PREFILL1, FILL1, 2}, |
| 84 | { 10000, 2000000, 3}, | 116 | { PREFILL1, FILL1, 3}, |
| 85 | { 10000, 2000000, 5}, | 117 | { PREFILL1, FILL1, 5}, |
| 86 | { 10000, 2000000, 8}, | 118 | { PREFILL1, FILL1, 8}, |
| 87 | { 10000, 2000000, 13}, | 119 | { PREFILL1, FILL1, 13}, |
| 88 | { 10000, 2000000, 21}, | 120 | { PREFILL1, FILL1, 21}, |
| 89 | { 10000, 2000000, 44}, | 121 | { PREFILL1, FILL1, 44}, |
| 122 | { PREFILL1, FILL1, 65}, | ||
| 90 | } | 123 | } |
| 91 | print "############################################\ntests #1" | 124 | print "############################################ tests #1" |
| 92 | for k, v in pairs( tests1) do | 125 | for i, v in ipairs( tests1) do |
| 126 | if i > TEST1 then break end | ||
| 93 | local pre, loop, batch = v[1], v[2], v[3] | 127 | local pre, loop, batch = v[1], v[2], v[3] |
| 94 | print( "testing", pre, loop, batch) | 128 | print("-------------------------------------------------\n") |
| 95 | print( pre, loop, batch, "duration = " .. ziva( pre, loop, batch) .. "\n") | 129 | print("START", "prefill="..pre, "fill="..loop, "batch="..batch) |
| 130 | print("DURATION = " .. ziva( pre, loop, batch) .. "\n") | ||
| 96 | end | 131 | end |
| 97 | 132 | ||
| 98 | --[[ | 133 | --################################################################################################## |
| 99 | V 2.1.0: | ||
| 100 | ziva( 20000, 0) -> 4s ziva( 10000, 20000) -> 3s | ||
| 101 | ziva( 30000, 0) -> 8s ziva( 20000, 30000) -> 7s | ||
| 102 | ziva( 40000, 0) -> 15s ziva( 30000, 40000) -> 15s | ||
| 103 | ziva( 50000, 0) -> 24s ziva( 40000, 50000) -> 23s | ||
| 104 | ziva( 60000, 0) -> 34s ziva( 50000, 60000) -> 33s | ||
| 105 | |||
| 106 | SIMPLIFIED: | ||
| 107 | ziva( 20000, 0) -> 4s ziva( 10000, 20000) -> 3s | ||
| 108 | ziva( 30000, 0) -> 9s ziva( 20000, 30000) -> 8s | ||
| 109 | ziva( 40000, 0) -> 15s ziva( 30000, 40000) -> 15s | ||
| 110 | ziva( 50000, 0) -> 25s ziva( 40000, 50000) -> 24s | ||
| 111 | ziva( 60000, 0) -> 35s ziva( 50000, 60000) -> 35s | ||
| 112 | |||
| 113 | FIFO: | ||
| 114 | ziva( 2000000, 0) -> 9s ziva( 1000000, 2000000) -> 33s | ||
| 115 | ziva( 3000000, 0) -> 14s ziva( 2000000, 3000000) -> 40s | ||
| 116 | ziva( 4000000, 0) -> 20s ziva( 3000000, 4000000) -> 27s | ||
| 117 | ziva( 5000000, 0) -> 24s ziva( 4000000, 5000000) -> 42s | ||
| 118 | ziva( 6000000, 0) -> 29s ziva( 5000000, 6000000) -> 55s | ||
| 119 | |||
| 120 | FIFO BATCHED: | ||
| 121 | ziva( 4000000, 0, 1) -> 20s | ||
| 122 | ziva( 4000000, 0, 2) -> 11s | ||
| 123 | ziva( 4000000, 0, 3) -> 7s | ||
| 124 | ziva( 4000000, 0, 5) -> 5s | ||
| 125 | ziva( 4000000, 0, 8) -> 3s | ||
| 126 | ziva( 4000000, 0, 13) -> 3s | ||
| 127 | ziva( 4000000, 0, 21) -> 3s | ||
| 128 | ziva( 4000000, 0, 44) -> 2s | ||
| 129 | ]] | ||
| 130 | 134 | ||
| 131 | -- sequential write/read (no parallelization involved) | 135 | -- sequential write/read (no parallelization involved) |
| 132 | local function ziva2( preloop, loop, batch) | 136 | local function ziva2( preloop, loop, batch) |
| @@ -159,7 +163,7 @@ local function ziva2( preloop, loop, batch) | |||
| 159 | for i = 1, preloop, step do | 163 | for i = 1, preloop, step do |
| 160 | batch_send() | 164 | batch_send() |
| 161 | end | 165 | end |
| 162 | print( "stored " .. (l:count( "key") or 0) .. " items in the linda before starting consumer lane") | 166 | print( "stored " .. (l:count( "key") or 0) .. " items in the linda before starting the alternating reads and writes") |
| 163 | -- loop that alternatively sends and reads data off the linda | 167 | -- loop that alternatively sends and reads data off the linda |
| 164 | if loop > preloop then | 168 | if loop > preloop then |
| 165 | for i = preloop + 1, loop, step do | 169 | for i = preloop + 1, loop, step do |
| @@ -169,40 +173,39 @@ local function ziva2( preloop, loop, batch) | |||
| 169 | end | 173 | end |
| 170 | -- here, we have preloop elements still waiting inside the linda | 174 | -- here, we have preloop elements still waiting inside the linda |
| 171 | for i = 1, preloop, step do | 175 | for i = 1, preloop, step do |
| 172 | batch_read() | 176 | batch_read() |
| 173 | end | 177 | end |
| 174 | return lanes.now_secs() - t1 | 178 | return lanes.now_secs() - t1 |
| 175 | end | 179 | end |
| 176 | 180 | ||
| 181 | --################################################################################################## | ||
| 182 | |||
| 183 | TEST2 = TEST2 or 1000 | ||
| 184 | PREFILL2 = PREFILL2 or 0 | ||
| 185 | FILL2 = FILL2 or 4000000 | ||
| 186 | |||
| 177 | local tests2 = | 187 | local tests2 = |
| 178 | { | 188 | { |
| 179 | -- prefill, then consume everything | 189 | { PREFILL2, FILL2}, |
| 180 | --[[ | 190 | { PREFILL2, FILL2, 1}, |
| 181 | { 4000000, 0}, | 191 | { PREFILL2, FILL2, 2}, |
| 182 | { 4000000, 0, 1}, | 192 | { PREFILL2, FILL2, 3}, |
| 183 | { 4000000, 0, 2}, | 193 | { PREFILL2, FILL2, 5}, |
| 184 | { 4000000, 0, 3}, | 194 | { PREFILL2, FILL2, 8}, |
| 185 | { 4000000, 0, 5}, | 195 | { PREFILL2, FILL2, 13}, |
| 186 | { 4000000, 0, 8}, | 196 | { PREFILL2, FILL2, 21}, |
| 187 | { 4000000, 0, 13}, | 197 | { PREFILL2, FILL2, 44}, |
| 188 | { 4000000, 0, 21}, | 198 | { PREFILL2, FILL2, 65}, |
| 189 | { 4000000, 0, 44}, | ||
| 190 | --]] | ||
| 191 | -- alternatively fill and consume | ||
| 192 | { 0, 4000000}, | ||
| 193 | { 0, 4000000, 1}, | ||
| 194 | { 0, 4000000, 2}, | ||
| 195 | { 0, 4000000, 3}, | ||
| 196 | { 0, 4000000, 5}, | ||
| 197 | { 0, 4000000, 8}, | ||
| 198 | { 0, 4000000, 13}, | ||
| 199 | { 0, 4000000, 21}, | ||
| 200 | { 0, 4000000, 44}, | ||
| 201 | } | 199 | } |
| 202 | 200 | ||
| 203 | print "\n############################################\ntests #2" | 201 | print "############################################ tests #2" |
| 204 | for k, v in pairs( tests2) do | 202 | for i, v in ipairs( tests2) do |
| 203 | if i > TEST2 then break end | ||
| 205 | local pre, loop, batch = v[1], v[2], v[3] | 204 | local pre, loop, batch = v[1], v[2], v[3] |
| 206 | print( "testing", pre, loop, batch) | 205 | print("-------------------------------------------------\n") |
| 207 | print( pre, loop, batch, "duration = " .. ziva2( pre, loop, batch) .. "\n") | 206 | print("START", "prefill="..pre, "fill="..loop, "batch="..(batch or "no")) |
| 207 | print("DURATION = " .. ziva2( pre, loop, batch) .. "\n") | ||
| 208 | end | 208 | end |
| 209 | |||
| 210 | print "############################################" | ||
| 211 | 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 | |||
| 46 | end | 46 | end |
| 47 | 47 | ||
| 48 | -- wait for completion | 48 | -- wait for completion |
| 49 | print "wait for completion" | ||
| 49 | linda:receive( linda.batched, "key", COUNT) | 50 | linda:receive( linda.batched, "key", COUNT) |
| 51 | print "waiting a bit more ..." | ||
| 52 | linda:receive( 1, "foo") | ||
| 50 | print "SUCCESS" | 53 | 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 | |||
| 18 | 18 | ||
| 19 | local T1= "1s" -- these keys can be anything... | 19 | local T1= "1s" -- these keys can be anything... |
| 20 | local T2= "5s" | 20 | local T2= "5s" |
| 21 | local PING_DURATION = 20 | ||
| 21 | 22 | ||
| 22 | local step= {} | 23 | local step= {} |
| 23 | 24 | ||
| 24 | lanes.timer( linda, T1, 1.0, 1.0 ) | 25 | lanes.timer( linda, T1, 1.0, 1.0 ) |
| 25 | step[T1]= 1.0 | 26 | step[T1]= 1.0 |
| 26 | 27 | ||
| 27 | PRINT( "\n*** Timers every second (not synced to wall clock) ***\n" ) | 28 | PRINT( "\n*** Starting 1s Timer (not synced to wall clock) ***\n" ) |
| 28 | 29 | ||
| 29 | local v_first | 30 | local v_first |
| 30 | local v_last= {} -- { [channel]= num } | 31 | local v_last= {} -- { [channel]= num } |
| @@ -46,14 +47,15 @@ while true do | |||
| 46 | -- do not make measurements, first round is not 5secs due to wall clock adjustment | 47 | -- do not make measurements, first round is not 5secs due to wall clock adjustment |
| 47 | T2_first_round= false | 48 | T2_first_round= false |
| 48 | else | 49 | else |
| 49 | assert( math.abs(v-v_last[channel]- step[channel]) < 0.02 ) | 50 | local dt = math.abs(v-v_last[channel]- step[channel]) |
| 51 | assert( dt < 0.02, "channel " .. channel .. " is late: " .. dt) | ||
| 50 | end | 52 | end |
| 51 | end | 53 | end |
| 52 | 54 | ||
| 53 | if not v_first then | 55 | if not v_first then |
| 54 | v_first= v | 56 | v_first= v |
| 55 | elseif v-v_first > 3.0 and (not step[T2]) then | 57 | elseif v-v_first > 3.0 and (not step[T2]) then |
| 56 | PRINT( "\n*** Adding timers every 5 second (synced to wall clock) ***\n" ) | 58 | PRINT( "\n*** Starting 5s timer (synced to wall clock) ***\n" ) |
| 57 | 59 | ||
| 58 | -- The first event can be in the past (just cut seconds down to 5s) | 60 | -- The first event can be in the past (just cut seconds down to 5s) |
| 59 | -- | 61 | -- |
| @@ -63,7 +65,7 @@ while true do | |||
| 63 | lanes.timer( linda, T2, date, 5.0 ) | 65 | lanes.timer( linda, T2, date, 5.0 ) |
| 64 | step[T2]= 5.0 | 66 | step[T2]= 5.0 |
| 65 | 67 | ||
| 66 | elseif v-v_first > 10 then -- exit condition | 68 | elseif v-v_first > PING_DURATION then -- exit condition |
| 67 | break | 69 | break |
| 68 | end | 70 | end |
| 69 | v_last[channel]= v | 71 | v_last[channel]= v |
| @@ -80,7 +82,7 @@ PRINT( "\n*** Listing timers ***\n" ) | |||
| 80 | local r = lanes.timers() -- list of {linda, key, {}} | 82 | local r = lanes.timers() -- list of {linda, key, {}} |
| 81 | for _,t in ipairs( r) do | 83 | for _,t in ipairs( r) do |
| 82 | local linda, key, timer = t[1], t[2], t[3] | 84 | local linda, key, timer = t[1], t[2], t[3] |
| 83 | print( tostring( linda), key, timer[1], timer[2]) | 85 | print( tostring( linda), key, timer[1], timer[2]) |
| 84 | end | 86 | end |
| 85 | 87 | ||
| 86 | 88 | ||
