[Lldb-commits] [lldb] r230003 - Reduce number of threads in lldb-mi.
Hafiz Abid Qadeer
hafiz_abid at mentor.com
Fri Feb 20 02:20:07 PST 2015
Author: abidh
Date: Fri Feb 20 04:20:05 2015
New Revision: 230003
URL: http://llvm.org/viewvc/llvm-project?rev=230003&view=rev
Log:
Reduce number of threads in lldb-mi.
LLDB-mi have 3 threads.
1. Wait for input.
2. Process commands.
3. Process events.
This revision merges 1 & 2. Same thread waits on input and then process the
command. This way, no synchronization is needed between first and 2nd. Also it is
easy to check when to exit.
A lot of code will redundant and will be cleaned up gradually.
All lldb-mi tests pass with gcc and clang as test compiler. Also did minimal testing
on command line and works ok. The "quit" and "-gdb-exit" command close the application
without needing any further return.
Reviewed in http://reviews.llvm.org/D7746.
Modified:
lldb/trunk/tools/lldb-mi/Driver.h
lldb/trunk/tools/lldb-mi/MICmnStreamStdin.cpp
lldb/trunk/tools/lldb-mi/MICmnStreamStdin.h
lldb/trunk/tools/lldb-mi/MIDriver.cpp
lldb/trunk/tools/lldb-mi/MIDriver.h
lldb/trunk/tools/lldb-mi/MIDriverMain.cpp
lldb/trunk/tools/lldb-mi/MIDriverMgr.cpp
lldb/trunk/tools/lldb-mi/MIDriverMgr.h
Modified: lldb/trunk/tools/lldb-mi/Driver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/Driver.h?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/Driver.h (original)
+++ lldb/trunk/tools/lldb-mi/Driver.h Fri Feb 20 04:20:05 2015
@@ -64,6 +64,7 @@ class Driver : public lldb::SBBroadcaste
virtual bool SetDriverParent(const CMIDriverBase &vrOtherDriver);
virtual const CMIUtilString &GetDriverName(void) const;
virtual const CMIUtilString &GetDriverId(void) const;
+ virtual void DeliverSignal(int signal) {}
// Original code:
public:
Modified: lldb/trunk/tools/lldb-mi/MICmnStreamStdin.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnStreamStdin.cpp?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnStreamStdin.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MICmnStreamStdin.cpp Fri Feb 20 04:20:05 2015
@@ -33,6 +33,7 @@
#else
#include "MICmnStreamStdinLinux.h"
#endif // defined( _MSC_VER )
+#include <string.h> // For std::strerror()
//++ ------------------------------------------------------------------------------------
// Details: CMICmnStreamStdin constructor.
@@ -49,6 +50,7 @@ CMICmnStreamStdin::CMICmnStreamStdin(voi
, m_bShowPrompt(true)
, m_bRedrawPrompt(true)
, m_pStdinReadHandler(nullptr)
+ , m_pCmdBuffer(nullptr)
{
}
@@ -103,6 +105,9 @@ CMICmnStreamStdin::Initialize(void)
return MIstatus::failure;
}
+ if (bOk)
+ m_pCmdBuffer = new MIchar[m_constBufferSize];
+
// Other resources required
if (bOk)
{
@@ -142,6 +147,12 @@ CMICmnStreamStdin::Shutdown(void)
ClrErrorDescription();
+ if (m_pCmdBuffer != nullptr)
+ {
+ delete[] m_pCmdBuffer;
+ m_pCmdBuffer = nullptr;
+ }
+
bool bOk = MIstatus::success;
CMIUtilString errMsg;
@@ -355,7 +366,28 @@ CMICmnStreamStdin::MonitorStdin(bool &vr
const MIchar *
CMICmnStreamStdin::ReadLine(CMIUtilString &vwErrMsg)
{
- return m_pStdinReadHandler->ReadLine(vwErrMsg);
+ vwErrMsg.clear();
+
+ // Read user input
+ const MIchar *pText = ::fgets(&m_pCmdBuffer[0], m_constBufferSize, stdin);
+ if (pText == nullptr)
+ {
+ if (::ferror(stdin) != 0)
+ vwErrMsg = ::strerror(errno);
+ return nullptr;
+ }
+
+ // Strip off new line characters
+ for (MIchar *pI = m_pCmdBuffer; *pI != '\0'; pI++)
+ {
+ if ((*pI == '\n') || (*pI == '\r'))
+ {
+ *pI = '\0';
+ break;
+ }
+ }
+
+ return pText;
}
//++ ------------------------------------------------------------------------------------
Modified: lldb/trunk/tools/lldb-mi/MICmnStreamStdin.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MICmnStreamStdin.h?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MICmnStreamStdin.h (original)
+++ lldb/trunk/tools/lldb-mi/MICmnStreamStdin.h Fri Feb 20 04:20:05 2015
@@ -84,6 +84,7 @@ class CMICmnStreamStdin : public CMICmnB
bool SetVisitor(IStreamStdin &vrVisitor);
bool SetOSStdinHandler(IOSStdinHandler &vrHandler);
void OnExitHandler(void);
+ const MIchar *ReadLine(CMIUtilString &vwErrMsg);
// Overridden:
public:
@@ -104,7 +105,6 @@ class CMICmnStreamStdin : public CMICmnB
void operator=(const CMICmnStreamStdin &);
bool MonitorStdin(bool &vrwbYesExit);
- const MIchar *ReadLine(CMIUtilString &vwErrMsg);
bool
InputAvailable(bool &vbAvail); // Bytes are available on stdin
@@ -122,4 +122,6 @@ class CMICmnStreamStdin : public CMICmnB
bool m_bShowPrompt; // True = Yes prompt is shown/output to the user (stdout), false = no prompt
bool m_bRedrawPrompt; // True = Prompt needs to be redrawn
IOSStdinHandler *m_pStdinReadHandler;
+ static const int m_constBufferSize = 2048;
+ MIchar *m_pCmdBuffer;
};
Modified: lldb/trunk/tools/lldb-mi/MIDriver.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriver.cpp?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriver.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIDriver.cpp Fri Feb 20 04:20:05 2015
@@ -500,42 +500,6 @@ CMIDriver::GetDriverIsGDBMICompatibleDri
}
//++ ------------------------------------------------------------------------------------
-// Details: Callback function for monitoring stream stdin object. Part of the visitor
-// pattern.
-// This function is called by the CMICmnStreamStdin::CThreadStdin
-// "stdin monitor" thread (ID).
-// Type: Overridden.
-// Args: vStdInBuffer - (R) Copy of the current stdin line data.
-// vrbYesExit - (RW) True = yes exit stdin monitoring, false = continue monitor.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::ReadLine(const CMIUtilString &vStdInBuffer, bool &vrwbYesExit)
-{
- // For debugging. Update prompt show stdin is working
- // printf( "%s\n", vStdInBuffer.c_str() );
- // fflush( stdout );
-
- // Special case look for the quit command here so stop monitoring stdin stream
- // So we do not go back to fgetc() and wait and hang thread on exit
- if (vStdInBuffer == "quit")
- vrwbYesExit = true;
-
- // 1. Put new line in the queue container by stdin monitor thread
- // 2. Then *this driver calls ReadStdinLineQueue() when ready to read the queue in its
- // own thread
- const bool bOk = QueueMICommand(vStdInBuffer);
-
- // Check to see if the *this driver is shutting down (exit application)
- if (!vrwbYesExit)
- vrwbYesExit = m_bDriverIsExiting;
-
- return bOk;
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Start worker threads for the driver.
// Type: Method.
// Args: None.
@@ -551,16 +515,6 @@ CMIDriver::StartWorkerThreads(void)
// Grab the thread manager
CMICmnThreadMgrStd &rThreadMgr = CMICmnThreadMgrStd::Instance();
- // Start the stdin thread
- bOk &= m_rStdin.SetVisitor(*this);
- if (bOk && !rThreadMgr.ThreadStart<CMICmnStreamStdin>(m_rStdin))
- {
- const CMIUtilString errMsg = CMIUtilString::Format(MIRSRC(IDS_THREADMGR_ERR_THREAD_FAIL_CREATE),
- CMICmnThreadMgrStd::Instance().GetErrorDescription().c_str());
- SetErrorDescriptionn(errMsg);
- return MIstatus::failure;
- }
-
// Start the event polling thread
if (bOk && !rThreadMgr.ThreadStart<CMICmnLLDBDebugger>(m_rLldbDebugger))
{
@@ -627,11 +581,31 @@ CMIDriver::DoMainLoop(void)
// While the app is active
while (!m_bExitApp)
{
- // Poll stdin queue and dispatch
- if (!ReadStdinLineQueue())
+ CMIUtilString errorText;
+ const MIchar *pCmd = m_rStdin.ReadLine (errorText);
+ if (pCmd != nullptr)
{
- // Something went wrong
- break;
+ CMIUtilString lineText(pCmd);
+ if (!lineText.empty ())
+ {
+ if (lineText == "quit")
+ {
+ // We want to be exiting when receiving a quit command
+ m_bExitApp = true;
+ break;
+ }
+
+ bool bOk = false;
+ {
+ // Lock Mutex before processing commands so that we don't disturb an event
+ // being processed
+ CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
+ bOk = InterpretCommand(lineText);
+ }
+ // Draw prompt if desired
+ if (bOk && m_rStdin.GetEnablePrompt())
+ m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
+ }
}
}
@@ -648,72 +622,6 @@ CMIDriver::DoMainLoop(void)
}
//++ ------------------------------------------------------------------------------------
-// Details: *this driver sits and waits for input to the stdin line queue shared by *this
-// driver and the stdin monitor thread, it queues, *this reads, interprets and
-// reacts.
-// This function is used by the application's main thread.
-// Type: Method.
-// Args: None.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::ReadStdinLineQueue(void)
-{
- // True when queue contains input
- bool bHaveInput = false;
-
- // Stores the current input line
- CMIUtilString lineText;
- {
- // Lock while we access the queue
- CMIUtilThreadLock lock(m_threadMutex);
- if (!m_queueStdinLine.empty())
- {
- lineText = m_queueStdinLine.front();
- m_queueStdinLine.pop();
- bHaveInput = !lineText.empty();
- }
- }
-
- // Process while we have input
- if (bHaveInput)
- {
- if (lineText == "quit")
- {
- // We want to be exiting when receiving a quit command
- m_bExitApp = true;
- return MIstatus::success;
- }
-
- // Process the command
- bool bOk = false;
- {
- // Lock Mutex before processing commands so that we don't disturb an event
- // that is being processed.
- CMIUtilThreadLock lock(CMICmnLLDBDebugSessionInfo::Instance().GetSessionMutex());
- bOk = InterpretCommand(lineText);
- }
-
- // Draw prompt if desired
- if (bOk && m_rStdin.GetEnablePrompt())
- m_rStdOut.WriteMIResponse(m_rStdin.GetPrompt());
-
- // Input has been processed
- bHaveInput = false;
- }
- else
- {
- // Give resources back to the OS
- const std::chrono::milliseconds time(1);
- std::this_thread::sleep_for(time);
- }
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Set things in motion, set state etc that brings *this driver (and the
// application) to a tidy shutdown.
// This function is used by the application's main thread.
@@ -926,42 +834,6 @@ CMIDriver::GetId(void) const
}
//++ ------------------------------------------------------------------------------------
-// Details: Inject a command into the command processing system to be interpreted as a
-// command read from stdin. The text representing the command is also written
-// out to stdout as the command did not come from via stdin.
-// Type: Method.
-// Args: vMICmd - (R) Text data representing a possible command.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::InjectMICommand(const CMIUtilString &vMICmd)
-{
- const bool bOk = m_rStdOut.WriteMIResponse(vMICmd);
-
- return bOk && QueueMICommand(vMICmd);
-}
-
-//++ ------------------------------------------------------------------------------------
-// Details: Add a new command candidate to the command queue to be processed by the
-// command system.
-// Type: Method.
-// Args: vMICmd - (R) Text data representing a possible command.
-// Return: MIstatus::success - Functional succeeded.
-// MIstatus::failure - Functional failed.
-// Throws: None.
-//--
-bool
-CMIDriver::QueueMICommand(const CMIUtilString &vMICmd)
-{
- CMIUtilThreadLock lock(m_threadMutex);
- m_queueStdinLine.push(vMICmd);
-
- return MIstatus::success;
-}
-
-//++ ------------------------------------------------------------------------------------
// Details: Interpret the text data and match against current commands to see if there
// is a match. If a match then the command is issued and actioned on. The
// text data if not understood by *this driver is past on to the Fall Thru
@@ -1093,7 +965,7 @@ CMIDriver::SetExitApplicationFlag(const
// but halt the inferior program being debugged instead
if (m_eCurrentDriverState == eDriverState_RunningDebugging)
{
- InjectMICommand("-exec-interrupt");
+ InterpretCommand("-exec-interrupt");
return;
}
@@ -1302,9 +1174,9 @@ CMIDriver::GetExecutableFileNamePathOnCm
bool
CMIDriver::LocalDebugSessionStartupInjectCommands(void)
{
- const CMIUtilString strCmd(CMIUtilString::Format("-file-exec-and-symbols %s", m_strCmdLineArgExecuteableFileNamePath.c_str()));
-
- return InjectMICommand(strCmd);
+ const CMIUtilString strCmd(CMIUtilString::Format("-file-exec-and-symbols \"%s\"", m_strCmdLineArgExecuteableFileNamePath.c_str()));
+ const bool bOk = CMICmnStreamStdout::TextToStdout(strCmd);
+ return (bOk && InterpretCommand(strCmd));
}
//++ ------------------------------------------------------------------------------------
@@ -1335,3 +1207,18 @@ CMIDriver::IsDriverDebuggingArgExecutabl
{
return m_bDriverDebuggingArgExecutable;
}
+
+//++ ------------------------------------------------------------------------------------
+// Details: Gets called when lldb-mi gets a signal. Stops the process if it was SIGINT.
+//
+// Type: Method.
+// Args: signal that was delivered
+// Return: None.
+// Throws: None.
+//--
+void
+CMIDriver::DeliverSignal(int signal)
+{
+ if (signal == SIGINT && (m_eCurrentDriverState == eDriverState_RunningDebugging))
+ InterpretCommand("-exec-interrupt");
+}
Modified: lldb/trunk/tools/lldb-mi/MIDriver.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriver.h?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriver.h (original)
+++ lldb/trunk/tools/lldb-mi/MIDriver.h Fri Feb 20 04:20:05 2015
@@ -51,7 +51,6 @@ class CMICmnStreamStdout;
class CMIDriver : public CMICmnBase,
public CMIDriverMgr::IDriver,
public CMIDriverBase,
- public CMICmnStreamStdin::IStreamStdin,
public MI::ISingleton<CMIDriver>
{
friend class MI::ISingleton<CMIDriver>;
@@ -101,7 +100,6 @@ class CMIDriver : public CMICmnBase,
bool WriteMessageToLog(const CMIUtilString &vMessage);
bool SetEnableFallThru(const bool vbYes);
bool GetEnableFallThru(void) const;
- bool InjectMICommand(const CMIUtilString &vMICmd);
bool HaveExecutableFileNamePathOnCmdLine(void) const;
const CMIUtilString &GetExecutableFileNamePathOnCmdLine(void) const;
@@ -128,8 +126,7 @@ class CMIDriver : public CMICmnBase,
virtual FILE *GetStderr(void) const;
virtual const CMIUtilString &GetDriverName(void) const;
virtual const CMIUtilString &GetDriverId(void) const;
- // From CMICmnStreamStdin
- virtual bool ReadLine(const CMIUtilString &vStdInBuffer, bool &vrbYesExit);
+ virtual void DeliverSignal(int signal);
// Typedefs:
private:
@@ -142,7 +139,6 @@ class CMIDriver : public CMICmnBase,
void operator=(const CMIDriver &);
lldb::SBError ParseArgs(const int argc, const char *argv[], FILE *vpStdOut, bool &vwbExiting);
- bool ReadStdinLineQueue(void);
bool DoAppQuit(void);
bool InterpretCommand(const CMIUtilString &vTextLine);
bool InterpretCommandThisDriver(const CMIUtilString &vTextLine, bool &vwbCmdYesValid);
@@ -152,7 +148,6 @@ class CMIDriver : public CMICmnBase,
bool StopWorkerThreads(void);
bool InitClientIDEToMIDriver(void) const;
bool InitClientIDEEclipse(void) const;
- bool QueueMICommand(const CMIUtilString &vMICmd);
bool LocalDebugSessionStartupInjectCommands(void);
// Overridden:
@@ -168,7 +163,6 @@ class CMIDriver : public CMICmnBase,
//
bool m_bFallThruToOtherDriverEnabled; // True = yes fall through, false = do not pass on command
CMIUtilThreadMutex m_threadMutex;
- QueueStdinLine_t m_queueStdinLine; // Producer = stdin monitor, consumer = *this driver
bool m_bDriverIsExiting; // True = yes, driver told to quit, false = continue working
void *m_handleMainThread; // *this driver is run by the main thread
CMICmnStreamStdin &m_rStdin;
Modified: lldb/trunk/tools/lldb-mi/MIDriverMain.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriverMain.cpp?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriverMain.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIDriverMain.cpp Fri Feb 20 04:20:05 2015
@@ -132,9 +132,8 @@ sigint_handler(int vSigno)
CMICmnLog::Instance().WriteLog(CMIUtilString::Format(MIRSRC(IDS_PROCESS_SIGNAL_RECEIVED), "SIGINT", vSigno));
- // CODETAG_DEBUG_SESSION_RUNNING_PROG_RECEIVED_SIGINT_PAUSE_PROGRAM
- // Signal MI to shutdown or halt a running debug session
- CMICmnStreamStdin::Instance().SetCtrlCHit();
+ // Send signal to driver so that it can take suitable action
+ rDriverMgr.DeliverSignal (vSigno);
}
// ToDo: Reevaluate if this function needs to be implemented like the UNIX equivalent
@@ -165,8 +164,8 @@ sigtstp_handler(int vSigno)
CMICmnLog::Instance().WriteLog(CMIUtilString::Format(MIRSRC(IDS_PROCESS_SIGNAL_RECEIVED), "SIGTSTP", vSigno));
- // Signal MI to shutdown
- CMICmnStreamStdin::Instance().SetCtrlCHit();
+ // Send signal to driver so that it can take suitable action
+ rDriverMgr.DeliverSignal (vSigno);
}
// ToDo: Reevaluate if this function needs to be implemented like the UNIX equivalent
@@ -196,8 +195,8 @@ sigcont_handler(int vSigno)
CMICmnLog::Instance().WriteLog(CMIUtilString::Format(MIRSRC(IDS_PROCESS_SIGNAL_RECEIVED), "SIGCONT", vSigno));
- // Signal MI to shutdown
- CMICmnStreamStdin::Instance().SetCtrlCHit();
+ // Send signal to driver so that it can take suitable action
+ rDriverMgr.DeliverSignal (vSigno);
}
//++ ------------------------------------------------------------------------------------
Modified: lldb/trunk/tools/lldb-mi/MIDriverMgr.cpp
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriverMgr.cpp?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriverMgr.cpp (original)
+++ lldb/trunk/tools/lldb-mi/MIDriverMgr.cpp Fri Feb 20 04:20:05 2015
@@ -778,3 +778,19 @@ CMIDriverMgr::GetDriver(const CMIUtilStr
return pDriver;
}
+
+
+//++ ------------------------------------------------------------------------------------
+// Details: Gets called when lldb-mi gets a signal. Passed signal to current driver.
+//
+// Type: Method.
+// Args: signal that was delivered
+// Return: None.
+// Throws: None.
+//--
+void
+CMIDriverMgr::DeliverSignal(int signal)
+{
+ if (m_pDriverCurrent != nullptr)
+ m_pDriverCurrent->DeliverSignal(signal);
+}
Modified: lldb/trunk/tools/lldb-mi/MIDriverMgr.h
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/tools/lldb-mi/MIDriverMgr.h?rev=230003&r1=230002&r2=230003&view=diff
==============================================================================
--- lldb/trunk/tools/lldb-mi/MIDriverMgr.h (original)
+++ lldb/trunk/tools/lldb-mi/MIDriverMgr.h Fri Feb 20 04:20:05 2015
@@ -79,6 +79,7 @@ class CMIDriverMgr : public CMICmnBase,
virtual bool GetDriverIsGDBMICompatibleDriver(void) const = 0;
virtual bool SetId(const CMIUtilString &vId) = 0;
virtual const CMIUtilString &GetId(void) const = 0;
+ virtual void DeliverSignal(int signal) = 0;
// Not part of the interface, ignore
/* dtor */ virtual ~IDriver(void) {}
@@ -106,6 +107,7 @@ class CMIDriverMgr : public CMICmnBase,
CMIUtilString DriverGetError(void) const;
CMIUtilString DriverGetName(void) const;
lldb::SBDebugger *DriverGetTheDebugger(void);
+ void DeliverSignal(int signal);
// Typedef:
private:
More information about the lldb-commits
mailing list