Added LuaState tracker and memory stats logging.
This commit is contained in:
parent
a59800ca0c
commit
1c8e60f91a
@ -42,6 +42,76 @@ const cLuaState::cRet cLuaState::Return = {};
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// cLuaStateTracker:
|
||||||
|
|
||||||
|
void cLuaStateTracker::Add(cLuaState & a_LuaState)
|
||||||
|
{
|
||||||
|
auto & Instance = Get();
|
||||||
|
cCSLock Lock(Instance.m_CSLuaStates);
|
||||||
|
Instance.m_LuaStates.push_back(&a_LuaState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void cLuaStateTracker::Del(cLuaState & a_LuaState)
|
||||||
|
{
|
||||||
|
auto & Instance = Get();
|
||||||
|
cCSLock Lock(Instance.m_CSLuaStates);
|
||||||
|
Instance.m_LuaStates.erase(
|
||||||
|
std::remove_if(
|
||||||
|
Instance.m_LuaStates.begin(), Instance.m_LuaStates.end(),
|
||||||
|
[&a_LuaState](cLuaStatePtr a_StoredLuaState)
|
||||||
|
{
|
||||||
|
return (&a_LuaState == a_StoredLuaState);
|
||||||
|
}
|
||||||
|
),
|
||||||
|
Instance.m_LuaStates.end()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
AString cLuaStateTracker::GetStats(void)
|
||||||
|
{
|
||||||
|
auto & Instance = Get();
|
||||||
|
cCSLock Lock(Instance.m_CSLuaStates);
|
||||||
|
AString res;
|
||||||
|
int Total = 0;
|
||||||
|
for (auto state: Instance.m_LuaStates)
|
||||||
|
{
|
||||||
|
int Mem = 0;
|
||||||
|
if (!state->Call("collectgarbage", "count", cLuaState::Return, Mem))
|
||||||
|
{
|
||||||
|
res.append(Printf("Cannot query memory for state \"%s\"\n", state->GetSubsystemName().c_str()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
res.append(Printf("State \"%s\" is using %d KiB of memory\n", state->GetSubsystemName().c_str(), Mem));
|
||||||
|
Total += Mem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
res.append(Printf("Total memory used by Lua: %d KiB\n", Total));
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
cLuaStateTracker & cLuaStateTracker::Get(void)
|
||||||
|
{
|
||||||
|
static cLuaStateTracker Inst; // The singleton
|
||||||
|
return Inst;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
// cLuaState:
|
// cLuaState:
|
||||||
|
|
||||||
@ -98,6 +168,7 @@ void cLuaState::Create(void)
|
|||||||
m_LuaState = lua_open();
|
m_LuaState = lua_open();
|
||||||
luaL_openlibs(m_LuaState);
|
luaL_openlibs(m_LuaState);
|
||||||
m_IsOwned = true;
|
m_IsOwned = true;
|
||||||
|
cLuaStateTracker::Add(*this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -133,6 +204,7 @@ void cLuaState::Close(void)
|
|||||||
Detach();
|
Detach();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
cLuaStateTracker::Del(*this);
|
||||||
lua_close(m_LuaState);
|
lua_close(m_LuaState);
|
||||||
m_LuaState = nullptr;
|
m_LuaState = nullptr;
|
||||||
m_IsOwned = false;
|
m_IsOwned = false;
|
||||||
|
@ -210,6 +210,9 @@ public:
|
|||||||
|
|
||||||
/** Returns true if the m_LuaState is valid */
|
/** Returns true if the m_LuaState is valid */
|
||||||
bool IsValid(void) const { return (m_LuaState != nullptr); }
|
bool IsValid(void) const { return (m_LuaState != nullptr); }
|
||||||
|
|
||||||
|
/** Returns the name of the subsystem, as specified when the instance was created. */
|
||||||
|
AString GetSubsystemName(void) const { return m_SubsystemName; }
|
||||||
|
|
||||||
/** Adds the specified path to package.<a_PathVariable> */
|
/** Adds the specified path to package.<a_PathVariable> */
|
||||||
void AddPackagePath(const AString & a_PathVariable, const AString & a_Path);
|
void AddPackagePath(const AString & a_PathVariable, const AString & a_Path);
|
||||||
@ -521,3 +524,37 @@ protected:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/** Keeps track of all create cLuaState instances.
|
||||||
|
Can query each for the amount of currently used memory. */
|
||||||
|
class cLuaStateTracker
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/** Adds the specified Lua state to the internal list of LuaStates. */
|
||||||
|
static void Add(cLuaState & a_LuaState);
|
||||||
|
|
||||||
|
/** Deletes the specified Lua state from the internal list of LuaStates. */
|
||||||
|
static void Del(cLuaState & a_LuaState);
|
||||||
|
|
||||||
|
/** Returns the statistics for all the registered LuaStates. */
|
||||||
|
static AString GetStats(void);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
typedef cLuaState * cLuaStatePtr;
|
||||||
|
typedef std::vector<cLuaStatePtr> cLuaStatePtrs;
|
||||||
|
|
||||||
|
/** The internal list of LuaStates.
|
||||||
|
Protected against multithreaded access by m_CSLuaStates. */
|
||||||
|
cLuaStatePtrs m_LuaStates;
|
||||||
|
|
||||||
|
/** Protects m_LuaStates against multithreaded access. */
|
||||||
|
cCriticalSection m_CSLuaStates;
|
||||||
|
|
||||||
|
|
||||||
|
/** Returns the single instance of this class. */
|
||||||
|
static cLuaStateTracker & Get(void);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@ -145,6 +145,8 @@ cServer::cServer(void) :
|
|||||||
m_ShouldLoadOfflinePlayerData(false),
|
m_ShouldLoadOfflinePlayerData(false),
|
||||||
m_ShouldLoadNamedPlayerData(true)
|
m_ShouldLoadNamedPlayerData(true)
|
||||||
{
|
{
|
||||||
|
// Initialize the LuaStateTracker singleton before the app goes multithreaded:
|
||||||
|
cLuaStateTracker::GetStats();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -522,6 +524,13 @@ void cServer::ExecuteConsoleCommand(const AString & a_Cmd, cCommandOutputCallbac
|
|||||||
a_Output.Finished();
|
a_Output.Finished();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
else if (split[0].compare("luastats") == 0)
|
||||||
|
{
|
||||||
|
a_Output.Out(cLuaStateTracker::GetStats());
|
||||||
|
a_Output.Finished();
|
||||||
|
return;
|
||||||
|
}
|
||||||
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
|
#if defined(_MSC_VER) && defined(_DEBUG) && defined(ENABLE_LEAK_FINDER)
|
||||||
else if (split[0].compare("dumpmem") == 0)
|
else if (split[0].compare("dumpmem") == 0)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user