[haiku-commits] haiku: hrev50249 - src/system/kernel/debug src/system/kernel headers/private/kernel

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sun, 24 Apr 2016 11:54:51 +0200 (CEST)

hrev50249 adds 1 changeset to branch 'master'
old head: 3218cf3b36d009689712c455600b23ef99a67a49
new head: 7a187cd6291b5d547a9aac1d94bb61f44bbedbe7
overview: 
http://cgit.haiku-os.org/haiku/log/?qt=range&q=7a187cd6291b+%5E3218cf3b36d0

----------------------------------------------------------------------------

7a187cd6291b: _user_debug_thread(): Use new signal SIGNAL_DEBUG_THREAD
  
  This resolves a TODO: We used thread_interrupt() to wake up the thread
  from an interruptable wait. However, if the thread was already in the
  kernel and about to start waiting, that would have no effect and the
  thread would wait anyway. Now there's the new non-blockable signal
  SIGNAL_DEBUG_THREAD, which is sent to the thread instead, making sure
  that thread doesn't start waiting.

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

Revision:    hrev50249
Commit:      7a187cd6291b5d547a9aac1d94bb61f44bbedbe7
URL:         http://cgit.haiku-os.org/haiku/commit/?id=7a187cd6291b
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Sat Apr  9 17:34:46 2016 UTC

----------------------------------------------------------------------------

3 files changed, 35 insertions(+), 26 deletions(-)
headers/private/kernel/ksignal.h          |  4 +++
src/system/kernel/debug/user_debugger.cpp | 35 ++++++++-------------------
src/system/kernel/signal.cpp              | 22 ++++++++++++++++-

----------------------------------------------------------------------------

diff --git a/headers/private/kernel/ksignal.h b/headers/private/kernel/ksignal.h
index 4727053..6b096dc 100644
--- a/headers/private/kernel/ksignal.h
+++ b/headers/private/kernel/ksignal.h
@@ -36,6 +36,10 @@ using BKernel::Thread;
 #define SYSCALL_RESTART_PARAMETER_SIZE 32
 
 // kernel-internal signals
+#define SIGNAL_DEBUG_THREAD            62
+       // Debug a thread. Used together with the B_THREAD_DEBUG_STOP thread 
debug
+       // flag. Continues the thread, if suspended, but has no effect 
otherwise.
+       // Non-blockable.
 #define SIGNAL_CANCEL_THREAD   63
        // Cancel a thread. Non-blockable.
 #define SIGNAL_CONTINUE_THREAD 64
diff --git a/src/system/kernel/debug/user_debugger.cpp 
b/src/system/kernel/debug/user_debugger.cpp
index fabfecd..0d74fcd 100644
--- a/src/system/kernel/debug/user_debugger.cpp
+++ b/src/system/kernel/debug/user_debugger.cpp
@@ -2903,39 +2903,24 @@ _user_debug_thread(thread_id threadID)
        if ((thread->debug_info.flags & B_THREAD_DEBUG_NUB_THREAD) != 0)
                return B_NOT_ALLOWED;
 
-       // already marked stopped?
-       if ((thread->debug_info.flags & B_THREAD_DEBUG_STOPPED) != 0)
+       // already marked stopped or being told to stop?
+       if ((thread->debug_info.flags
+                       & (B_THREAD_DEBUG_STOPPED | B_THREAD_DEBUG_STOP)) != 0) 
{
                return B_OK;
+       }
 
        // set the flag that tells the thread to stop as soon as possible
        atomic_or(&thread->debug_info.flags, B_THREAD_DEBUG_STOP);
 
        update_thread_user_debug_flag(thread);
 
-       // resume/interrupt the thread, if necessary
+       // send the thread a SIGNAL_DEBUG_THREAD, so it is interrupted (or
+       // continued)
        threadDebugInfoLocker.Unlock();
