1 /* Copyright 2016 The TensorFlow Authors. All Rights Reserved. 2 3 Licensed under the Apache License, Version 2.0 (the "License"); 4 you may not use this file except in compliance with the License. 5 You may obtain a copy of the License at 6 7 http://www.apache.org/licenses/LICENSE-2.0 8 9 Unless required by applicable law or agreed to in writing, software 10 distributed under the License is distributed on an "AS IS" BASIS, 11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 See the License for the specific language governing permissions and 13 limitations under the License. 14 ==============================================================================*/ 15 16 // PeriodicFunction will periodically call the given function with a specified 17 // period in a background thread. After Start() returns, the thread is 18 // guaranteed to have started. The destruction of the class causes the 19 // background thread to be destroyed as well. Start() should not be called more 20 // than once. 21 // 22 // PeriodicFunction runs the function as soon as any previous run both is 23 // complete and was started more than "interval_micros" earlier. Thus, runs are 24 // both serialized, and normally have a period of "interval_micros" if no run 25 // exceeds the time. 26 // 27 // Note that, if the function takes longer than two interval_micross to finish, 28 // then PeriodicFunction will "skip" at least one call to the function. For 29 // instance, if the period is 50ms and the function starts runs at time 0 for 30 // 150ms, then the function will immediately start executing again at time 150, 31 // but there will be no function runs corresponding to times 50 or 100. This is 32 // especially important to remember when using an environment with a simulated 33 // clock: advancing simulated time atomically over N interval_micross will not 34 // cause the function to be called N times. 35 // 36 // This object is thread-safe. 37 // 38 // Example: 39 // 40 // class Foo { 41 // public: 42 // Foo() : periodic_function_([this]() { Bar(); }, 43 // 1000 /* 1000us == 1ms*/) { 44 // } 45 // 46 // private: 47 // void Bar() { ... } 48 // 49 // PeriodicFunction periodic_function_; 50 // }; 51 52 #ifndef TENSORFLOW_CORE_KERNELS_BATCHING_UTIL_PERIODIC_FUNCTION_H_ 53 #define TENSORFLOW_CORE_KERNELS_BATCHING_UTIL_PERIODIC_FUNCTION_H_ 54 55 #include "tensorflow/core/kernels/batching_util/periodic_function.h" 56 57 #include <functional> 58 #include <memory> 59 #include <string> 60 61 #include "tensorflow/core/lib/core/notification.h" 62 #include "tensorflow/core/platform/env.h" 63 #include "tensorflow/core/platform/macros.h" 64 #include "tensorflow/core/platform/types.h" 65 66 namespace tensorflow { 67 namespace serving { 68 69 namespace internal { 70 class PeriodicFunctionTestAccess; 71 } 72 73 class PeriodicFunction { 74 public: 75 // Provides the ability to customize several aspects of the PeriodicFunction. 76 // Passed to constructor of PeriodicFunction. 77 struct Options { OptionsOptions78 Options() {} 79 80 // Any standard thread options, such as stack size, should 81 // be passed via "thread_options". 82 ThreadOptions thread_options; 83 84 // Specifies the thread name prefix (see the description in class 85 // Thread). 86 string thread_name_prefix = "periodic_function"; 87 88 // The environment to use. Does not take ownership, but must remain alive 89 // for as long as the PeriodicFunction exists. 90 Env* env = Env::Default(); 91 92 // Specifies the length of sleep before the first invocation of the 93 // function. 94 // This can be used for adding a random jitter to avoid synchronous behavior 95 // across multiple periodic functions. 96 int64_t startup_delay_micros = 0; 97 }; 98 99 // Also starts the background thread which will be calling the function. 100 PeriodicFunction(const std::function<void()>& function, 101 int64_t interval_micros, const Options& options = Options()); 102 103 ~PeriodicFunction(); 104 105 private: 106 friend class internal::PeriodicFunctionTestAccess; 107 108 // Notifies the background thread to stop. 109 void NotifyStop(); 110 111 // (Blocking.) Loops forever calling "function_" every "interval_micros_". 112 void RunLoop(int64_t start); 113 114 const std::function<void()> function_; // Actual client function 115 const int64_t interval_micros_; // Interval between calls. 116 const Options options_; 117 118 // Used to notify the thread to stop. 119 Notification stop_thread_; 120 121 // Thread for running "function_" 122 std::unique_ptr<Thread> thread_ = nullptr; 123 124 TF_DISALLOW_COPY_AND_ASSIGN(PeriodicFunction); 125 }; 126 127 } // namespace serving 128 } // namespace tensorflow 129 130 #endif // TENSORFLOW_CORE_KERNELS_BATCHING_UTIL_PERIODIC_FUNCTION_H_ 131