Commit 9e915abd authored by Ramon Nou's avatar Ramon Nou
Browse files

refactor syscall measurement logic and improve command-line argument parsing

parent d5505f2a
Loading
Loading
Loading
Loading
+95 −88
Original line number Diff line number Diff line
@@ -15,7 +15,39 @@ bool always_syscall =
        false;        // whether to call the original syscall after the hook
bool verbose = false; // whether to print debug messages

int main(int argc, char *argv[]) {

// Function to measure syscall time
template <typename PreFunc, typename PostFunc>
double
measure_syscall_time(PreFunc pre, PostFunc post, double reps) {
    const int inner_loop_size = 1000000; // Size of the inner loop (1 million)
    int repext =
            static_cast<int>(reps / inner_loop_size); // Outer loop iterations
    int repint = inner_loop_size;                     // Inner loop iterations
    double remainder = std::fmod(reps, inner_loop_size); // Remaining iterations
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);

    for(int i = 0; i < repext; ++i) {
        for(int j = 0; j < repint; ++j) {
            auto result = pre();
            post(result);
        }
    }

    for(int j = 0; j < remainder; ++j) {
        auto result = pre();
        post(result);
    }

    clock_gettime(CLOCK_MONOTONIC, &end);
    return (end.tv_sec - start.tv_sec) * 1e6 +
           (end.tv_nsec - start.tv_nsec) / 1e3;
}


int
main(int argc, char* argv[]) {
    // Parse command-line arguments
    std::string syscall;
    for(int i = 1; i < argc; ++i) {
@@ -24,14 +56,16 @@ int main(int argc, char *argv[]) {
            if(i + 1 < argc) {
                syscall = argv[++i];
            } else {
        std::cerr << "Error: --syscall requires an argument" << std::endl;
                std::cerr << "Error: --syscall requires an argument"
                          << std::endl;
                return 1;
            }
        } else if(arg == "--reps") {
            if(i + 1 < argc) {
                reps = atof(argv[++i]);
                if(reps <= 0) {
          std::cerr << "Error: --reps requires a positive integer" << std::endl;
                    std::cerr << "Error: --reps requires a positive integer"
                              << std::endl;
                    return 1;
                }
            } else {
@@ -48,12 +82,6 @@ int main(int argc, char *argv[]) {
        }
    }

  const int inner_loop_size = 1000000; // Size of the inner loop (1 million)
  int repext =
      static_cast<int>(reps / inner_loop_size); // Outer loop iterations
  int repint = inner_loop_size;                     // Inner loop iterations
  double remainder =
      std::fmod(reps, inner_loop_size); // Remaining iterations

    // Validate that --syscall is provided
    if(syscall.empty()) {
@@ -61,42 +89,21 @@ int main(int argc, char *argv[]) {
        return 1;
    }

  // Handle the --syscall option
  if (syscall == "open") {

    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);

    for (int i = 0; i < repext; ++i) {
      for (int j = 0; j < repint; ++j) {
    // Handle the --syscall option
    auto pre_open = []() {
      int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0);
      if(verbose) {
          std::cout << "open() returned " << fd << std::endl;
        std::cout << "openat() returned " << fd << std::endl;
      }
      return fd;
    };

    auto post_open = [](int fd) {
      close(fd);
      }
    }
    for (int j = 0; j < remainder; ++j) {
      int fd = openat(AT_FDCWD, "/dev/null", O_RDWR, 0);
      if (verbose) {
        std::cout << "open() returned " << fd << std::endl;
      }
      close(fd);
    }

    clock_gettime(CLOCK_MONOTONIC, &end);
    double time_taken =
        (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3;
    };

    std::cout << "Mean time taken: " << time_taken / reps << " microseconds"
              << std::endl;
  } else if (syscall == "getpid") {
    struct timespec start, end;
    clock_gettime(CLOCK_MONOTONIC, &start);

    for (int i = 0; i < repext; ++i) {
      for (int j = 0; j < repint; ++j) {
    auto pre_getpid = []() {
      int ret = getpid();
      if(verbose) {
        std::cout << "getpid() returned " << ret << std::endl;
@@ -104,22 +111,22 @@ int main(int argc, char *argv[]) {
      if(always_syscall) {
        syscall_no_intercept(SYS_getpid);
      }
      }
    }
      return ret;
    };

    for (int j = 0; j < remainder; ++j) {
      int ret = getpid();
      if (verbose) {
        std::cout << "getpid() returned " << ret << std::endl;
      }
      if (always_syscall) {
        syscall_no_intercept(SYS_getpid);
      }
    }
    auto post_getpid = [](int) {
    };

    clock_gettime(CLOCK_MONOTONIC, &end);
    double time_taken =
        (end.tv_sec - start.tv_sec) * 1e6 + (end.tv_nsec - start.tv_nsec) / 1e3;
    double time_taken = 0.0;

    if(syscall == "open") {
      time_taken = measure_syscall_time(pre_open, post_open, reps);
    } else if(syscall == "getpid") {
      time_taken = measure_syscall_time(pre_getpid, post_getpid, reps);
    } else {
      std::cerr << "Error: Unsupported syscall '" << syscall << "'" << std::endl;
      return 1;
    }

    std::cout << "Mean time taken: " << time_taken / reps << " microseconds"
              << std::endl;