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 #include <android-base/file.h>
18 #include <android-base/logging.h>
19 #include <android-base/result.h>
20 #include <jni.h>
21 #include <time.h>
22 
23 using android::base::ErrnoError;
24 using android::base::Error;
25 using android::base::Result;
26 using android::base::WriteStringToFd;
27 
28 constexpr size_t kNumBytesPerMB = 1024 * 1024;
29 
measure_send_rate(int fd,int num_bytes_to_send)30 Result<double> measure_send_rate(int fd, int num_bytes_to_send) {
31     std::string data;
32     data.assign(num_bytes_to_send, 'a');
33     struct timespec start;
34     if (clock_gettime(CLOCK_MONOTONIC, &start) == -1) {
35         return ErrnoError() << "failed to clock_gettime";
36     }
37     if (!WriteStringToFd(data, fd)) {
38         return Error() << "Cannot send data to client";
39     }
40     struct timespec finish;
41     if (clock_gettime(CLOCK_MONOTONIC, &finish) == -1) {
42         return ErrnoError() << "failed to clock_gettime";
43     }
44     double elapsed_seconds = finish.tv_sec - start.tv_sec + (finish.tv_nsec - start.tv_nsec) / 1e9;
45     LOG(INFO) << "Host:Finished sending data in " << elapsed_seconds << " seconds.";
46     double send_rate = (double)num_bytes_to_send / kNumBytesPerMB / elapsed_seconds;
47     return {send_rate};
48 }
49 
50 extern "C" JNIEXPORT jdouble JNICALL
Java_com_android_microdroid_benchmark_IoVsockHostNative_measureSendRate(__unused JNIEnv * env,__unused jclass clazz,int fd,int num_bytes_to_send)51 Java_com_android_microdroid_benchmark_IoVsockHostNative_measureSendRate(__unused JNIEnv *env,
52                                                                         __unused jclass clazz,
53                                                                         int fd,
54                                                                         int num_bytes_to_send) {
55     if (auto res = measure_send_rate(fd, num_bytes_to_send); res.ok()) {
56         return res.value();
57     } else {
58         LOG(ERROR) << "Cannot send data from host to VM: " << res.error();
59         abort();
60     }
61 }
62