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