-       SpinLocker schedulerLocker(thread->scheduler_lock);
-
-       switch (thread->state) {
-               case B_THREAD_SUSPENDED:
-                       // thread suspended: wake it up
-                       scheduler_enqueue_in_run_queue(thread);
-                       break;
-
-               default:
-                       // thread may be waiting: interrupt it
-                       thread_interrupt(thread, false);
-                               // TODO: If the thread is already in the kernel 
and e.g.
-                               // about to acquire a semaphore (before
-                               // thread_prepare_to_block()), we won't 
interrupt it.
-                               // Maybe we should rather send a signal 
(SIGTRAP).
-                       schedulerLocker.Unlock();
-
-                       
schedulerLocker.SetTo(thread_get_current_thread()->scheduler_lock,
-                               false);
-                       scheduler_reschedule_if_necessary_locked();
-                       break;
-       }
+       ReadSpinLocker teamLocker(thread->team_lock);
+       SpinLocker locker(thread->team->signal_lock);
+
+       send_signal_to_thread_locked(thread, SIGNAL_DEBUG_THREAD, NULL, 0);
 
        return B_OK;
 }
diff --git a/src/system/kernel/signal.cpp b/src/system/kernel/signal.cpp
index 84a5165..8305e0b 100644
--- a/src/system/kernel/signal.cpp
+++ b/src/system/kernel/signal.cpp
@@ -45,13 +45,15 @@
 
 #define BLOCKABLE_SIGNALS      \
        (~(KILL_SIGNALS | SIGNAL_TO_MASK(SIGSTOP)       \
+       | SIGNAL_TO_MASK(SIGNAL_DEBUG_THREAD)   \
        | SIGNAL_TO_MASK(SIGNAL_CONTINUE_THREAD)        \
        | SIGNAL_TO_MASK(SIGNAL_CANCEL_THREAD)))
 #define STOP_SIGNALS \
        (SIGNAL_TO_MASK(SIGSTOP) | SIGNAL_TO_MASK(SIGTSTP) \
        | SIGNAL_TO_MASK(SIGTTIN) | SIGNAL_TO_MASK(SIGTTOU))
 #define CONTINUE_SIGNALS \
-       (SIGNAL_TO_MASK(SIGCONT) | SIGNAL_TO_MASK(SIGNAL_CONTINUE_THREAD))
+       (SIGNAL_TO_MASK(SIGCONT) | SIGNAL_TO_MASK(SIGNAL_CONTINUE_THREAD) \
+       | SIGNAL_TO_MASK(SIGNAL_DEBUG_THREAD))
 #define DEFAULT_IGNORE_SIGNALS \
        (SIGNAL_TO_MASK(SIGCHLD) | SIGNAL_TO_MASK(SIGWINCH) \
        | SIGNAL_TO_MASK(SIGCONT) \
@@ -1038,6 +1040,11 @@ handle_signals(Thread* thread)
                                                notify_debugger(thread, signal, 
handler, false);
                                        continue;
 
+                               case SIGNAL_DEBUG_THREAD:
+                                       // ignore -- used together with 
B_THREAD_DEBUG_STOP, which
+                                       // is handled above
+                                       continue;
+
                                case SIGNAL_CANCEL_THREAD:
                                        // set up the signal handler
                                        handler.sa_handler = 
thread->cancel_function;
@@ -1425,6 +1432,19 @@ send_signal_to_thread_locked(Thread* thread, uint32 
signalNumber,
 
                        break;
                }
+               case SIGNAL_DEBUG_THREAD:
+               {
+                       // Wake up thread if it was suspended, otherwise 
interrupt it.
+                       thread->going_to_suspend = false;
+
+                       SpinLocker locker(thread->scheduler_lock);
+                       if (thread->state == B_THREAD_SUSPENDED)
+                               scheduler_enqueue_in_run_queue(thread);
+                       else
+                               thread_interrupt(thread, false);
+
+                       break;
+               }
                case SIGNAL_CONTINUE_THREAD:
                {
                        // wake up thread, and interrupt its current syscall


Other related posts:

  • » [haiku-commits] haiku: hrev50249 - src/system/kernel/debug src/system/kernel headers/private/kernel - ingo_weinhold