ysr@777: /* mikael@6198: * Copyright (c) 2001, 2013, Oracle and/or its affiliates. All rights reserved. ysr@777: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. ysr@777: * ysr@777: * This code is free software; you can redistribute it and/or modify it ysr@777: * under the terms of the GNU General Public License version 2 only, as ysr@777: * published by the Free Software Foundation. ysr@777: * ysr@777: * This code is distributed in the hope that it will be useful, but WITHOUT ysr@777: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or ysr@777: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License ysr@777: * version 2 for more details (a copy is included in the LICENSE file that ysr@777: * accompanied this code). ysr@777: * ysr@777: * You should have received a copy of the GNU General Public License version ysr@777: * 2 along with this work; if not, write to the Free Software Foundation, ysr@777: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. ysr@777: * trims@1907: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA trims@1907: * or visit www.oracle.com if you need additional information or have any trims@1907: * questions. ysr@777: * ysr@777: */ ysr@777: stefank@2314: #ifndef SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP stefank@2314: #define SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP stefank@2314: jprovino@4542: #include "utilities/macros.hpp" jprovino@4542: #if INCLUDE_ALL_GCS stefank@2314: #include "runtime/thread.hpp" jprovino@4542: #endif // INCLUDE_ALL_GCS stefank@2314: ysr@777: class VoidClosure; ysr@777: ysr@777: // A SuspendibleThreadSet is (obviously) a set of threads that can be ysr@777: // suspended. A thread can join and later leave the set, and periodically ysr@777: // yield. If some thread (not in the set) requests, via suspend_all, that ysr@777: // the threads be suspended, then the requesting thread is blocked until ysr@777: // all the threads in the set have yielded or left the set. (Threads may ysr@777: // not enter the set when an attempted suspension is in progress.) The ysr@777: // suspending thread later calls resume_all, allowing the suspended threads ysr@777: // to continue. ysr@777: ysr@777: class SuspendibleThreadSet { ysr@777: Monitor* _m; ysr@777: int _async; ysr@777: bool _async_stop; ysr@777: int _async_stopped; ysr@777: bool _initialized; ysr@777: double _suspend_all_start; ysr@777: ysr@777: void initialize_work(); ysr@777: ysr@777: public: ysr@777: SuspendibleThreadSet() : _initialized(false) {} ysr@777: ysr@777: // Add the current thread to the set. May block if a suspension ysr@777: // is in progress. ysr@777: void join(); ysr@777: // Removes the current thread from the set. ysr@777: void leave(); ysr@777: // Returns "true" iff an suspension is in progress. ysr@777: bool should_yield() { return _async_stop; } ysr@777: // Suspends the current thread if a suspension is in progress (for ysr@777: // the duration of the suspension.) ysr@777: void yield(const char* id); ysr@777: // Return when all threads in the set are suspended. ysr@777: void suspend_all(); ysr@777: // Allow suspended threads to resume. ysr@777: void resume_all(); ysr@777: // Redundant initializations okay. ysr@777: void initialize() { ysr@777: // Double-check dirty read idiom. ysr@777: if (!_initialized) initialize_work(); ysr@777: } ysr@777: }; ysr@777: ysr@777: ysr@777: class ConcurrentGCThread: public NamedThread { ysr@777: friend class VMStructs; ysr@777: ysr@777: protected: iveresov@1229: bool _should_terminate; iveresov@1229: bool _has_terminated; ysr@777: ysr@777: enum CGC_flag_type { ysr@777: CGC_nil = 0x0, ysr@777: CGC_dont_suspend = 0x1, ysr@777: CGC_CGC_safepoint = 0x2, ysr@777: CGC_VM_safepoint = 0x4 ysr@777: }; ysr@777: ysr@777: static int _CGC_flag; ysr@777: ysr@777: static bool CGC_flag_is_set(int b) { return (_CGC_flag & b) != 0; } ysr@777: static int set_CGC_flag(int b) { return _CGC_flag |= b; } ysr@777: static int reset_CGC_flag(int b) { return _CGC_flag &= ~b; } ysr@777: ysr@777: // All instances share this one set. ysr@777: static SuspendibleThreadSet _sts; ysr@777: ysr@777: // Create and start the thread (setting it's priority high.) ysr@777: void create_and_start(); ysr@777: ysr@777: // Do initialization steps in the thread: record stack base and size, ysr@777: // init thread local storage, set JNI handle block. ysr@777: void initialize_in_thread(); ysr@777: ysr@777: // Wait until Universe::is_fully_initialized(); ysr@777: void wait_for_universe_init(); ysr@777: ysr@777: // Record that the current thread is terminating, and will do more ysr@777: // concurrent work. ysr@777: void terminate(); ysr@777: ysr@777: public: ysr@777: // Constructor ysr@777: ysr@777: ConcurrentGCThread(); ysr@777: ~ConcurrentGCThread() {} // Exists to call NamedThread destructor. ysr@777: ysr@777: // Tester ysr@777: bool is_ConcurrentGC_thread() const { return true; } ysr@777: ysr@777: static void safepoint_synchronize(); ysr@777: static void safepoint_desynchronize(); ysr@777: ysr@777: // All overridings should probably do _sts::yield, but we allow ysr@777: // overriding for distinguished debugging messages. Default is to do ysr@777: // nothing. ysr@777: virtual void yield() {} ysr@777: ysr@777: bool should_yield() { return _sts.should_yield(); } ysr@777: ysr@777: // they are prefixed by sts since there are already yield() and ysr@777: // should_yield() (non-static) methods in this class and it was an ysr@777: // easy way to differentiate them. ysr@777: static void stsYield(const char* id); ysr@777: static bool stsShouldYield(); ysr@777: static void stsJoin(); ysr@777: static void stsLeave(); ysr@777: ysr@777: }; ysr@777: ysr@777: // The SurrogateLockerThread is used by concurrent GC threads for ysr@777: // manipulating Java monitors, in particular, currently for ysr@777: // manipulating the pending_list_lock. XXX ysr@777: class SurrogateLockerThread: public JavaThread { ysr@777: friend class VMStructs; ysr@777: public: ysr@777: enum SLT_msg_type { ysr@777: empty = 0, // no message ysr@777: acquirePLL, // acquire pending list lock ysr@777: releaseAndNotifyPLL // notify and release pending list lock ysr@777: }; ysr@777: private: ysr@777: // the following are shared with the CMSThread ysr@777: SLT_msg_type _buffer; // communication buffer ysr@777: Monitor _monitor; // monitor controlling buffer ysr@777: BasicLock _basicLock; // used for PLL locking ysr@777: ysr@777: public: ysr@777: static SurrogateLockerThread* make(TRAPS); ysr@777: ysr@777: SurrogateLockerThread(); ysr@777: ysr@777: bool is_hidden_from_external_view() const { return true; } ysr@777: ysr@777: void loop(); // main method ysr@777: ysr@777: void manipulatePLL(SLT_msg_type msg); ysr@777: ysr@777: }; stefank@2314: stefank@2314: #endif // SHARE_VM_GC_IMPLEMENTATION_SHARED_CONCURRENTGCTHREAD_HPP