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 javax.annotation.concurrent.GuardedBy;
14 abstract class SimpleRatelimiter {
15 private final AtomicInteger counter = new AtomicInteger();
16 private final Object counterLock = new Object();
17 @GuardedBy("counterLock")
18 private int lowWatermark;
19 private volatile int lowWatermarkEffective;
20 private volatile int highWatermark;
21 @GuardedBy("counterLock")
22 private volatile boolean limited;
24 SimpleRatelimiter(final int lowWatermark, final int highWatermark) {
25 Preconditions.checkArgument(lowWatermark >= 0);
26 Preconditions.checkArgument(highWatermark >= 0);
27 Preconditions.checkArgument(lowWatermark <= highWatermark);
29 this.lowWatermark = lowWatermark;
30 this.highWatermark = highWatermark;
31 lowWatermarkEffective = lowWatermark;
34 protected final boolean isLimited() {
38 protected abstract void disableFlow();
40 protected abstract void enableFlow();
42 boolean acquirePermit() {
43 final int cnt = counter.incrementAndGet();
44 if (cnt > highWatermark) {
45 synchronized (counterLock) {
46 final int recheck = counter.decrementAndGet();
47 if (recheck >= highWatermark && !limited) {
58 void releasePermit() {
59 final int cnt = counter.decrementAndGet();
60 if (cnt <= lowWatermarkEffective) {
61 synchronized (counterLock) {
62 final int recheck = counter.get();
63 if (recheck <= lowWatermarkEffective && limited) {
72 @GuardedBy("counterLock")
73 private void resetLowWaterMark() {
74 lowWatermarkEffective = lowWatermark;
77 void adaptLowWaterMarkAndDisableFlow(int temporaryLowWaterMark) {
78 if (temporaryLowWaterMark < highWatermark) {
79 synchronized (counterLock) {
80 lowWatermarkEffective = temporaryLowWaterMark;
89 int getOccupiedPermits() {
93 void changeWaterMarks(final int newLowWatermark, final int newHighWatermark) {
94 synchronized (counterLock) {
95 lowWatermark = newLowWatermark;
96 highWatermark = newHighWatermark;