// Like time(1), but for power consumption.
//
// Copyright Troels Henriksen (athas@sigkill.dk), licensed under the
// GPLv3 or any later version.
//
// Using the Linux RAPL interface provided in /sys, prints the energy
// used by the CPU while running the given command.  Note that this is
// total system energy consumption; not just the energy consumed by
// the indicated command.  Run this on an otherwise quiet system if
// you want to see power consumption of a single command.
//
// Probably needs to run with root permissions.

#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
#include <unistd.h>

long read_uj() {
  const char *energy_uj_fname = "/sys/class/powercap/intel-rapl/intel-rapl:0/energy_uj";
  FILE* f = fopen(energy_uj_fname, "r");

  if (f == NULL) {
    fprintf(stderr, "%s: %s\n", energy_uj_fname, strerror(errno));
    exit(1);
  }

  long x;
  fscanf(f, "%ld", &x);
  fclose(f);
  return x;
}

int main(int argc, char** argv) {
  if (argc < 2) {
    printf("Usage: %s <command> [args...]\n", argv[0]);
    return 1;
  }

  long bef = read_uj();

  int pid;
  if ((pid = fork()) == 0) {
    execvp(argv[1], argv+1);
    fprintf(stderr, "%s: %s\n", argv[1], strerror(errno));
    exit(1);
  }

  int status;
  waitpid(pid, &status, 0);

  long aft = read_uj();
  printf("%f J\n", (aft-bef)/1e6);
}