/* * Copyright (c) 2017, Red Hat, Inc. and/or its affiliates. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. * */ #ifndef SHARE_VM_GC_SHENANDOAH_SHENANDOAH_PHASER_HPP #define SHARE_VM_GC_SHENANDOAH_SHENANDOAH_PHASER_HPP #include "memory/allocation.hpp" /** * This is an implementation of simplified java.util.concurrent.Phaser */ class ShenandoahPhaser : public CHeapObj { private: enum { MAX_PARTIES = 0xffff, MAX_PHASE = 2147483647, PARTIES_SHIFT = 16, PHASE_SHIFT = 32, ONE_ARRIVAL = 1, ONE_PARTY = 1 << PARTIES_SHIFT, ONE_DEREGISTER = ONE_ARRIVAL|ONE_PARTY, EMPTY = 1 }; static const jlong PARTIES_MARK = 0xffff0000L; static const jlong UNARRIVED_MASK = 0x0000ffffL; static const jlong COUNTS_MARK = 0xffffffffL; static const jlong TERMINATION_BIT = 1L << 63; private: volatile jlong _state; public: ShenandoahPhaser(int parties = 1); inline int register_party() { return do_register(1); } inline bool is_terminated() const { return _state < 0L; } int arrive() { return do_arrive(ONE_ARRIVAL); } int arriveAndAwaitAdvance(); int arriveAndDeregister() { return do_arrive(ONE_DEREGISTER); } inline int get_registered_parties() const { return parties_of(_state); } inline int get_arrived_parties() const { return arrived_of(_state); } protected: // Termination condition virtual bool onAdvance(int phase, int registeredParties) = 0; // barrier virtual int blockWaiters(int phase) = 0; virtual void releaseWaiters(int phase) = 0; private: int do_register(int registrations); int do_arrive(int adjust); inline int parties_of(jlong s) const { return (int)((unsigned jlong)s & PARTIES_MARK) >> PARTIES_SHIFT; } inline int phase_of(jlong s) const { return (int)(s >> PHASE_SHIFT); } inline int arrived_of(jlong s) const { int counts = (int)s; return (counts == EMPTY) ? 0 : (int)(((unsigned int)counts) >> PARTIES_SHIFT) - (counts & UNARRIVED_MASK); } inline int unarrived_of(jlong s) const { int counts = (int)s; return (counts == EMPTY) ? 0 : (counts & UNARRIVED_MASK); } }; #endif // SHARE_VM_GC_SHENANDOAH_SHENANDOAH_PHASER_HPP