removing non-existing file from the build
[folly.git] / folly / wangle / concurrent / Codel.cpp
1 /*
2  * Copyright 2015 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/wangle/concurrent/Codel.h>
18 #include <algorithm>
19 #include <math.h>
20
21 #ifndef NO_LIB_GFLAGS
22   #include <gflags/gflags.h>
23   DEFINE_int32(codel_interval, 100,
24                "Codel default interval time in ms");
25   DEFINE_int32(codel_target_delay, 5,
26                "Target codel queueing delay in ms");
27 #endif
28
29 namespace folly { namespace wangle {
30
31 #ifdef NO_LIB_GFLAGS
32   int32_t FLAGS_codel_interval = 100;
33   int32_t FLAGS_codel_target_delay = 5;
34 #endif
35
36 Codel::Codel()
37     : codelMinDelay_(0),
38       codelIntervalTime_(std::chrono::steady_clock::now()),
39       codelResetDelay_(true),
40       overloaded_(false) {}
41
42 bool Codel::overloaded(std::chrono::microseconds delay) {
43   bool ret = false;
44   auto now = std::chrono::steady_clock::now();
45
46   // Avoid another thread updating the value at the same time we are using it
47   // to calculate the overloaded state
48   auto minDelay = codelMinDelay_;
49
50   if (now  > codelIntervalTime_ &&
51       (!codelResetDelay_.load(std::memory_order_acquire)
52        && !codelResetDelay_.exchange(true))) {
53     codelIntervalTime_ = now + std::chrono::milliseconds(FLAGS_codel_interval);
54
55     if (minDelay > std::chrono::milliseconds(FLAGS_codel_target_delay)) {
56       overloaded_ = true;
57     } else {
58       overloaded_ = false;
59     }
60   }
61   // Care must be taken that only a single thread resets codelMinDelay_,
62   // and that it happens after the interval reset above
63   if (codelResetDelay_.load(std::memory_order_acquire) &&
64       codelResetDelay_.exchange(false)) {
65     codelMinDelay_ = delay;
66     // More than one request must come in during an interval before codel
67     // starts dropping requests
68     return false;
69   } else if(delay < codelMinDelay_) {
70     codelMinDelay_ = delay;
71   }
72
73   if (overloaded_ &&
74       delay > std::chrono::milliseconds(FLAGS_codel_target_delay * 2)) {
75     ret = true;
76   }
77
78   return ret;
79
80 }
81
82 int Codel::getLoad() {
83   return std::min(100, (int)codelMinDelay_.count() /
84                   (2 * FLAGS_codel_target_delay));
85 }
86
87 int Codel::getMinDelay() {
88   return (int) codelMinDelay_.count();
89 }
90
91 }} //namespace