• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
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 #ifndef SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_CLOCK_FUNCTIONS_H_
18 #define SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_CLOCK_FUNCTIONS_H_
19 
20 #include <sqlite3.h>
21 #include <unordered_map>
22 #include "perfetto/ext/base/base64.h"
23 #include "protos/perfetto/common/builtin_clock.pbzero.h"
24 #include "src/trace_processor/importers/common/clock_converter.h"
25 #include "src/trace_processor/prelude/functions/create_function_internal.h"
26 #include "src/trace_processor/util/status_macros.h"
27 
28 #include "src/trace_processor/prelude/functions/sql_function.h"
29 
30 namespace perfetto {
31 namespace trace_processor {
32 
33 struct AbsTimeStr : public SqlFunction {
34   using Context = ClockConverter;
35   static base::Status Run(ClockConverter* tracker,
36                           size_t argc,
37                           sqlite3_value** argv,
38                           SqlValue& out,
39                           Destructors& destructors);
40 };
41 
Run(ClockConverter * tracker,size_t argc,sqlite3_value ** argv,SqlValue & out,Destructors & destructors)42 base::Status AbsTimeStr::Run(ClockConverter* tracker,
43                              size_t argc,
44                              sqlite3_value** argv,
45                              SqlValue& out,
46                              Destructors& destructors) {
47   if (argc != 1) {
48     return base::ErrStatus("ABS_TIME_STR: 1 arg required");
49   }
50 
51   // If the timestamp is null, just return null as the result.
52   if (sqlite3_value_type(argv[0]) == SQLITE_NULL) {
53     return base::OkStatus();
54   }
55   if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER) {
56     return base::ErrStatus("ABS_TIME_STR: first argument should be timestamp");
57   }
58 
59   int64_t ts = sqlite3_value_int64(argv[0]);
60   base::StatusOr<std::string> iso8601 = tracker->ToAbsTime(ts);
61   if (!iso8601.ok()) {
62     // We are returning an OkStatus, because one bad timestamp shouldn't stop
63     // the query.
64     return base::OkStatus();
65   }
66 
67   std::unique_ptr<char, base::FreeDeleter> s(
68       static_cast<char*>(malloc(iso8601->size() + 1)));
69   memcpy(s.get(), iso8601->c_str(), iso8601->size() + 1);
70 
71   destructors.string_destructor = free;
72   out = SqlValue::String(s.release());
73   return base::OkStatus();
74 }
75 
76 struct ToMonotonic : public SqlFunction {
77   using Context = ClockConverter;
78   static base::Status Run(ClockConverter* tracker,
79                           size_t argc,
80                           sqlite3_value** argv,
81                           SqlValue& out,
82                           Destructors& destructors);
83 };
84 
Run(ClockConverter * tracker,size_t argc,sqlite3_value ** argv,SqlValue & out,Destructors &)85 base::Status ToMonotonic::Run(ClockConverter* tracker,
86                               size_t argc,
87                               sqlite3_value** argv,
88                               SqlValue& out,
89                               Destructors&) {
90   if (argc != 1) {
91     return base::ErrStatus("TO_MONOTONIC: 1 arg required");
92   }
93 
94   // If the timestamp is null, just return null as the result.
95   if (sqlite3_value_type(argv[0]) == SQLITE_NULL) {
96     return base::OkStatus();
97   }
98   if (sqlite3_value_type(argv[0]) != SQLITE_INTEGER) {
99     return base::ErrStatus("TO_MONOTONIC: first argument should be timestamp");
100   }
101 
102   int64_t ts = sqlite3_value_int64(argv[0]);
103   base::StatusOr<int64_t> monotonic = tracker->ToMonotonic(ts);
104 
105   if (!monotonic.ok()) {
106     // We are returning an OkStatus, because one bad timestamp shouldn't stop
107     // the query.
108     return base::OkStatus();
109   }
110 
111   out = SqlValue::Long(*monotonic);
112   return base::OkStatus();
113 }
114 
115 }  // namespace trace_processor
116 }  // namespace perfetto
117 
118 #endif  // SRC_TRACE_PROCESSOR_PRELUDE_FUNCTIONS_CLOCK_FUNCTIONS_H_
119