Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [gdbserver/win32] (5/11) New interrupting method : elevating the  priority
@ 2007-11-12  2:07 Pedro Alves
  2007-12-01 18:58 ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Pedro Alves @ 2007-11-12  2:07 UTC (permalink / raw)
  To: gdb-patches, Lerele

[-- Attachment #1: Type: text/plain, Size: 1069 bytes --]

Hi,

The previous patch that introduced the new interrupting
method, leaves some chances for the inferior to mess the
interrupting, since the operation is not atomic.  For
example by tweaking its own thread's priorities or if the
inferior is calling ResumeThread in its own threads while
gdbserver is stopping them.

Here is the patch that tweaks gdbserver's priorities
so to minimize those chances.

This can never be perfect, since, now we may be adding a bit
of extra entropy to other components of the system, especially
true in WinCE, where we may be inhibiting some other lower
priority thread to execute, even if just for a little.
For WinCE, I'm putting the ceiling on the highest application
priority, which is normally lower than what the time critical
drivers threads use.

This is mostly Leo's code.  I've splitted it from his
previous patch, fixed and cleaned a few things here and there,
added WinCE support, and regtested it on a local
i686-pc-cygwin gdbserver and against a remote arm-wince
gdbserver.

Leo, did I miss anything?

Cheers,
Pedro Alves




[-- Attachment #2: gdbserver_priority.diff --]
[-- Type: text/x-diff, Size: 8021 bytes --]

2007-11-12  Leo Zayas  <lerele@champenstudios@com>
	    Pedro Alves  <pedro_alves@portugalmail.pt>

	* win32-low.c (winapi_SetProcessPriorityBoost)
	(winapi_GetProcessPriorityBoost, winapi_SetProcessAffinityMask)
	[!_WIN32_WCE]: New typedefs.
	(interrupt_thread_event) [!_WIN32_WCE]: New global.
	(consume_cpu_interrupt_thread) [!_WIN32_WCE]: New.
	(realtime_execute) [!_WIN32_WCE]: New.
	(winapi_CeSetThreadPriority, winapi_CeGetThreadPriority)
	[_WIN32_WCE]: New typedefs.
	(realtime_execute) [_WIN32_WCE]: New.
	(do_continue_one_thread): New.
	(child_continue): If continuing with a faked breakpoint, do the
	thread resuming with higher priority, and don't call
	ContinueDebugEvent.
	(suspend_all_threads): New.
	(fake_breakpoint_event): Do the thread suspending with higher
	priority.

---
 gdb/gdbserver/win32-low.c |  198 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 188 insertions(+), 10 deletions(-)

Index: src/gdb/gdbserver/win32-low.c
===================================================================
--- src.orig/gdb/gdbserver/win32-low.c	2007-11-11 23:15:44.000000000 +0000
+++ src/gdb/gdbserver/win32-low.c	2007-11-11 23:15:54.000000000 +0000
@@ -267,6 +267,159 @@ do_initial_child_stuff (DWORD pid)
     (*the_low_target.initial_stuff) ();
 }
 
+#ifndef _WIN32_WCE
+
+typedef BOOL WINAPI (*winapi_SetProcessPriorityBoost) (HANDLE, BOOL);
+typedef BOOL WINAPI (*winapi_GetProcessPriorityBoost) (HANDLE, PBOOL);
+typedef BOOL WINAPI (*winapi_SetProcessAffinityMask) (HANDLE, DWORD_PTR);
+
+static HANDLE interrupt_thread_event;
+
+/* Thread function that consumes cpu while interrupt code pauses child
+   threads.  */
+static DWORD WINAPI
+consume_cpu_interrupt_thread (LPVOID data)
+{
+  while (WaitForSingleObject (interrupt_thread_event, 0) != WAIT_OBJECT_0)
+    ;
+  return 0;
+}
+
+static void
+realtime_execute (void (*func) (void*), void *args)
+{
+  DWORD old_process_priority_class;
+  DWORD old_process_affinity_mask;
+  BOOL old_process_priority_boost;
+  DWORD system_affinity_mask;
+  HANDLE h;
+  SYSTEM_INFO sys_info;
+  HANDLE *threads = NULL;
+  HMODULE dll;
+
+  winapi_SetProcessPriorityBoost SetProcessPriorityBoost;
+  winapi_GetProcessPriorityBoost GetProcessPriorityBoost;
+  winapi_SetProcessAffinityMask SetProcessAffinityMask;
+
+  dll = GetModuleHandle (_T("KERNEL32.DLL"));
+  SetProcessPriorityBoost = GETPROCADDRESS (dll, SetProcessPriorityBoost);
+  GetProcessPriorityBoost = GETPROCADDRESS (dll, GetProcessPriorityBoost);
+  SetProcessAffinityMask = GETPROCADDRESS (dll, SetProcessAffinityMask);
+
+  h = GetCurrentProcess ();
+
+  old_process_priority_class = GetPriorityClass (h);
+
+  /* Go real-time so we can pause child as atomically as possible.  */
+  SetPriorityClass (h, REALTIME_PRIORITY_CLASS);
+
+  if (GetProcessPriorityBoost != NULL)
+    GetProcessPriorityBoost (h, &old_process_priority_boost);
+  if (SetProcessPriorityBoost != NULL)
+    SetProcessPriorityBoost (h, FALSE);
+
+  GetSystemInfo (&sys_info);
+
+  if (sys_info.dwNumberOfProcessors > 1)
+    {
+      int thr;
+      GetProcessAffinityMask (h,
+			      &old_process_affinity_mask,
+			      &system_affinity_mask);
+
+      /* Set gdbserver to run on all CPUs.  */
+      if (SetProcessAffinityMask != NULL)
+	SetProcessAffinityMask (h, system_affinity_mask);
+
+      interrupt_thread_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+      threads = alloca (sizeof (HANDLE) * (sys_info.dwNumberOfProcessors - 1));
+      for (thr = 0; thr < sys_info.dwNumberOfProcessors - 1; thr++)
+	threads[thr] = CreateThread (NULL, 0, consume_cpu_interrupt_thread,
+				     NULL, 0, NULL);
+    }
+
+  /* Do the work.  */
+  (*func) (args);
+
+  /* Revert the priorities.  */
+  if (sys_info.dwNumberOfProcessors > 1)
+    {
+      int thr;
+
+      /* Once paused, signal gdbserver secondary cpu-consumption threads
+	 to terminate, wait for them to do so, and gracefully free all
+	 synchronization objects.  */
+      SetEvent (interrupt_thread_event);
+      WaitForMultipleObjects (sys_info.dwNumberOfProcessors - 1,
+			      threads, TRUE, INFINITE);
+      for (thr = 0; thr < sys_info.dwNumberOfProcessors - 1; thr++)
+	CloseHandle (threads[thr]);
+      CloseHandle (interrupt_thread_event);
+
+      if (SetProcessAffinityMask != NULL)
+	SetProcessAffinityMask (h, old_process_affinity_mask);
+    }
+
+  /* Restore gdbserver Windows scheduling state.  */
+  if (SetProcessPriorityBoost != NULL)
+    SetProcessPriorityBoost (h, old_process_priority_boost);
+  SetPriorityClass (h, old_process_priority_class);
+}
+
+#else
+
+typedef BOOL WINAPI (*winapi_CeSetThreadPriority) (HANDLE, int);
+typedef int WINAPI (*winapi_CeGetThreadPriority) (HANDLE);
+
+static void
+realtime_execute (void (*func) (void*), void *args)
+{
+  /* Windows CE (at least up to 6) does not support multi-processor.
+     Windows CE is a real-time operating system, with a fixed priority
+     scheduler.  Each thread runs at particular priority level, and
+     the highest priority runnable thread is always the one that is
+     run.  If there is more than one thread at that priority level,
+     they are run round-robin.  */
+
+  HANDLE h = GetCurrentThread ();
+  int prio;
+
+  static HMODULE dll = NULL;
+  static winapi_CeSetThreadPriority CeSetThreadPriority = NULL;
+  static winapi_CeGetThreadPriority CeGetThreadPriority = NULL;
+
+  if (dll == NULL)
+    {
+      dll = GetModuleHandle (L"COREDLL.DLL");
+      CeSetThreadPriority = GETPROCADDRESS (dll, CeSetThreadPriority);
+      CeGetThreadPriority = GETPROCADDRESS (dll, CeGetThreadPriority);
+    }
+
+  if (CeSetThreadPriority != NULL)
+    {
+      prio = CeGetThreadPriority (h);
+      /* Highest priority below drivers.  */
+      CeSetThreadPriority (h, 153);
+    }
+  else
+    {
+      prio = GetThreadPriority (h);
+      SetThreadPriority (h, THREAD_PRIORITY_TIME_CRITICAL);
+    }
+
+  /* Do the work.  */
+  (*func) (args);
+
+  /* Revert the priority.  */
+  if (CeSetThreadPriority != NULL)
+    CeSetThreadPriority (h, prio);
+  else
+    SetThreadPriority (h, prio);
+}
+
+#endif
+
 /* Resume all artificially suspended threads if we are continuing
    execution.  */
 static int
@@ -297,18 +450,37 @@ continue_one_thread (struct inferior_lis
   return 0;
 }
 
+static void
+do_continue_one_thread (void *args)
+{
+  int *thread_id_ptr = args;
+  find_inferior (&all_threads, continue_one_thread, thread_id_ptr);
+}
+
 static BOOL
 child_continue (DWORD continue_status, int thread_id)
 {
-  /* The inferior will only continue after the ContinueDebugEvent
-     call.  */
-  find_inferior (&all_threads, continue_one_thread, &thread_id);
-  faked_breakpoint = 0;
-
-  if (!ContinueDebugEvent (current_event.dwProcessId,
-			   current_event.dwThreadId,
-			   continue_status))
-    return FALSE;
+  if (faked_breakpoint)
+    {
+      realtime_execute (do_continue_one_thread, &thread_id);
+      faked_breakpoint = 0;
+    }
+  else
+    {
+      /* The inferior will only continue after the ContinueDebugEvent
+	 call.  */
+      find_inferior (&all_threads, continue_one_thread, &thread_id);
+
+      if (!ContinueDebugEvent (current_event.dwProcessId,
+			       current_event.dwThreadId,
+			       continue_status))
+	{
+	  DWORD err = GetLastError ();
+	  OUTMSG (("warning: ContinueDebugEvent failed in child_continue, "
+		   "(error %d): %s\n", (int) err, strwinerror (err)));
+	  return FALSE;
+	}
+    }
 
   return TRUE;
 }
@@ -1278,6 +1450,12 @@ suspend_one_thread (struct inferior_list
 }
 
 static void
+suspend_all_threads (void *data)
+{
+  for_each_inferior (&all_threads, suspend_one_thread);
+}
+
+static void
 fake_breakpoint_event (void)
 {
   OUTMSG2(("fake_breakpoint_event\n"));
@@ -1290,7 +1468,7 @@ fake_breakpoint_event (void)
   current_event.u.Exception.ExceptionRecord.ExceptionCode =
     EXCEPTION_BREAKPOINT;
 
-  for_each_inferior (&all_threads, suspend_one_thread);
+  realtime_execute (suspend_all_threads, NULL);
 }
 
 /* Get the next event from the child.  */




^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [gdbserver/win32] (5/11) New interrupting method : elevating  the  priority
  2007-11-12  2:07 [gdbserver/win32] (5/11) New interrupting method : elevating the priority Pedro Alves
@ 2007-12-01 18:58 ` Daniel Jacobowitz
  2007-12-03  3:54   ` Pedro Alves
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Jacobowitz @ 2007-12-01 18:58 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, Lerele

On Mon, Nov 12, 2007 at 02:07:31AM +0000, Pedro Alves wrote:
> 2007-11-12  Leo Zayas  <lerele@champenstudios@com>
> 	    Pedro Alves  <pedro_alves@portugalmail.pt>
> 
> 	* win32-low.c (winapi_SetProcessPriorityBoost)
> 	(winapi_GetProcessPriorityBoost, winapi_SetProcessAffinityMask)
> 	[!_WIN32_WCE]: New typedefs.
> 	(interrupt_thread_event) [!_WIN32_WCE]: New global.
> 	(consume_cpu_interrupt_thread) [!_WIN32_WCE]: New.
> 	(realtime_execute) [!_WIN32_WCE]: New.
> 	(winapi_CeSetThreadPriority, winapi_CeGetThreadPriority)
> 	[_WIN32_WCE]: New typedefs.
> 	(realtime_execute) [_WIN32_WCE]: New.
> 	(do_continue_one_thread): New.
> 	(child_continue): If continuing with a faked breakpoint, do the
> 	thread resuming with higher priority, and don't call
> 	ContinueDebugEvent.
> 	(suspend_all_threads): New.
> 	(fake_breakpoint_event): Do the thread suspending with higher
> 	priority.

I'm just going to have to trust you on this one.  It looks fine.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [gdbserver/win32] (5/11) New interrupting method : elevating   the  priority
  2007-12-01 18:58 ` Daniel Jacobowitz
@ 2007-12-03  3:54   ` Pedro Alves
  2008-01-29 17:00     ` Daniel Jacobowitz
  0 siblings, 1 reply; 4+ messages in thread
From: Pedro Alves @ 2007-12-03  3:54 UTC (permalink / raw)
  To: gdb-patches, Lerele

[-- Attachment #1: Type: text/plain, Size: 1297 bytes --]

Daniel Jacobowitz wrote:
> On Mon, Nov 12, 2007 at 02:07:31AM +0000, Pedro Alves wrote:
>> 2007-11-12  Leo Zayas
>> 	    Pedro Alves  <pedro_alves@portugalmail.pt>
>>
>> 	* win32-low.c (winapi_SetProcessPriorityBoost)
>> 	(winapi_GetProcessPriorityBoost, winapi_SetProcessAffinityMask)
>> 	[!_WIN32_WCE]: New typedefs.
>> 	(interrupt_thread_event) [!_WIN32_WCE]: New global.
>> 	(consume_cpu_interrupt_thread) [!_WIN32_WCE]: New.
>> 	(realtime_execute) [!_WIN32_WCE]: New.
>> 	(winapi_CeSetThreadPriority, winapi_CeGetThreadPriority)
>> 	[_WIN32_WCE]: New typedefs.
>> 	(realtime_execute) [_WIN32_WCE]: New.
>> 	(do_continue_one_thread): New.
>> 	(child_continue): If continuing with a faked breakpoint, do the
>> 	thread resuming with higher priority, and don't call
>> 	ContinueDebugEvent.
>> 	(suspend_all_threads): New.
>> 	(fake_breakpoint_event): Do the thread suspending with higher
>> 	priority.
> 
> I'm just going to have to trust you on this one.  It looks fine.
> 

Thank you.

I've checked the whole series in, except for this one and the next (6).

Leo, could you take a look at the attached patch?  It's a
refresh against current cvs, with a minor tweak to minimize a
race in the previous version -- we were creating the threads
but not waiting for them to start.

-- 
Pedro Alves


[-- Attachment #2: gdbserver_priority.diff --]
[-- Type: text/x-diff, Size: 8433 bytes --]

2007-12-03  Leo Zayas
	    Pedro Alves  <pedro_alves@portugalmail.pt>

	* win32-low.c (winapi_SetProcessPriorityBoost)
	(winapi_GetProcessPriorityBoost, winapi_SetProcessAffinityMask)
	[!_WIN32_WCE]: New typedefs.
	(interrupt_thread_event) [!_WIN32_WCE]: New global.
	(consume_cpu_interrupt_thread) [!_WIN32_WCE]: New.
	(realtime_execute) [!_WIN32_WCE]: New.
	(winapi_CeSetThreadPriority, winapi_CeGetThreadPriority)
	[_WIN32_WCE]: New typedefs.
	(realtime_execute) [_WIN32_WCE]: New.
	(do_continue_one_thread): New.
	(child_continue): If continuing with a faked breakpoint, do the
	thread resuming with higher priority, and don't call
	ContinueDebugEvent.
	(suspend_all_threads): New.
	(fake_breakpoint_event): Do the thread suspending with higher
	priority.

---
 gdb/gdbserver/win32-low.c |  214 +++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 204 insertions(+), 10 deletions(-)

Index: src/gdb/gdbserver/win32-low.c
===================================================================
--- src.orig/gdb/gdbserver/win32-low.c	2007-12-03 01:42:20.000000000 +0000
+++ src/gdb/gdbserver/win32-low.c	2007-12-03 01:42:32.000000000 +0000
@@ -300,6 +300,175 @@ do_initial_child_stuff (DWORD pid)
     (*the_low_target.initial_stuff) ();
 }
 
+#ifndef _WIN32_WCE
+
+typedef BOOL WINAPI (*winapi_SetProcessPriorityBoost) (HANDLE, BOOL);
+typedef BOOL WINAPI (*winapi_GetProcessPriorityBoost) (HANDLE, PBOOL);
+typedef BOOL WINAPI (*winapi_SetProcessAffinityMask) (HANDLE, DWORD_PTR);
+
+static HANDLE interrupt_thread_event;
+
+/* Thread function that consumes cpu while interrupt code pauses child
+   threads.  */
+static DWORD WINAPI
+consume_cpu_interrupt_thread (LPVOID data)
+{
+  HANDLE* ran = data;
+  SetEvent (*ran);
+  while (WaitForSingleObject (interrupt_thread_event, 0) != WAIT_OBJECT_0)
+    ;
+  return 0;
+}
+
+static void
+realtime_execute (void (*func) (void*), void *args)
+{
+  DWORD old_process_priority_class;
+  DWORD old_process_affinity_mask;
+  BOOL old_process_priority_boost;
+  DWORD system_affinity_mask;
+  HANDLE h;
+  SYSTEM_INFO sys_info;
+  HANDLE *threads = NULL;
+  HANDLE *events = NULL;
+  HMODULE dll;
+
+  winapi_SetProcessPriorityBoost SetProcessPriorityBoost;
+  winapi_GetProcessPriorityBoost GetProcessPriorityBoost;
+  winapi_SetProcessAffinityMask SetProcessAffinityMask;
+
+  dll = GetModuleHandle (_T("KERNEL32.DLL"));
+  SetProcessPriorityBoost = GETPROCADDRESS (dll, SetProcessPriorityBoost);
+  GetProcessPriorityBoost = GETPROCADDRESS (dll, GetProcessPriorityBoost);
+  SetProcessAffinityMask = GETPROCADDRESS (dll, SetProcessAffinityMask);
+
+  h = GetCurrentProcess ();
+
+  old_process_priority_class = GetPriorityClass (h);
+
+  /* Go real-time so we can pause child as atomically as possible.  */
+  SetPriorityClass (h, REALTIME_PRIORITY_CLASS);
+
+  if (GetProcessPriorityBoost != NULL)
+    GetProcessPriorityBoost (h, &old_process_priority_boost);
+  if (SetProcessPriorityBoost != NULL)
+    SetProcessPriorityBoost (h, FALSE);
+
+  GetSystemInfo (&sys_info);
+
+  if (sys_info.dwNumberOfProcessors > 1)
+    {
+      int i;
+
+      GetProcessAffinityMask (h,
+			      &old_process_affinity_mask,
+			      &system_affinity_mask);
+
+      /* Set gdbserver to run on all CPUs.  */
+      if (SetProcessAffinityMask != NULL)
+	SetProcessAffinityMask (h, system_affinity_mask);
+
+      /* manual reset */
+      interrupt_thread_event = CreateEvent (NULL, TRUE, FALSE, NULL);
+
+      threads = alloca (sizeof (HANDLE) * (sys_info.dwNumberOfProcessors - 1));
+      events = alloca (sizeof (HANDLE) * (sys_info.dwNumberOfProcessors - 1));
+      for (i = 0; i < sys_info.dwNumberOfProcessors - 1; i++)
+	{
+	  events[i] = CreateEvent (NULL, FALSE, FALSE, NULL);
+	  threads[i] = CreateThread (NULL, 0, consume_cpu_interrupt_thread,
+				     &events[i], 0, NULL);
+	}
+
+      /* wait all */
+      WaitForMultipleObjects(sys_info.dwNumberOfProcessors - 1,
+			     events, TRUE, INFINITE);
+
+      for (i = 0; i < sys_info.dwNumberOfProcessors - 1; i++)
+	CloseHandle (events[i]);
+    }
+
+  /* Do the work.  */
+  (*func) (args);
+
+  /* Revert the priorities.  */
+  if (sys_info.dwNumberOfProcessors > 1)
+    {
+      int i;
+
+      /* Once paused, signal gdbserver secondary cpu-consumption threads
+	 to terminate, wait for them to do so, and gracefully free all
+	 synchronization objects.  */
+      SetEvent (interrupt_thread_event);
+      WaitForMultipleObjects (sys_info.dwNumberOfProcessors - 1,
+			      threads, TRUE, INFINITE);
+      for (i = 0; i < sys_info.dwNumberOfProcessors - 1; i++)
+	CloseHandle (threads[i]);
+      CloseHandle (interrupt_thread_event);
+
+      if (SetProcessAffinityMask != NULL)
+	SetProcessAffinityMask (h, old_process_affinity_mask);
+    }
+
+  /* Restore gdbserver Windows scheduling state.  */
+  if (SetProcessPriorityBoost != NULL)
+    SetProcessPriorityBoost (h, old_process_priority_boost);
+  SetPriorityClass (h, old_process_priority_class);
+}
+
+#else
+
+typedef BOOL WINAPI (*winapi_CeSetThreadPriority) (HANDLE, int);
+typedef int WINAPI (*winapi_CeGetThreadPriority) (HANDLE);
+
+static void
+realtime_execute (void (*func) (void*), void *args)
+{
+  /* Windows CE (at least up to 6) does not support multi-processor.
+     Windows CE is a real-time operating system, with a fixed priority
+     scheduler.  Each thread runs at particular priority level, and
+     the highest priority runnable thread is always the one that is
+     run.  If there is more than one thread at that priority level,
+     they are run round-robin.  */
+
+  HANDLE h = GetCurrentThread ();
+  int prio;
+
+  static HMODULE dll = NULL;
+  static winapi_CeSetThreadPriority CeSetThreadPriority = NULL;
+  static winapi_CeGetThreadPriority CeGetThreadPriority = NULL;
+
+  if (dll == NULL)
+    {
+      dll = GetModuleHandle (L"COREDLL.DLL");
+      CeSetThreadPriority = GETPROCADDRESS (dll, CeSetThreadPriority);
+      CeGetThreadPriority = GETPROCADDRESS (dll, CeGetThreadPriority);
+    }
+
+  if (CeSetThreadPriority != NULL)
+    {
+      prio = CeGetThreadPriority (h);
+      /* Highest priority below drivers.  */
+      CeSetThreadPriority (h, 153);
+    }
+  else
+    {
+      prio = GetThreadPriority (h);
+      SetThreadPriority (h, THREAD_PRIORITY_TIME_CRITICAL);
+    }
+
+  /* Do the work.  */
+  (*func) (args);
+
+  /* Revert the priority.  */
+  if (CeSetThreadPriority != NULL)
+    CeSetThreadPriority (h, prio);
+  else
+    SetThreadPriority (h, prio);
+}
+
+#endif
+
 /* Resume all artificially suspended threads if we are continuing
    execution.  */
 static int
@@ -330,18 +499,37 @@ continue_one_thread (struct inferior_lis
   return 0;
 }
 
+static void
+do_continue_one_thread (void *args)
+{
+  int *thread_id_ptr = args;
+  find_inferior (&all_threads, continue_one_thread, thread_id_ptr);
+}
+
 static BOOL
 child_continue (DWORD continue_status, int thread_id)
 {
-  /* The inferior will only continue after the ContinueDebugEvent
-     call.  */
-  find_inferior (&all_threads, continue_one_thread, &thread_id);
-  faked_breakpoint = 0;
-
-  if (!ContinueDebugEvent (current_event.dwProcessId,
-			   current_event.dwThreadId,
-			   continue_status))
-    return FALSE;
+  if (faked_breakpoint)
+    {
+      realtime_execute (do_continue_one_thread, &thread_id);
+      faked_breakpoint = 0;
+    }
+  else
+    {
+      /* The inferior will only continue after the ContinueDebugEvent
+	 call.  */
+      find_inferior (&all_threads, continue_one_thread, &thread_id);
+
+      if (!ContinueDebugEvent (current_event.dwProcessId,
+			       current_event.dwThreadId,
+			       continue_status))
+	{
+	  DWORD err = GetLastError ();
+	  OUTMSG (("warning: ContinueDebugEvent failed in child_continue, "
+		   "(error %d): %s\n", (int) err, strwinerror (err)));
+	  return FALSE;
+	}
+    }
 
   return TRUE;
 }
@@ -1313,6 +1501,12 @@ suspend_one_thread (struct inferior_list
 }
 
 static void
+suspend_all_threads (void *data)
+{
+  for_each_inferior (&all_threads, suspend_one_thread);
+}
+
+static void
 fake_breakpoint_event (void)
 {
   OUTMSG2(("fake_breakpoint_event\n"));
@@ -1325,7 +1519,7 @@ fake_breakpoint_event (void)
   current_event.u.Exception.ExceptionRecord.ExceptionCode
     = EXCEPTION_BREAKPOINT;
 
-  for_each_inferior (&all_threads, suspend_one_thread);
+  realtime_execute (suspend_all_threads, NULL);
 }
 
 /* Get the next event from the child.  */

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [gdbserver/win32] (5/11) New interrupting method : elevating  the  priority
  2007-12-03  3:54   ` Pedro Alves
@ 2008-01-29 17:00     ` Daniel Jacobowitz
  0 siblings, 0 replies; 4+ messages in thread
From: Daniel Jacobowitz @ 2008-01-29 17:00 UTC (permalink / raw)
  To: Pedro Alves; +Cc: gdb-patches, Lerele

On Mon, Dec 03, 2007 at 02:45:54AM +0000, Pedro Alves wrote:
> Thank you.
>
> I've checked the whole series in, except for this one and the next (6).
>
> Leo, could you take a look at the attached patch?  It's a
> refresh against current cvs, with a minor tweak to minimize a
> race in the previous version -- we were creating the threads
> but not waiting for them to start.

No one's responded to this, and it's been quite a while - at this
point, I think it's OK to commit.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2008-01-29 16:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-12  2:07 [gdbserver/win32] (5/11) New interrupting method : elevating the priority Pedro Alves
2007-12-01 18:58 ` Daniel Jacobowitz
2007-12-03  3:54   ` Pedro Alves
2008-01-29 17:00     ` Daniel Jacobowitz

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox