diff options
Diffstat (limited to 'src/lanes.cpp')
-rw-r--r-- | src/lanes.cpp | 74 |
1 files changed, 37 insertions, 37 deletions
diff --git a/src/lanes.cpp b/src/lanes.cpp index 4dd9b46..12cd7ef 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp | |||
@@ -126,8 +126,8 @@ bool Lane::waitForCompletion(lua_Duration duration_) | |||
126 | 126 | ||
127 | std::unique_lock lock{ m_done_mutex }; | 127 | std::unique_lock lock{ m_done_mutex }; |
128 | //std::stop_token token{ m_thread.get_stop_token() }; | 128 | //std::stop_token token{ m_thread.get_stop_token() }; |
129 | //return m_done_signal.wait_for(lock, token, secs_, [this](){ return status >= DONE; }); | 129 | //return m_done_signal.wait_until(lock, token, secs_, [this](){ return m_status >= Lane::Done; }); |
130 | return m_done_signal.wait_until(lock, until, [this](){ return status >= DONE; }); | 130 | return m_done_signal.wait_until(lock, until, [this](){ return m_status >= Lane::Done; }); |
131 | } | 131 | } |
132 | 132 | ||
133 | static void lane_main(Lane* lane); | 133 | static void lane_main(Lane* lane); |
@@ -848,12 +848,12 @@ static void lane_main(Lane* lane) | |||
848 | // wait until the launching thread has finished preparing L | 848 | // wait until the launching thread has finished preparing L |
849 | lane->m_ready.wait(); | 849 | lane->m_ready.wait(); |
850 | int rc{ LUA_ERRRUN }; | 850 | int rc{ LUA_ERRRUN }; |
851 | if (lane->status == PENDING) // nothing wrong happened during preparation, we can work | 851 | if (lane->m_status == Lane::Pending) // nothing wrong happened during preparation, we can work |
852 | { | 852 | { |
853 | // At this point, the lane function and arguments are on the stack | 853 | // At this point, the lane function and arguments are on the stack |
854 | int const nargs{ lua_gettop(L) - 1 }; | 854 | int const nargs{ lua_gettop(L) - 1 }; |
855 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); | 855 | DEBUGSPEW_CODE(Universe* U = universe_get(L)); |
856 | lane->status = RUNNING; // PENDING -> RUNNING | 856 | lane->m_status = Lane::Running; // Pending -> Running |
857 | 857 | ||
858 | // Tie "set_finalizer()" to the state | 858 | // Tie "set_finalizer()" to the state |
859 | lua_pushcfunction(L, LG_set_finalizer); | 859 | lua_pushcfunction(L, LG_set_finalizer); |
@@ -924,14 +924,12 @@ static void lane_main(Lane* lane) | |||
924 | { | 924 | { |
925 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them | 925 | // leave results (1..top) or error message + stack trace (1..2) on the stack - master will copy them |
926 | 926 | ||
927 | enum e_status st = (rc == 0) ? DONE : CANCEL_ERROR.equals(L, 1) ? CANCELLED : ERROR_ST; | 927 | Lane::Status st = (rc == LUA_OK) ? Lane::Done : CANCEL_ERROR.equals(L, 1) ? Lane::Cancelled : Lane::Error; |
928 | 928 | ||
929 | // Posix no PTHREAD_TIMEDJOIN: | ||
930 | // 'm_done_mutex' protects the -> DONE|ERROR_ST|CANCELLED state change | ||
931 | // | ||
932 | { | 929 | { |
930 | // 'm_done_mutex' protects the -> Done|Error|Cancelled state change | ||
933 | std::lock_guard lock{ lane->m_done_mutex }; | 931 | std::lock_guard lock{ lane->m_done_mutex }; |
934 | lane->status = st; | 932 | lane->m_status = st; |
935 | lane->m_done_signal.notify_one();// wake up master (while 'lane->m_done_mutex' is on) | 933 | lane->m_done_signal.notify_one();// wake up master (while 'lane->m_done_mutex' is on) |
936 | } | 934 | } |
937 | } | 935 | } |
@@ -1045,13 +1043,15 @@ LUAG_FUNC(lane_new) | |||
1045 | lua_State* const m_L; | 1043 | lua_State* const m_L; |
1046 | Lane* m_lane{ nullptr }; | 1044 | Lane* m_lane{ nullptr }; |
1047 | int const m_gc_cb_idx; | 1045 | int const m_gc_cb_idx; |
1046 | DEBUGSPEW_CODE(Universe* const U); // for DEBUGSPEW only (hence the absence of m_ prefix) | ||
1048 | 1047 | ||
1049 | public: | 1048 | public: |
1050 | 1049 | ||
1051 | OnExit(lua_State* L_, Lane* lane_, int gc_cb_idx_) | 1050 | OnExit(lua_State* L_, Lane* lane_, int gc_cb_idx_ DEBUGSPEW_COMMA_PARAM(Universe* U_)) |
1052 | : m_L{ L_ } | 1051 | : m_L{ L_ } |
1053 | , m_lane{ lane_ } | 1052 | , m_lane{ lane_ } |
1054 | , m_gc_cb_idx{ gc_cb_idx_ } | 1053 | , m_gc_cb_idx{ gc_cb_idx_ } |
1054 | DEBUGSPEW_COMMA_PARAM(U{ U_ }) | ||
1055 | {} | 1055 | {} |
1056 | 1056 | ||
1057 | ~OnExit() | 1057 | ~OnExit() |
@@ -1065,7 +1065,7 @@ LUAG_FUNC(lane_new) | |||
1065 | CANCEL_ERROR.pushKey(m_lane->L); | 1065 | CANCEL_ERROR.pushKey(m_lane->L); |
1066 | { | 1066 | { |
1067 | std::lock_guard lock{ m_lane->m_done_mutex }; | 1067 | std::lock_guard lock{ m_lane->m_done_mutex }; |
1068 | m_lane->status = CANCELLED; | 1068 | m_lane->m_status = Lane::Cancelled; |
1069 | m_lane->m_done_signal.notify_one(); // wake up master (while 'lane->m_done_mutex' is on) | 1069 | m_lane->m_done_signal.notify_one(); // wake up master (while 'lane->m_done_mutex' is on) |
1070 | } | 1070 | } |
1071 | // unblock the thread so that it can terminate gracefully | 1071 | // unblock the thread so that it can terminate gracefully |
@@ -1113,7 +1113,7 @@ LUAG_FUNC(lane_new) | |||
1113 | m_lane->m_ready.count_down(); | 1113 | m_lane->m_ready.count_down(); |
1114 | m_lane = nullptr; | 1114 | m_lane = nullptr; |
1115 | } | 1115 | } |
1116 | } onExit{ L, lane, gc_cb_idx }; | 1116 | } onExit{ L, lane, gc_cb_idx DEBUGSPEW_COMMA_PARAM(U) }; |
1117 | // launch the thread early, it will sync with a std::latch to parallelize OS thread warmup and L2 preparation | 1117 | // launch the thread early, it will sync with a std::latch to parallelize OS thread warmup and L2 preparation |
1118 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END)); | 1118 | DEBUGSPEW_CODE(fprintf(stderr, INDENT_BEGIN "lane_new: launching thread\n" INDENT_END)); |
1119 | lane->startThread(priority); | 1119 | lane->startThread(priority); |
@@ -1311,7 +1311,7 @@ static int lane_gc(lua_State* L) | |||
1311 | } | 1311 | } |
1312 | 1312 | ||
1313 | // We can read 'lane->status' without locks, but not wait for it | 1313 | // We can read 'lane->status' without locks, but not wait for it |
1314 | if (lane->status < DONE) | 1314 | if (lane->m_status < Lane::Done) |
1315 | { | 1315 | { |
1316 | // still running: will have to be cleaned up later | 1316 | // still running: will have to be cleaned up later |
1317 | selfdestruct_add(lane); | 1317 | selfdestruct_add(lane); |
@@ -1358,14 +1358,14 @@ static int lane_gc(lua_State* L) | |||
1358 | // | 1358 | // |
1359 | static char const * thread_status_string(Lane* lane_) | 1359 | static char const * thread_status_string(Lane* lane_) |
1360 | { | 1360 | { |
1361 | enum e_status const st{ lane_->status }; // read just once (volatile) | 1361 | Lane::Status const st{ lane_->m_status }; // read just once (volatile) |
1362 | char const* str = | 1362 | char const* str = |
1363 | (st == PENDING) ? "pending" : | 1363 | (st == Lane::Pending) ? "pending" : |
1364 | (st == RUNNING) ? "running" : // like in 'co.status()' | 1364 | (st == Lane::Running) ? "running" : // like in 'co.status()' |
1365 | (st == WAITING) ? "waiting" : | 1365 | (st == Lane::Waiting) ? "waiting" : |
1366 | (st == DONE) ? "done" : | 1366 | (st == Lane::Done) ? "done" : |
1367 | (st == ERROR_ST) ? "error" : | 1367 | (st == Lane::Error) ? "error" : |
1368 | (st == CANCELLED) ? "cancelled" : nullptr; | 1368 | (st == Lane::Cancelled) ? "cancelled" : nullptr; |
1369 | return str; | 1369 | return str; |
1370 | } | 1370 | } |
1371 | 1371 | ||
@@ -1406,16 +1406,16 @@ LUAG_FUNC(thread_join) | |||
1406 | } | 1406 | } |
1407 | 1407 | ||
1408 | STACK_CHECK_START_REL(L, 0); | 1408 | STACK_CHECK_START_REL(L, 0); |
1409 | // Thread is DONE/ERROR_ST/CANCELLED; all ours now | 1409 | // Thread is Done/Error/Cancelled; all ours now |
1410 | 1410 | ||
1411 | int ret{ 0 }; | 1411 | int ret{ 0 }; |
1412 | Universe* const U{ lane->U }; | 1412 | Universe* const U{ lane->U }; |
1413 | // debug_name is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed | 1413 | // debug_name is a pointer to string possibly interned in the lane's state, that no longer exists when the state is closed |
1414 | // so store it in the userdata uservalue at a key that can't possibly collide | 1414 | // so store it in the userdata uservalue at a key that can't possibly collide |
1415 | securize_debug_threadname(L, lane); | 1415 | securize_debug_threadname(L, lane); |
1416 | switch (lane->status) | 1416 | switch (lane->m_status) |
1417 | { | 1417 | { |
1418 | case DONE: | 1418 | case Lane::Done: |
1419 | { | 1419 | { |
1420 | int const n{ lua_gettop(L2) }; // whole L2 stack | 1420 | int const n{ lua_gettop(L2) }; // whole L2 stack |
1421 | if ((n > 0) && (luaG_inter_move(U, L2, L, n, LookupMode::LaneBody) != 0)) | 1421 | if ((n > 0) && (luaG_inter_move(U, L2, L, n, LookupMode::LaneBody) != 0)) |
@@ -1426,7 +1426,7 @@ LUAG_FUNC(thread_join) | |||
1426 | } | 1426 | } |
1427 | break; | 1427 | break; |
1428 | 1428 | ||
1429 | case ERROR_ST: | 1429 | case Lane::Error: |
1430 | { | 1430 | { |
1431 | int const n{ lua_gettop(L2) }; | 1431 | int const n{ lua_gettop(L2) }; |
1432 | STACK_GROW(L, 3); | 1432 | STACK_GROW(L, 3); |
@@ -1440,12 +1440,12 @@ LUAG_FUNC(thread_join) | |||
1440 | } | 1440 | } |
1441 | break; | 1441 | break; |
1442 | 1442 | ||
1443 | case CANCELLED: | 1443 | case Lane::Cancelled: |
1444 | ret = 0; | 1444 | ret = 0; |
1445 | break; | 1445 | break; |
1446 | 1446 | ||
1447 | default: | 1447 | default: |
1448 | DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->status)); | 1448 | DEBUGSPEW_CODE(fprintf(stderr, "Status: %d\n", lane->m_status)); |
1449 | ASSERT_L(false); | 1449 | ASSERT_L(false); |
1450 | ret = 0; | 1450 | ret = 0; |
1451 | } | 1451 | } |
@@ -1505,7 +1505,7 @@ LUAG_FUNC(thread_index) | |||
1505 | lua_pushcfunction(L, LG_thread_join); | 1505 | lua_pushcfunction(L, LG_thread_join); |
1506 | lua_pushvalue(L, UD); | 1506 | lua_pushvalue(L, UD); |
1507 | lua_call(L, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ | 1507 | lua_call(L, 1, LUA_MULTRET); // all return values are on the stack, at slots 4+ |
1508 | switch (lane->status) | 1508 | switch (lane->m_status) |
1509 | { | 1509 | { |
1510 | default: | 1510 | default: |
1511 | // this is an internal error, we probably never get here | 1511 | // this is an internal error, we probably never get here |
@@ -1516,7 +1516,7 @@ LUAG_FUNC(thread_index) | |||
1516 | raise_lua_error(L); | 1516 | raise_lua_error(L); |
1517 | [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack | 1517 | [[fallthrough]]; // fall through if we are killed, as we got nil, "killed" on the stack |
1518 | 1518 | ||
1519 | case DONE: // got regular return values | 1519 | case Lane::Done: // got regular return values |
1520 | { | 1520 | { |
1521 | int const nvalues{ lua_gettop(L) - 3 }; | 1521 | int const nvalues{ lua_gettop(L) - 3 }; |
1522 | for (int i = nvalues; i > 0; --i) | 1522 | for (int i = nvalues; i > 0; --i) |
@@ -1527,7 +1527,7 @@ LUAG_FUNC(thread_index) | |||
1527 | } | 1527 | } |
1528 | break; | 1528 | break; |
1529 | 1529 | ||
1530 | case ERROR_ST: // got 3 values: nil, errstring, callstack table | 1530 | case Lane::Error: // got 3 values: nil, errstring, callstack table |
1531 | // me[-2] could carry the stack table, but even | 1531 | // me[-2] could carry the stack table, but even |
1532 | // me[-1] is rather unnecessary (and undocumented); | 1532 | // me[-1] is rather unnecessary (and undocumented); |
1533 | // use ':join()' instead. --AKa 22-Jan-2009 | 1533 | // use ':join()' instead. --AKa 22-Jan-2009 |
@@ -1538,7 +1538,7 @@ LUAG_FUNC(thread_index) | |||
1538 | lua_rawset(L, USR); | 1538 | lua_rawset(L, USR); |
1539 | break; | 1539 | break; |
1540 | 1540 | ||
1541 | case CANCELLED: | 1541 | case Lane::Cancelled: |
1542 | // do nothing | 1542 | // do nothing |
1543 | break; | 1543 | break; |
1544 | } | 1544 | } |
@@ -1648,13 +1648,17 @@ LUAG_FUNC(threads) | |||
1648 | */ | 1648 | */ |
1649 | 1649 | ||
1650 | /* | 1650 | /* |
1651 | * secs= now_secs() | 1651 | * secs = now_secs() |
1652 | * | 1652 | * |
1653 | * Returns the current time, as seconds (millisecond resolution). | 1653 | * Returns the current time, as seconds. Resolution depends on std::system_clock implementation |
1654 | * Can't use std::chrono::steady_clock because we need the same baseline as std::mktime | ||
1654 | */ | 1655 | */ |
1655 | LUAG_FUNC(now_secs) | 1656 | LUAG_FUNC(now_secs) |
1656 | { | 1657 | { |
1657 | lua_pushnumber(L, now_secs()); | 1658 | auto const now{ std::chrono::system_clock::now() }; |
1659 | lua_Duration duration { now.time_since_epoch() }; | ||
1660 | |||
1661 | lua_pushnumber(L, duration.count()); | ||
1658 | return 1; | 1662 | return 1; |
1659 | } | 1663 | } |
1660 | 1664 | ||
@@ -1739,10 +1743,6 @@ static const struct luaL_Reg lanes_functions[] = | |||
1739 | */ | 1743 | */ |
1740 | static void init_once_LOCKED( void) | 1744 | static void init_once_LOCKED( void) |
1741 | { | 1745 | { |
1742 | #if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | ||
1743 | now_secs(); // initialize 'now_secs()' internal offset | ||
1744 | #endif | ||
1745 | |||
1746 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) | 1746 | #if (defined PLATFORM_OSX) && (defined _UTILBINDTHREADTOCPU) |
1747 | chudInitialize(); | 1747 | chudInitialize(); |
1748 | #endif | 1748 | #endif |