2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.openflowplugin.impl.device;
10 import com.google.common.base.Preconditions;
11 import java.util.concurrent.atomic.AtomicInteger;
12 import org.checkerframework.checker.lock.qual.GuardedBy;
13 import org.checkerframework.checker.lock.qual.Holding;
15 abstract class SimpleRatelimiter {
16 private final AtomicInteger counter = new AtomicInteger();
17 private final Object counterLock = new Object();
18 @GuardedBy("counterLock")
19 private int lowWatermark;
20 private volatile int lowWatermarkEffective;
21 private volatile int highWatermark;
22 @GuardedBy("counterLock")
23 private volatile boolean limited;
25 SimpleRatelimiter(final int lowWatermark, final int highWatermark) {
26 Preconditions.checkArgument(lowWatermark >= 0);
27 Preconditions.checkArgument(highWatermark >= 0);
28 Preconditions.checkArgument(lowWatermark <= highWatermark);
30 this.lowWatermark = lowWatermark;
31 this.highWatermark = highWatermark;
32 lowWatermarkEffective = lowWatermark;
35 protected final boolean isLimited() {
39 protected abstract void disableFlow();
41 protected abstract void enableFlow();
43 boolean acquirePermit() {
44 final int cnt = counter.incrementAndGet();
45 if (cnt > highWatermark) {
46 synchronized (counterLock) {
47 final int recheck = counter.decrementAndGet();
48 if (recheck >= highWatermark && !limited) {
59 void releasePermit() {
60 final int cnt = counter.decrementAndGet();
61 if (cnt <= lowWatermarkEffective) {
62 synchronized (counterLock) {
63 final int recheck = counter.get();
64 if (recheck <= lowWatermarkEffective && limited) {
73 @Holding("counterLock")
74 private void resetLowWaterMark() {
75 lowWatermarkEffective = lowWatermark;
78 void adaptLowWaterMarkAndDisableFlow(int temporaryLowWaterMark) {
79 if (temporaryLowWaterMark < highWatermark) {
80 synchronized (counterLock) {
81 lowWatermarkEffective = temporaryLowWaterMark;
90 int getOccupiedPermits() {
94 void changeWaterMarks(final int newLowWatermark, final int newHighWatermark) {
95 synchronized (counterLock) {
96 lowWatermark = newLowWatermark;
97 highWatermark = newHighWatermark;