1 // Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
2 //  This source code is licensed under both the GPLv2 (found in the
3 //  COPYING file in the root directory) and Apache 2.0 License
4 //  (found in the LICENSE.Apache file in the root directory).
5 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
6 // Use of this source code is governed by a BSD-style license that can be
7 // found in the LICENSE file. See the AUTHORS file for names of contributors.
8 
9 #pragma once
10 #include <stdint.h>
11 
12 #include <memory>
13 
14 #include "rocksdb/customizable.h"
15 #include "rocksdb/rocksdb_namespace.h"
16 #include "rocksdb/status.h"
17 
18 #ifdef _WIN32
19 // Windows API macro interference
20 #undef GetCurrentTime
21 #endif
22 
23 namespace ROCKSDB_NAMESPACE {
24 struct ConfigOptions;
25 
26 // A SystemClock is an interface used by the rocksdb implementation to access
27 // operating system time-related functionality.
28 class SystemClock : public Customizable {
29  public:
~SystemClock()30   virtual ~SystemClock() {}
31 
Type()32   static const char* Type() { return "SystemClock"; }
33   static Status CreateFromString(const ConfigOptions& options,
34                                  const std::string& value,
35                                  std::shared_ptr<SystemClock>* result);
36   // The name of this system clock
37   virtual const char* Name() const = 0;
38 
39   // The name/nickname for the Default SystemClock.  This name can be used
40   // to determine if the clock is the default one.
kDefaultName()41   static const char* kDefaultName() { return "DefaultClock"; }
42 
43   // Return a default SystemClock suitable for the current operating
44   // system.
45   static const std::shared_ptr<SystemClock>& Default();
46 
47   // Returns the number of micro-seconds since some fixed point in time.
48   // It is often used as system time such as in GenericRateLimiter
49   // and other places so a port needs to return system time in order to work.
50   virtual uint64_t NowMicros() = 0;
51 
52   // Returns the number of nano-seconds since some fixed point in time. Only
53   // useful for computing deltas of time in one run.
54   // Default implementation simply relies on NowMicros.
55   // In platform-specific implementations, NowNanos() should return time points
56   // that are MONOTONIC.
NowNanos()57   virtual uint64_t NowNanos() { return NowMicros() * 1000; }
58 
59   // Returns the number of micro-seconds of CPU time used by the current thread.
60   // 0 indicates not supported.
CPUMicros()61   virtual uint64_t CPUMicros() { return 0; }
62 
63   // Returns the number of nano-seconds of CPU time used by the current thread.
64   // Default implementation simply relies on CPUMicros.
65   // 0 indicates not supported.
CPUNanos()66   virtual uint64_t CPUNanos() { return CPUMicros() * 1000; }
67 
68   // Sleep/delay the thread for the prescribed number of micro-seconds.
69   virtual void SleepForMicroseconds(int micros) = 0;
70 
71   // Get the number of seconds since the Epoch, 1970-01-01 00:00:00 (UTC).
72   // Only overwrites *unix_time on success.
73   virtual Status GetCurrentTime(int64_t* unix_time) = 0;
74 
75   // Converts seconds-since-Jan-01-1970 to a printable string
76   virtual std::string TimeToString(uint64_t time) = 0;
77 };
78 
79 // Wrapper class for a SystemClock.  Redirects all methods (except Name)
80 // of the SystemClock interface to the target/wrapped class.
81 class SystemClockWrapper : public SystemClock {
82  public:
83   explicit SystemClockWrapper(const std::shared_ptr<SystemClock>& t);
84 
NowMicros()85   uint64_t NowMicros() override { return target_->NowMicros(); }
86 
NowNanos()87   uint64_t NowNanos() override { return target_->NowNanos(); }
88 
CPUMicros()89   uint64_t CPUMicros() override { return target_->CPUMicros(); }
90 
CPUNanos()91   uint64_t CPUNanos() override { return target_->CPUNanos(); }
92 
SleepForMicroseconds(int micros)93   virtual void SleepForMicroseconds(int micros) override {
94     return target_->SleepForMicroseconds(micros);
95   }
96 
GetCurrentTime(int64_t * unix_time)97   Status GetCurrentTime(int64_t* unix_time) override {
98     return target_->GetCurrentTime(unix_time);
99   }
100 
TimeToString(uint64_t time)101   std::string TimeToString(uint64_t time) override {
102     return target_->TimeToString(time);
103   }
104 
105   Status PrepareOptions(const ConfigOptions& options) override;
106 #ifndef ROCKSDB_LITE
107   std::string SerializeOptions(const ConfigOptions& config_options,
108                                const std::string& header) const override;
109 #endif  // ROCKSDB_LITE
Inner()110   const Customizable* Inner() const override { return target_.get(); }
111 
112  protected:
113   std::shared_ptr<SystemClock> target_;
114 };
115 
116 }  // end namespace ROCKSDB_NAMESPACE
117