1 /*
  2  * Copyright (c) 2013, 2021, Red Hat, Inc. All rights reserved.
  3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  4  *
  5  * This code is free software; you can redistribute it and/or modify it
  6  * under the terms of the GNU General Public License version 2 only, as
  7  * published by the Free Software Foundation.
  8  *
  9  * This code is distributed in the hope that it will be useful, but WITHOUT
 10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 12  * version 2 for more details (a copy is included in the LICENSE file that
 13  * accompanied this code).
 14  *
 15  * You should have received a copy of the GNU General Public License version
 16  * 2 along with this work; if not, write to the Free Software Foundation,
 17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 18  *
 19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 20  * or visit www.oracle.com if you need additional information or have any
 21  * questions.
 22  *
 23  */
 24 
 25 #ifndef SHARE_GC_SHENANDOAH_SHENANDOAHCONTROLTHREAD_HPP
 26 #define SHARE_GC_SHENANDOAH_SHENANDOAHCONTROLTHREAD_HPP
 27 
 28 #include "gc/shared/gcCause.hpp"
 29 #include "gc/shared/concurrentGCThread.hpp"
 30 #include "gc/shenandoah/shenandoahGC.hpp"
 31 #include "gc/shenandoah/shenandoahPadding.hpp"
 32 #include "gc/shenandoah/shenandoahSharedVariables.hpp"
 33 
 34 class ShenandoahControlThread: public ConcurrentGCThread {
 35   friend class VMStructs;
 36 
 37 private:
 38   typedef enum {
 39     none,
 40     concurrent_normal,
 41     stw_degenerated,
 42     stw_full
 43   } GCMode;
 44 
 45   // While we could have a single lock for these, it may risk unblocking
 46   // GC waiters when alloc failure GC cycle finishes. We want instead
 47   // to make complete explicit cycle for for demanding customers.
 48   Monitor _alloc_failure_waiters_lock;
 49   Monitor _gc_waiters_lock;
 50 
 51 public:
 52   void run_service();
 53   void stop_service();
 54 
 55 private:
 56   ShenandoahSharedFlag _gc_requested;
 57   ShenandoahSharedFlag _alloc_failure_gc;
 58   ShenandoahSharedFlag _graceful_shutdown;
 59   GCCause::Cause       _requested_gc_cause;
 60   ShenandoahGC::ShenandoahDegenPoint _degen_point;
 61 
 62   shenandoah_padding(0);
 63   volatile size_t _allocs_seen;
 64   shenandoah_padding(1);
 65   volatile size_t _gc_id;
 66   shenandoah_padding(2);
 67 
 68   bool check_cancellation_or_degen(ShenandoahGC::ShenandoahDegenPoint point);
 69   void service_concurrent_normal_cycle(GCCause::Cause cause);
 70   void service_stw_full_cycle(GCCause::Cause cause);
 71   void service_stw_degenerated_cycle(GCCause::Cause cause, ShenandoahGC::ShenandoahDegenPoint point);
 72 
 73   bool try_set_alloc_failure_gc();
 74   void notify_alloc_failure_waiters();
 75   bool is_alloc_failure_gc();
 76 
 77   void reset_gc_id();
 78   void update_gc_id();
 79   size_t get_gc_id();
 80 
 81   void notify_gc_waiters();
 82 
 83   // Handle GC request.
 84   // Blocks until GC is over.
 85   void handle_requested_gc(GCCause::Cause cause);
 86 
 87 public:
 88   // Constructor
 89   ShenandoahControlThread();
 90 
 91   // Handle allocation failure from a mutator allocation.
 92   // Optionally blocks while collector is handling the failure. If the GC
 93   // threshold has been exceeded, the mutator allocation will not block so
 94   // that the out of memory error can be raised promptly.
 95   void handle_alloc_failure(ShenandoahAllocRequest& req, bool block = true);
 96 
 97   // Handle allocation failure from evacuation path.
 98   void handle_alloc_failure_evac(size_t words);
 99 
100   void request_gc(GCCause::Cause cause);
101 
102   void pacing_notify_alloc(size_t words);
103 
104   void start();
105   void prepare_for_graceful_shutdown();
106   bool in_graceful_shutdown();
107 };
108 
109 #endif // SHARE_GC_SHENANDOAH_SHENANDOAHCONTROLTHREAD_HPP