1 /* 2 * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. 7 * 8 * This code is distributed in the hope that it will be useful, but WITHOUT 9 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 11 * version 2 for more details (a copy is included in the LICENSE file that 12 * accompanied this code). 13 * 14 * You should have received a copy of the GNU General Public License version 15 * 2 along with this work; if not, write to the Free Software Foundation, 16 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 17 * 18 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19 * or visit www.oracle.com if you need additional information or have any 20 * questions. 21 * 22 */ 23 24 #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAH_PHASER_HPP 25 #define SHARE_VM_GC_SHENANDOAH_SHENANDOAH_PHASER_HPP 26 27 #include "memory/allocation.hpp" 28 29 /** 30 * This is an implementation of simplified java.util.concurrent.Phaser 31 */ 32 33 class ShenandoahPhaser : public CHeapObj<mtGC> { 34 private: 35 enum { 36 MAX_PARTIES = 0xffff, 37 MAX_PHASE = 2147483647, 38 PARTIES_SHIFT = 16, 39 PHASE_SHIFT = 32, 40 ONE_ARRIVAL = 1, 41 ONE_PARTY = 1 << PARTIES_SHIFT, 42 ONE_DEREGISTER = ONE_ARRIVAL|ONE_PARTY, 43 EMPTY = 1 44 }; 45 46 static const jlong PARTIES_MARK = 0xffff0000L; 47 static const jlong UNARRIVED_MASK = 0x0000ffffL; 48 static const jlong COUNTS_MARK = 0xffffffffL; 49 static const jlong TERMINATION_BIT = 1L << 63; 50 51 private: 52 volatile jlong _state; 53 54 public: 55 ShenandoahPhaser(int parties = 1); 56 57 inline int register_party() { return do_register(1); } 58 59 inline bool is_terminated() const { return _state < 0L; } 60 61 int arrive() { return do_arrive(ONE_ARRIVAL); } 62 int arriveAndAwaitAdvance(); 63 int arriveAndDeregister() { return do_arrive(ONE_DEREGISTER); } 64 65 inline int get_registered_parties() const { 66 return parties_of(_state); 67 } 68 69 inline int get_arrived_parties() const { 70 return arrived_of(_state); 71 } 72 73 protected: 74 // Termination condition 75 virtual bool onAdvance(int phase, int registeredParties) = 0; 76 77 // barrier 78 virtual int blockWaiters(int phase) = 0; 79 virtual void releaseWaiters(int phase) = 0; 80 81 private: 82 int do_register(int registrations); 83 int do_arrive(int adjust); 84 85 inline int parties_of(jlong s) const { return (int)((unsigned jlong)s & PARTIES_MARK) >> PARTIES_SHIFT; } 86 inline int phase_of(jlong s) const { return (int)(s >> PHASE_SHIFT); } 87 inline int arrived_of(jlong s) const { 88 int counts = (int)s; 89 return (counts == EMPTY) ? 0 : 90 (int)(((unsigned int)counts) >> PARTIES_SHIFT) - (counts & UNARRIVED_MASK); 91 } 92 inline int unarrived_of(jlong s) const { 93 int counts = (int)s; 94 return (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK); 95 } 96 97 }; 98 99 #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAH_PHASER_HPP