1 /* 2 * Copyright (c) 2018, 2019, Oracle and/or its affiliates. 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_MEMORY_METASPACE_COUNTER_HPP 26 #define SHARE_MEMORY_METASPACE_COUNTER_HPP 27 28 #include "runtime/atomic.hpp" 29 #include "utilities/debug.hpp" 30 #include "utilities/globalDefinitions.hpp" 31 32 33 namespace metaspace { 34 35 // A very simple helper class which counts something, offers decrement/increment 36 // methods and checks for overflow/underflow on increment/decrement. 37 // 38 // (since we seem to do that alot....) 39 40 template <class T> 41 class AbstractCounter { 42 43 T _c; 44 45 public: 46 47 AbstractCounter() : _c(0) {} 48 49 T get() const { return _c; } 50 51 void increment() { assert(_c + 1 > _c, "overflow"); _c ++; } 52 void increment_by(T v) { assert(_c + v >= _c, "overflow"); _c += v; } 53 void decrement() { assert(_c - 1 < _c, "underflow"); _c --; } 54 void decrement_by(T v) { assert(_c - v <= _c, "underflow"); _c -= v; } 55 56 #ifdef ASSERT 57 void check(T expected) const { 58 assert(_c == expected, "Counter mismatch: %d, expected: %d.", 59 (int)_c, (int)expected); 60 } 61 #endif 62 63 }; 64 65 typedef AbstractCounter<size_t> SizeCounter; 66 typedef AbstractCounter<int> IntCounter; 67 68 69 template <class T> 70 class AbstractAtomicCounter { 71 72 volatile T _c; 73 74 public: 75 76 AbstractAtomicCounter() : _c(0) {} 77 78 T get() const { return _c; } 79 80 void increment() { assert(_c + 1 > _c, "overflow"); Atomic::inc(&_c); } 81 void increment_by(T v) { assert(_c + v >= _c, "overflow"); Atomic::add(&_c, v); } 82 void decrement() { assert(_c - 1 < _c, "underflow"); Atomic::dec(&_c); } 83 void decrement_by(T v) { assert(_c - v <= _c, "underflow"); Atomic::sub(&_c, v); } 84 85 #ifdef ASSERT 86 void check(T expected) const { 87 assert(_c == expected, "Counter mismatch: %d, expected: %d.", 88 (int)_c, (int)expected); 89 } 90 #endif 91 92 }; 93 94 typedef AbstractAtomicCounter<size_t> SizeAtomicCounter; 95 96 97 98 } // namespace metaspace 99 100 #endif // SHARE_MEMORY_METASPACE_WORDSIZECOUNTER_HPP 101