1 /** @file
2 
3   Milestones
4 
5   @section license License
6 
7   Licensed to the Apache Software Foundation (ASF) under one
8   or more contributor license agreements.  See the NOTICE file
9   distributed with this work for additional information
10   regarding copyright ownership.  The ASF licenses this file
11   to you under the Apache License, Version 2.0 (the
12   "License"); you may not use this file except in compliance
13   with the License.  You may obtain a copy of the License at
14 
15       http://www.apache.org/licenses/LICENSE-2.0
16 
17   Unless required by applicable law or agreed to in writing, software
18   distributed under the License is distributed on an "AS IS" BASIS,
19   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20   See the License for the specific language governing permissions and
21   limitations under the License.
22  */
23 
24 #pragma once
25 
26 #include "ts/apidefs.h"
27 
28 #include "tscore/ink_platform.h"
29 #include "tscore/ink_hrtime.h"
30 
31 #include "I_EventSystem.h"
32 
33 template <class T, size_t entries> class Milestones
34 {
35 public:
36   ink_hrtime &
37   operator[](T ms)
38   {
39     return this->_milestones[static_cast<size_t>(ms)];
40   }
41   ink_hrtime
42   operator[](T ms) const
43   {
44     return this->_milestones[static_cast<size_t>(ms)];
45   }
46 
47   /**
48    * Mark given milestone with timestamp if it's not marked yet
49    * @param ms The milestone to mark
50    * @return N/A
51    */
52   void
mark(T ms)53   mark(T ms)
54   {
55     if (this->_milestones[static_cast<size_t>(ms)] == 0) {
56       this->_milestones[static_cast<size_t>(ms)] = Thread::get_hrtime();
57     }
58   }
59 
60   /**
61    * Takes two milestones and returns the difference.
62    * @param start The start time
63    * @param end The end time
64    * @return The difference time in milliseconds
65    */
66   int64_t
difference_msec(T ms_start,T ms_end)67   difference_msec(T ms_start, T ms_end) const
68   {
69     if (this->_milestones[static_cast<size_t>(ms_end)] == 0) {
70       return -1;
71     }
72     return ink_hrtime_to_msec(this->_milestones[static_cast<size_t>(ms_end)] - this->_milestones[static_cast<size_t>(ms_start)]);
73   }
74 
75   /**
76    * Takes two milestones and returns the difference.
77    * @param start The start time
78    * @param end The end time
79    * @return A double that is the difference time in seconds
80    */
81   double
difference_sec(T ms_start,T ms_end)82   difference_sec(T ms_start, T ms_end) const
83   {
84     return static_cast<double>(difference_msec(ms_start, ms_end) / 1000.0);
85   }
86 
87   /**
88    * Takes two milestones and returns the difference.
89    * @param start The start time
90    * @param end The end time
91    * @return The difference time in high-resolution time
92    */
93   ink_hrtime
elapsed(T ms_start,T ms_end)94   elapsed(T ms_start, T ms_end) const
95   {
96     return this->_milestones[static_cast<size_t>(ms_end)] - this->_milestones[static_cast<size_t>(ms_start)];
97   }
98 
99 private:
100   std::array<ink_hrtime, entries> _milestones = {{0}};
101 };
102 
103 // For compatibility with HttpSM.h and HttpTransact.h
104 using TransactionMilestones = Milestones<TSMilestonesType, TS_MILESTONE_LAST_ENTRY>;
105