aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/_pch.hpp4
-rw-r--r--src/linda.cpp10
-rw-r--r--src/linda.hpp2
-rw-r--r--src/macros_and_utils.hpp1
-rw-r--r--tests/track_lanes.lua6
-rw-r--r--unit_tests/UnitTests.vcxproj1
-rw-r--r--unit_tests/UnitTests.vcxproj.filters3
-rw-r--r--unit_tests/_pch.hpp2
-rw-r--r--unit_tests/embedded_tests.cpp5
-rw-r--r--unit_tests/linda_tests.cpp17
-rw-r--r--unit_tests/scripts/linda/wake_period.lua41
-rw-r--r--unit_tests/shared.cpp1
12 files changed, 72 insertions, 21 deletions
diff --git a/src/_pch.hpp b/src/_pch.hpp
index 495a959..a77b7f5 100644
--- a/src/_pch.hpp
+++ b/src/_pch.hpp
@@ -1,5 +1,3 @@
1#pragma once
2
3#include <algorithm> 1#include <algorithm>
4#include <array> 2#include <array>
5#include <atomic> 3#include <atomic>
@@ -9,6 +7,7 @@
9#include <compare> 7#include <compare>
10#include <concepts> 8#include <concepts>
11#include <condition_variable> 9#include <condition_variable>
10#include <cstring>
12#include <functional> 11#include <functional>
13#include <iostream> 12#include <iostream>
14#ifndef __PROSPERO__ 13#ifndef __PROSPERO__
@@ -19,6 +18,7 @@
19#include <ranges> 18#include <ranges>
20#include <source_location> 19#include <source_location>
21//#include <stop_token> 20//#include <stop_token>
21#include <span>
22#include <string_view> 22#include <string_view>
23#include <thread> 23#include <thread>
24#include <tuple> 24#include <tuple>
diff --git a/src/linda.cpp b/src/linda.cpp
index a9ae61c..fa28385 100644
--- a/src/linda.cpp
+++ b/src/linda.cpp
@@ -1178,7 +1178,15 @@ LUAG_FUNC(linda)
1178 if (lua_isnil(L_, kIdxTop)) { 1178 if (lua_isnil(L_, kIdxTop)) {
1179 lua_pop(L_, 1); 1179 lua_pop(L_, 1);
1180 lua_pushnumber(L_, _U->lindaWakePeriod.count()); 1180 lua_pushnumber(L_, _U->lindaWakePeriod.count());
1181 } else { 1181 } else if (luaG_type(L_, kIdxTop) == LuaType::STRING) {
1182 if (luaG_tostring(L_, kIdxTop) != "never") {
1183 luaL_argerror(L_, 1, "invalid wake_period");
1184 } else {
1185 lua_pop(L_, 1);
1186 lua_pushnumber(L_, 0);
1187 }
1188 }
1189 else {
1182 luaL_argcheck(L_, luaL_optnumber(L_, 2, 0) > 0, 1, "wake_period must be > 0"); 1190 luaL_argcheck(L_, luaL_optnumber(L_, 2, 0) > 0, 1, "wake_period must be > 0");
1183 } 1191 }
1184 1192
diff --git a/src/linda.hpp b/src/linda.hpp
index 7874db3..cff30e5 100644
--- a/src/linda.hpp
+++ b/src/linda.hpp
@@ -18,7 +18,7 @@ class Linda final
18 { 18 {
19 private: 19 private:
20 Linda& linda; 20 Linda& linda;
21 [[maybe_unused]] lua_State* const L; // just here for inspection while debugging 21 lua_State* const L{}; // just here for inspection while debugging
22 22
23 public: 23 public:
24 KeeperOperationInProgress(Linda& linda_, lua_State* const L_) 24 KeeperOperationInProgress(Linda& linda_, lua_State* const L_)
diff --git a/src/macros_and_utils.hpp b/src/macros_and_utils.hpp
index 16011f7..1aca818 100644
--- a/src/macros_and_utils.hpp
+++ b/src/macros_and_utils.hpp
@@ -21,6 +21,7 @@ inline void STACK_GROW(lua_State* const L_, int const n_)
21 21
22// ################################################################################################# 22// #################################################################################################
23 23
24// 1 unit of lua_Duration lasts 1 second (using default period of std::ratio<1>)
24using lua_Duration = std::chrono::template duration<lua_Number>; 25using lua_Duration = std::chrono::template duration<lua_Number>;
25 26
26// ################################################################################################# 27// #################################################################################################
diff --git a/tests/track_lanes.lua b/tests/track_lanes.lua
index d1670ae..ef2ca06 100644
--- a/tests/track_lanes.lua
+++ b/tests/track_lanes.lua
@@ -59,8 +59,10 @@ local threads = track( "============= START", 2)
59-- two_seconds forever 59-- two_seconds forever
60assert(threads[1].status == 'waiting' and threads[2].status == 'waiting') 60assert(threads[1].status == 'waiting' and threads[2].status == 'waiting')
61 61
62-- wait until ephemeral1 has completed 62-- wait until ephemeral1 has completed, should take about 2 seconds
63SLEEP(2.1) 63repeat
64 SLEEP(0.1)
65until ephemeral1.status == "done"
64 66
65local threads = track( "============= two_seconds dead", 2) 67local threads = track( "============= two_seconds dead", 2)
66-- two_seconds forever 68-- two_seconds forever
diff --git a/unit_tests/UnitTests.vcxproj b/unit_tests/UnitTests.vcxproj
index e1370c3..8c22653 100644
--- a/unit_tests/UnitTests.vcxproj
+++ b/unit_tests/UnitTests.vcxproj
@@ -968,6 +968,7 @@
968 <ItemGroup> 968 <ItemGroup>
969 <None Include="..\.runsettings" /> 969 <None Include="..\.runsettings" />
970 <None Include="scripts\lane\tasking_cancelling_with_hook.lua" /> 970 <None Include="scripts\lane\tasking_cancelling_with_hook.lua" />
971 <None Include="scripts\linda\wake_period.lua" />
971 <None Include="UnitTests.makefile" /> 972 <None Include="UnitTests.makefile" />
972 <None Include="scripts\coro\basics.lua" /> 973 <None Include="scripts\coro\basics.lua" />
973 <None Include="scripts\coro\error_handling.lua" /> 974 <None Include="scripts\coro\error_handling.lua" />
diff --git a/unit_tests/UnitTests.vcxproj.filters b/unit_tests/UnitTests.vcxproj.filters
index b0ce216..ce8cb58 100644
--- a/unit_tests/UnitTests.vcxproj.filters
+++ b/unit_tests/UnitTests.vcxproj.filters
@@ -116,5 +116,8 @@
116 <None Include="scripts\lane\tasking_cancelling_with_hook.lua"> 116 <None Include="scripts\lane\tasking_cancelling_with_hook.lua">
117 <Filter>Scripts\lane</Filter> 117 <Filter>Scripts\lane</Filter>
118 </None> 118 </None>
119 <None Include="scripts\linda\wake_period.lua">
120 <Filter>Scripts\linda</Filter>
121 </None>
119 </ItemGroup> 122 </ItemGroup>
120</Project> \ No newline at end of file 123</Project> \ No newline at end of file
diff --git a/unit_tests/_pch.hpp b/unit_tests/_pch.hpp
index 1e98c5a..f6e5fff 100644
--- a/unit_tests/_pch.hpp
+++ b/unit_tests/_pch.hpp
@@ -1,5 +1,3 @@
1#pragma once
2
3#include <atomic> 1#include <atomic>
4#include <cassert> 2#include <cassert>
5#include <filesystem> 3#include <filesystem>
diff --git a/unit_tests/embedded_tests.cpp b/unit_tests/embedded_tests.cpp
index a0a7bb2..04a8f87 100644
--- a/unit_tests/embedded_tests.cpp
+++ b/unit_tests/embedded_tests.cpp
@@ -2,6 +2,7 @@
2#include "shared.h" 2#include "shared.h"
3#include "lanes/src/lanes.hpp" 3#include "lanes/src/lanes.hpp"
4 4
5#if defined __has_include && __has_include(<windows.h>)
5#include <windows.h> 6#include <windows.h>
6 7
7// ################################################################################################# 8// #################################################################################################
@@ -265,4 +266,6 @@ TEST_CASE("lanes.embedding.with custom allocator")
265 lua_close(L3); 266 lua_close(L3);
266 lua_close(L2); 267 lua_close(L2);
267 lua_close(L1); 268 lua_close(L1);
268} \ No newline at end of file 269}
270
271#endif // windows.h
diff --git a/unit_tests/linda_tests.cpp b/unit_tests/linda_tests.cpp
index 9dbaa85..d956ae2 100644
--- a/unit_tests/linda_tests.cpp
+++ b/unit_tests/linda_tests.cpp
@@ -104,16 +104,7 @@ TEST_CASE("linda.single_keeper.creation/wake_period")
104 S.requireFailure("lanes.linda{wake_period = -1}"); 104 S.requireFailure("lanes.linda{wake_period = -1}");
105 S.requireFailure("lanes.linda{wake_period = 0}"); 105 S.requireFailure("lanes.linda{wake_period = 0}");
106 S.requireSuccess("lanes.linda{wake_period = 0.0001}"); 106 S.requireSuccess("lanes.linda{wake_period = 0.0001}");
107} 107 S.requireSuccess("lanes.linda{wake_period = 'never'}");
108
109// #################################################################################################
110
111TEST_CASE("linda.single_keeper.wake_period")
112{
113 FAIL("TODO: check that wake_period works as expected");
114 // - use configure default if not provided
115 // - overrides default when provided
116 // - blocking operation wakes at the specified period
117} 108}
118 109
119// ################################################################################################# 110// #################################################################################################
@@ -397,17 +388,19 @@ TEST_CASE("scripted_tests." #DIR "." #FILE) \
397 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \ 388 _runner.performTest(FileRunnerParam{ #DIR "/" #FILE, TestType::AssertNoLuaError }); \
398} 389}
399 390
391MAKE_TEST_CASE(linda, multiple_keepers)
400MAKE_TEST_CASE(linda, send_receive) 392MAKE_TEST_CASE(linda, send_receive)
401MAKE_TEST_CASE(linda, send_registered_userdata) 393MAKE_TEST_CASE(linda, send_registered_userdata)
402MAKE_TEST_CASE(linda, multiple_keepers) 394MAKE_TEST_CASE(linda, wake_period)
403 395
404/* 396/*
405TEST_CASE("linda.scripted_tests") 397TEST_CASE("linda.scripted_tests")
406{ 398{
407 auto const& _testParam = GENERATE( 399 auto const& _testParam = GENERATE(
400 FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError },
408 FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError }, 401 FileRunnerParam{ "linda/send_receive", TestType::AssertNoLuaError },
409 FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError }, 402 FileRunnerParam{ "linda/send_registered_userdata", TestType::AssertNoLuaError },
410 FileRunnerParam{ "linda/multiple_keepers", TestType::AssertNoLuaError } 403 FileRunnerParam{ "linda/wake_period", TestType::AssertNoLuaError }
411 ); 404 );
412 405
413 FileRunner _runner(R"(.\unit_tests\scripts)"); 406 FileRunner _runner(R"(.\unit_tests\scripts)");
diff --git a/unit_tests/scripts/linda/wake_period.lua b/unit_tests/scripts/linda/wake_period.lua
new file mode 100644
index 0000000..e4a900d
--- /dev/null
+++ b/unit_tests/scripts/linda/wake_period.lua
@@ -0,0 +1,41 @@
1-- default wake period is 0.5 seconds
2local require_lanes_result_1, require_lanes_result_2 = require "lanes".configure{linda_wake_period = 0.5}
3local lanes = require_lanes_result_1
4
5-- a lane that performs a blocking operation for 2 seconds
6local body = function(linda_)
7 -- a blocking read that lasts longer than the tested wake_period values
8 linda_:receive(2, "empty_slot")
9 return true
10end
11
12-- if we don't cancel the lane, we should wait the whole duration
13local function check_wake_duration(linda_, expected_, do_cancel_)
14 local h = lanes.gen(body)(linda_)
15 -- wait until the linda is blocked
16 repeat until h.status == "waiting"
17 local t0 = lanes.now_secs()
18 -- soft cancel, no timeout, no waking
19 if do_cancel_ then
20 local result, reason = h:cancel('soft', 0, false)
21 -- should say there was a timeout, since the lane didn't actually cancel (normal since we did not wake it)
22 assert(result == false and reason == 'timeout', "unexpected cancel result")
23 end
24 -- this should wait until the linda wakes by itself before the actual receive timeout and sees the cancel request
25 h:join()
26 local t1 = lanes.now_secs()
27 local delta = t1 - t0
28 -- the linda should check for cancellation at about the expected period, not earlier
29 assert(delta >= expected_, tostring(linda_) .. " woke too early:" .. delta)
30 -- the lane shouldn't terminate too long after cancellation was processed
31 assert(delta <= expected_ * 1.1, tostring(linda_) .. " woke too late: " .. delta)
32end
33
34-- legacy behavior: linda waits until operation timeout
35check_wake_duration(lanes.linda{name = "A", wake_period = 'never'}, 2, true)
36-- early wake behavior: linda wakes after the expected time, sees a cancellation requests, and aborts the operation early
37check_wake_duration(lanes.linda{name = "B", wake_period = 0.25}, 0.25, true)
38check_wake_duration(lanes.linda{name = "C"}, 0.5, true) -- wake_period defaults to 0.5 (see above)
39check_wake_duration(lanes.linda{name = "D", wake_period = 1}, 1, true)
40-- even when there is a wake_period, the operation should reach full timeout if not cancelled early
41check_wake_duration(lanes.linda{name = "E", wake_period = 0.1}, 2, false)
diff --git a/unit_tests/shared.cpp b/unit_tests/shared.cpp
index 2e2af73..e70d5d8 100644
--- a/unit_tests/shared.cpp
+++ b/unit_tests/shared.cpp
@@ -476,6 +476,7 @@ void FileRunner::performTest(FileRunnerParam const& testParam_)
476 INFO(testParam_.script); 476 INFO(testParam_.script);
477 switch (testParam_.test) { 477 switch (testParam_.test) {
478 case TestType::AssertNoLuaError: 478 case TestType::AssertNoLuaError:
479 lua_atpanic(L, _atPanic);
479 requireSuccess(root, testParam_.script); 480 requireSuccess(root, testParam_.script);
480 break; 481 break;
481 482