1 /*
2 * Copyright 2020 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
18 #define LOG_TAG "GpuProfilingData"
19
20 #include <chrono>
21 #include <csignal>
22 #include <string>
23 #include <thread>
24 #include <unistd.h>
25 #include <vector>
26
27 #include <android/log.h>
28 #include <dlfcn.h>
29
30 #define ALOGI(msg, ...) \
31 __android_log_print(ANDROID_LOG_INFO, LOG_TAG, (msg), __VA_ARGS__)
32 #define ALOGE(msg, ...) \
33 __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, (msg), __VA_ARGS__)
34 #define ALOGD(msg, ...) \
35 __android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, (msg), __VA_ARGS__)
36 #define REQUIRE_SUCCESS(fn, name) \
37 do { \
38 if (VK_SUCCESS != fn) { \
39 ALOGE("Vulkan Error in %s", name); \
40 return -1; \
41 } \
42 } while (0)
43
44 namespace {
45
46 typedef void (*FN_PTR)(void);
47
48 /**
49 * Load the vendor provided counter producer library.
50 * startCounterProducer is a thin rewrite of the same producer loading logic in
51 * github.com/google/agi
52 */
53
startCounterProducer()54 int startCounterProducer() {
55 ALOGI("%s", "Loading producer library");
56 char *error;
57 std::string libDir = sizeof(void *) == 8 ? "lib64" : "lib";
58 std::string producerPath = "/vendor/" + libDir + "/libgpudataproducer.so";
59
60 ALOGI("Trying %s", producerPath.c_str());
61 void *handle = dlopen(producerPath.c_str(), RTLD_GLOBAL);
62 if ((error = dlerror()) != nullptr || handle == nullptr) {
63 ALOGE("Error loading lib: %s", error);
64 return -1;
65 }
66
67 FN_PTR startFunc = (FN_PTR)dlsym(handle, "start");
68 if ((error = dlerror()) != nullptr) {
69 ALOGE("Error looking for start symbol: %s", error);
70 dlclose(handle);
71 return -1;
72 }
73
74 if (startFunc == nullptr) {
75 ALOGE("Did not find the producer library %s", producerPath.c_str());
76 ALOGE("LD_LIBRARY_PATH=%s", getenv("LD_LIBRARY_PATH"));
77 return -1;
78 }
79
80 ALOGI("Calling start at %p", startFunc);
81 (*startFunc)();
82 ALOGI("Producer %s has exited.", producerPath.c_str());
83 dlclose(handle);
84 return 0;
85 }
86
87 volatile std::sig_atomic_t done = 0;
88
89 } // anonymous namespace
90
main()91 int main() {
92 std::signal(SIGTERM, [](int /*signal*/) {
93 ALOGI("%s", "SIGTERM received");
94 done = 1;
95 });
96 std::thread dummy([&]() {
97 int result = startCounterProducer();
98 ALOGI("%s %d", "startCounterProducer returned", result);
99 });
100 ALOGI("%s", "Waiting for host");
101 while (!done) {
102 std::this_thread::sleep_for(std::chrono::milliseconds(100));
103 }
104 return 0;
105 }
106