2 * Copyright (c) 2000 - 2015 Samsung Electronics Co., Ltd All Rights Reserved
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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
17 * @file ckm_so_loader.cpp
18 * @author Krzysztof Jackiewicz (k.jackiewicz@samsung.com)
26 #include <sys/types.h>
44 ofstream of("/proc/sys/vm/drop_caches");
47 cerr << "Cache clearing failed with errno: " << errno << endl;
54 void test(int flags, const string &library, const string &symbol)
56 bool lazy = (flags & LAZY);
58 if (flags & CLEAR_CACHE)
61 chrono::time_point<chrono::high_resolution_clock> tp[4];
63 tp[0] = chrono::high_resolution_clock::now();
64 void *handle = dlopen(library.c_str(), (lazy ? RTLD_LAZY : RTLD_NOW));
65 tp[1] = chrono::high_resolution_clock::now();
68 cerr << "dlopen failed: " << dlerror() << endl;
72 if (!symbol.empty()) {
73 tp[2] = chrono::high_resolution_clock::now();
74 void *sym = dlsym(handle, symbol.c_str());
75 tp[3] = chrono::high_resolution_clock::now();
78 cerr << "dlsym failed: " << dlerror() << endl;
85 cout << (tp[1] - tp[0]).count() << ";" << (tp[3] - tp[2]).count() << endl;
88 int main(int argc, char *argv[])
91 cerr << "Usage: ckm_so_loader [flags] [repeats] [library] [symbol]" << endl;
92 cerr << " flags: 1-clear cache, 2-lazy binding" << endl;
93 cerr << "Example: ckm_so_loader 3 100 /usr/lib/libkey-manager-client.so ckmc_save_key"
99 int flags = stoi(argv[1]); // let it throw
100 int repeats = stoi(argv[2]); // let it throw
101 string so_path(argv[3]);
102 string symbol(argv[4]);
104 cout << "dlopen[us];dlsym[us]" << endl;
106 for (int cnt = 0 ; cnt < repeats; cnt++) {
108 * It has to be a different process each time. Glibc somehow caches the library information
109 * and consecutive calls are faster
114 cerr << "fork failed with errno: " << errno << endl;
116 } else if (pid == 0) {
117 test(flags, so_path, symbol);
121 pid_t ret = waitpid(pid, &status, 0);
124 cerr << "waitpid failed with errno: " << errno << endl;
132 cerr << "Unexpected exception occured" << endl;