< prev index next >

src/hotspot/share/runtime/handshake.hpp

Print this page
*** 49,10 ***
--- 49,11 ---
    virtual ~HandshakeClosure()                      {}
    const char* name() const                         { return _name; }
    virtual bool is_async()                          { return false; }
    virtual bool is_suspend()                        { return false; }
    virtual void do_thread(Thread* thread) = 0;
+   virtual bool can_be_processed_by(Thread* thread) { return true; }
  };
  
  class AsyncHandshakeClosure : public HandshakeClosure {
   public:
     AsyncHandshakeClosure(const char* name) : HandshakeClosure(name) {}

*** 76,10 ***
--- 77,11 ---
  // JavaThread or by the target JavaThread itself.
  class HandshakeState {
    friend ThreadSelfSuspensionHandshake;
    friend SuspendThreadHandshake;
    friend JavaThread;
+ 
    // This a back reference to the JavaThread,
    // the target for all operation in the queue.
    JavaThread* _handshakee;
    // The queue containing handshake operations to be performed on _handshakee.
    FilterQueue<HandshakeOperation*> _queue;

*** 87,15 ***
--- 89,19 ---
    // JavaThread suspend/resume operations.
    Monitor _lock;
    // Set to the thread executing the handshake operation.
    Thread* volatile _active_handshaker;
  
+   // Caller of suspension.  Only the caller can resume the thread.
+   JavaThread* _caller;
+ 
    bool claim_handshake();
    bool possibly_can_process_handshake();
    bool can_process_handshake();
  
    bool have_non_self_executable_operation();
+   static bool non_self_queue_filter(HandshakeOperation* op);
    HandshakeOperation* get_op_for_self(bool allow_suspend);
    HandshakeOperation* get_op();
    void remove_op(HandshakeOperation* op);
  
    void set_active_handshaker(Thread* thread) { Atomic::store(&_active_handshaker, thread); }

*** 148,20 ***
    // thread gets suspended again (after a resume)
    // and we have not yet processed it.
    bool _async_suspend_handshake;
  
    // Called from the suspend handshake.
!   bool suspend_with_handshake();
    // Called from the async handshake (the trap)
    // to stop a thread from continuing execution when suspended.
    void do_self_suspend();
  
!   bool is_suspended()                       { return Atomic::load(&_suspended); }
    void set_suspended(bool to)               { return Atomic::store(&_suspended, to); }
    bool has_async_suspend_handshake()        { return _async_suspend_handshake; }
    void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }
  
    bool suspend();
    bool resume();
  };
  
  #endif // SHARE_RUNTIME_HANDSHAKE_HPP
--- 154,31 ---
    // thread gets suspended again (after a resume)
    // and we have not yet processed it.
    bool _async_suspend_handshake;
  
    // Called from the suspend handshake.
!   bool suspend_with_handshake(JavaThread* caller);
+ 
    // Called from the async handshake (the trap)
    // to stop a thread from continuing execution when suspended.
    void do_self_suspend();
  
!   bool is_suspended() const                 { return Atomic::load(&_suspended); }
    void set_suspended(bool to)               { return Atomic::store(&_suspended, to); }
    bool has_async_suspend_handshake()        { return _async_suspend_handshake; }
    void set_async_suspend_handshake(bool to) { _async_suspend_handshake = to; }
  
+   void set_caller_thread(JavaThread* caller){ return Atomic::store(&_caller, caller); }
+   JavaThread* caller_thread() const         { return Atomic::load(&_caller); }
+ 
+   // "blocked" is short for saying "suspended by caller"
+   bool is_blocked() const                   { return caller_thread() != nullptr; }
+   bool is_suspended_or_blocked() const      { return is_suspended() || is_blocked(); }
+ 
    bool suspend();
    bool resume();
+ 
+   bool block_suspend(JavaThread* caller);
+   bool continue_resume(JavaThread* caller);
  };
  
  #endif // SHARE_RUNTIME_HANDSHAKE_HPP
< prev index next >