Bug 579877 - Slow Threads update for debugging on remote target

Reason:
=======
The problem is that we use '-thread-info' command for each thread and
for each command, a lot of common conversation happen between gdb and
gdbserver for each command.

Solution:
=========
We should use '-list-thread-groups <group id>' instead which provides
the same required information for all the threads and minimizes the
communication between gdb and gdbserver. This command takes lesser time
than the collective time taken by all '-thread-info' commands.

Tested with 2 and 8 threaded application using gdb 7.1 and 11. The gain
is more prominent as the number of threads increases.

Signed-off-by: Umair Sair <umair_sair@hotmail.com>

Change-Id: Ie4824bf110f05d4136697f4e1ecbcc19dcf145a7
diff --git a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_1.java b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_1.java
index abfaa3f..81ff87d 100644
--- a/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_1.java
+++ b/dsf-gdb/org.eclipse.cdt.dsf.gdb/src/org/eclipse/cdt/dsf/gdb/service/GDBProcesses_7_1.java
@@ -41,7 +41,6 @@
 import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo;
 import org.eclipse.cdt.dsf.mi.service.command.output.MIListThreadGroupsInfo.IThreadGroupInfo;
 import org.eclipse.cdt.dsf.mi.service.command.output.MIThread;
-import org.eclipse.cdt.dsf.mi.service.command.output.MIThreadInfoInfo;
 import org.eclipse.cdt.dsf.service.DsfServiceEventHandler;
 import org.eclipse.cdt.dsf.service.DsfSession;
 import org.eclipse.core.runtime.IStatus;
@@ -178,20 +177,25 @@
 				}
 			});
 		} else if (dmc instanceof MIThreadDMC) {
-			// Starting with GDB 7.1, we can obtain the core on which a thread
-			// is currently located.  The info is a new field in -thread-info
-			final MIThreadDMC threadDmc = (MIThreadDMC) dmc;
-
 			ICommandControlDMContext controlDmc = DMContexts.getAncestorOfType(dmc, ICommandControlDMContext.class);
-			fCommandForCoresCache.execute(fCommandFactory.createMIThreadInfo(controlDmc, threadDmc.getId()),
-					new ImmediateDataRequestMonitor<MIThreadInfoInfo>(rm) {
+			final String groupId = getGroupFromPid(
+					(DMContexts.getParentOfType(dmc, IMIProcessDMContext.class)).getProcId());
+			String threadId = ((MIThreadDMC) dmc).getId();
+
+			fCommandForCoresCache.execute(fCommandFactory.createMIListThreadGroups(controlDmc, groupId),
+					new ImmediateDataRequestMonitor<MIListThreadGroupsInfo>(rm) {
 						@Override
-						protected void handleSuccess() {
+						protected void handleCompleted() {
 							IThreadDMData threadData = null;
-							if (getData().getThreadList().length != 0) {
-								MIThread thread = getData().getThreadList()[0];
-								if (thread.getThreadId().equals(threadDmc.getId())) {
-									threadData = createThreadDMData(thread);
+							if (isSuccess()) {
+								MIThread[] threads = getData().getThreadInfo().getThreadList();
+								if (threads != null) {
+									for (MIThread thread : threads) {
+										if (thread.getThreadId().equals(threadId)) {
+											threadData = createThreadDMData(thread);
+											break;
+										}
+									}
 								}
 							}
 
@@ -199,7 +203,7 @@
 								rm.setData(threadData);
 							} else {
 								rm.setStatus(new Status(IStatus.ERROR, GdbPlugin.PLUGIN_ID, INVALID_HANDLE,
-										"Could not get thread info", null)); //$NON-NLS-1$
+										"Could not get thread info", getStatus().getException())); //$NON-NLS-1$
 							}
 							rm.done();
 						}