From 1013970853e6acfd60591a89ae08cc40c64bee06 Mon Sep 17 00:00:00 2001 From: Benoit Germain Date: Tue, 14 May 2024 10:05:54 +0200 Subject: Moved Lane tracking implementation in a separate file --- src/Makefile | 4 +-- src/lanes.cpp | 91 +++++------------------------------------------ src/tools.cpp | 1 + src/tracker.cpp | 108 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/tracker.h | 35 ++++++++++++++++++ src/universe.h | 7 ++-- 6 files changed, 156 insertions(+), 90 deletions(-) create mode 100644 src/tracker.cpp create mode 100644 src/tracker.h (limited to 'src') diff --git a/src/Makefile b/src/Makefile index bbe7b23..fddc45e 100644 --- a/src/Makefile +++ b/src/Makefile @@ -7,9 +7,9 @@ MODULE=lanes -SRC=lanes.c cancel.cpp compat.cpp threading.cpp tools.cpp state.cpp linda.cpp lindafactory.cpp deep.cpp keeper.cpp universe.cpp intercopycontext.cpp +SRC=cancel.cpp compat.cpp deep.cpp intercopycontext.cpp keeper.cpp lanes.cpp linda.cpp lindafactory.cpp state.cpp threading.cpp tools.cpp tracker.cpp universe.cpp -OBJ=$(SRC:.c=.o) +OBJ=$(SRC:.cpp=.o) # LuaRocks gives 'LIBFLAG' from the outside # diff --git a/src/lanes.cpp b/src/lanes.cpp index 9c9d7d1..f8efa42 100644 --- a/src/lanes.cpp +++ b/src/lanes.cpp @@ -104,67 +104,12 @@ THE SOFTWARE. // ################################################################################################# -#if HAVE_LANE_TRACKING() - -// The chain is ended by '(Lane*)(-1)', not nullptr: -// 'trackingFirst -> ... -> ... -> (-1)' -#define TRACKING_END ((Lane*) (-1)) - -/* - * Add the lane to tracking chain; the ones still running at the end of the - * whole process will be cancelled. - */ -static void tracking_add(Lane* lane_) -{ - std::lock_guard _guard{ lane_->U->trackingMutex }; - assert(lane_->tracking_next == nullptr); - - lane_->tracking_next = lane_->U->trackingFirst; - lane_->U->trackingFirst = lane_; -} - -// ################################################################################################# - -/* - * A free-running lane has ended; remove it from tracking chain - */ -[[nodiscard]] static bool tracking_remove(Lane* lane_) -{ - bool _found{ false }; - std::lock_guard _guard{ lane_->U->trackingMutex }; - // Make sure (within the MUTEX) that we actually are in the chain - // still (at process exit they will remove us from chain and then - // cancel/kill). - // - if (lane_->tracking_next != nullptr) { - Lane** _ref = (Lane**) &lane_->U->trackingFirst; - - while (*_ref != TRACKING_END) { - if (*_ref == lane_) { - *_ref = lane_->tracking_next; - lane_->tracking_next = nullptr; - _found = true; - break; - } - _ref = (Lane**) &((*_ref)->tracking_next); - } - assert(_found); - } - return _found; -} - -#endif // HAVE_LANE_TRACKING() - -// ################################################################################################# - Lane::Lane(Universe* U_, lua_State* L_) : U{ U_ } , L{ L_ } { #if HAVE_LANE_TRACKING() - if (U->trackingFirst) { - tracking_add(this); - } + U->tracker.tracking_add(this); #endif // HAVE_LANE_TRACKING() } @@ -241,10 +186,7 @@ Lane::~Lane() // Clean up after a (finished) thread // #if HAVE_LANE_TRACKING() - if (U->trackingFirst != nullptr) { - // Lane was cleaned up, no need to handle at process termination - std::ignore = tracking_remove(this); - } + std::ignore = U->tracker.tracking_remove(this); #endif // HAVE_LANE_TRACKING() } @@ -1428,27 +1370,8 @@ LUAG_FUNC(thread_index) // Return a list of all known lanes LUAG_FUNC(threads) { - int const _top{ lua_gettop(L_) }; - Universe* const _U{ universe_get(L_) }; - - // List _all_ still running threads - std::lock_guard _guard{ _U->trackingMutex }; - if (_U->trackingFirst && _U->trackingFirst != TRACKING_END) { - Lane* _lane{ _U->trackingFirst }; - int _index{ 0 }; - lua_newtable(L_); // L_: {} - while (_lane != TRACKING_END) { - // insert a { name='', status='' } tuple, so that several lanes with the same name can't clobber each other - lua_createtable(L_, 0, 2); // L_: {} {} - lua_pushstring(L_, _lane->debugName); // L_: {} {} "name" - lua_setfield(L_, -2, "name"); // L_: {} {} - _lane->pushThreadStatus(L_); // L_: {} {} "status" - lua_setfield(L_, -2, "status"); // L_: {} {} - lua_rawseti(L_, -2, ++_index); // L_: {} - _lane = _lane->tracking_next; - } - } - return lua_gettop(L_) - _top; // L_: 0 or 1 + LaneTracker const& _tracker = universe_get(L_)->tracker; + return _tracker.pushThreadsTable(L_); } #endif // HAVE_LANE_TRACKING() @@ -1668,7 +1591,9 @@ LUAG_FUNC(configure) lua_pop(L_, 1); // L_: settings #if HAVE_LANE_TRACKING() lua_getfield(L_, 1, "track_lanes"); // L_: settings track_lanes - _U->trackingFirst = lua_toboolean(L_, -1) ? TRACKING_END : nullptr; + if (lua_toboolean(L_, -1)) { + _U->tracker.activate(); + } lua_pop(L_, 1); // L_: settings #endif // HAVE_LANE_TRACKING() // Linked chains handling @@ -1704,7 +1629,7 @@ LUAG_FUNC(configure) luaG_registerlibfuncs(L_, global::sLanesFunctions); #if HAVE_LANE_TRACKING() // register core.threads() only if settings say it should be available - if (_U->trackingFirst != nullptr) { + if (_U->tracker.isActive()) { lua_pushcfunction(L_, LG_threads); // L_: settings M LG_threads() lua_setfield(L_, -2, "threads"); // L_: settings M } diff --git a/src/tools.cpp b/src/tools.cpp index 0cfe1ab..3e6224a 100644 --- a/src/tools.cpp +++ b/src/tools.cpp @@ -523,3 +523,4 @@ int luaG_nameof(lua_State* L_) lua_replace(L_, -3); // L_: "type" "result" return 2; } + \ No newline at end of file diff --git a/src/tracker.cpp b/src/tracker.cpp new file mode 100644 index 0000000..e6affb2 --- /dev/null +++ b/src/tracker.cpp @@ -0,0 +1,108 @@ +/* +=============================================================================== + +Copyright (C) 2024 Benoit Germain + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +=============================================================================== +*/ +#include "tracker.h" +#include "lanes_private.h" + +// ################################################################################################# + +#if HAVE_LANE_TRACKING() + +/* + * Add the lane to tracking chain; the ones still running at the end of the + * whole process will be cancelled. + */ +void LaneTracker::tracking_add(Lane* lane_) +{ + if (!isActive()) { + return; + } + std::lock_guard _guard{ trackingMutex }; + assert(lane_->tracking_next == nullptr); + + lane_->tracking_next = trackingFirst; + trackingFirst = lane_; +} + +// ################################################################################################# + +/* + * A free-running lane has ended; remove it from tracking chain + */ +[[nodiscard]] bool LaneTracker::tracking_remove(Lane* lane_) +{ + if (!isActive()) { + return false; + } + + bool _found{ false }; + std::lock_guard _guard{ trackingMutex }; + // Make sure (within the MUTEX) that we actually are in the chain + // still (at process exit they will remove us from chain and then + // cancel/kill). + // + if (lane_->tracking_next != nullptr) { + Lane** _ref = (Lane**) &trackingFirst; + + while (*_ref != TRACKING_END) { + if (*_ref == lane_) { + *_ref = lane_->tracking_next; + lane_->tracking_next = nullptr; + _found = true; + break; + } + _ref = (Lane**) &((*_ref)->tracking_next); + } + assert(_found); + } + return _found; +} + +// ################################################################################################ + +[[nodiscard]] int LaneTracker::pushThreadsTable(lua_State* L_) const +{ + int const _top{ lua_gettop(L_) }; + // List _all_ still running threads + std::lock_guard _guard{ trackingMutex }; + if (trackingFirst && trackingFirst != TRACKING_END) { + Lane* _lane{ trackingFirst }; + int _index{ 0 }; + lua_newtable(L_); // L_: {} + while (_lane != TRACKING_END) { + // insert a { name='', status='' } tuple, so that several lanes with the same name can't clobber each other + lua_createtable(L_, 0, 2); // L_: {} {} + lua_pushstring(L_, _lane->debugName); // L_: {} {} "name" + lua_setfield(L_, -2, "name"); // L_: {} {} + _lane->pushThreadStatus(L_); // L_: {} {} "status" + lua_setfield(L_, -2, "status"); // L_: {} {} + lua_rawseti(L_, -2, ++_index); // L_: {} + _lane = _lane->tracking_next; + } + } + return lua_gettop(L_) - _top; // L_: 0 or 1 +} + +#endif // HAVE_LANE_TRACKING() diff --git a/src/tracker.h b/src/tracker.h new file mode 100644 index 0000000..087598c --- /dev/null +++ b/src/tracker.h @@ -0,0 +1,35 @@ +#pragma once + +#include + +// Do we want to activate full lane tracking feature? +#define HAVE_LANE_TRACKING() 1 + +#if HAVE_LANE_TRACKING() + +class Lane; +struct lua_State; + +// The chain is ended by '(Lane*)(-1)', not nullptr: +// 'trackingFirst -> ... -> ... -> (-1)' +#define TRACKING_END ((Lane*) (-1)) + +class LaneTracker +{ + private: + mutable std::mutex trackingMutex; + Lane* volatile trackingFirst{ nullptr }; // will change to TRACKING_END if we want to activate tracking + + public: + void tracking_add(Lane* lane_); + [[nodiscard]] bool tracking_remove(Lane* lane_); + [[nodiscard]] int pushThreadsTable(lua_State* L_) const; + void activate() { + trackingFirst = TRACKING_END; + } + [[nodiscard]] bool isActive() const { + return trackingFirst != nullptr; + } +}; + +#endif // HAVE_LANE_TRACKING() diff --git a/src/universe.h b/src/universe.h index 3adba4d..8244980 100644 --- a/src/universe.h +++ b/src/universe.h @@ -10,6 +10,7 @@ extern "C" #endif // __cplusplus #include "macros_and_utils.h" +#include "tracker.h" #include "uniquekey.h" #include @@ -22,9 +23,6 @@ struct DeepPrelude; struct Keepers; class Lane; -// Do we want to activate full lane tracking feature? -#define HAVE_LANE_TRACKING() 1 - // ################################################################################################# // everything we need to provide to lua_newstate() @@ -158,8 +156,7 @@ class Universe DeepPrelude* timerLinda{ nullptr }; #if HAVE_LANE_TRACKING() - std::mutex trackingMutex; - Lane* volatile trackingFirst{ nullptr }; // will change to TRACKING_END if we want to activate tracking + LaneTracker tracker; #endif // HAVE_LANE_TRACKING() // Protects modifying the selfdestruct chain -- cgit v1.2.3-55-g6feb