diff --git a/devlib/bin/arm64/readenergy b/devlib/bin/arm64/readenergy index 2918038..01806ce 100755 Binary files a/devlib/bin/arm64/readenergy and b/devlib/bin/arm64/readenergy differ diff --git a/src/readenergy/readenergy.c b/src/readenergy/readenergy.c index 1f33ab9..6e4f35f 100644 --- a/src/readenergy/readenergy.c +++ b/src/readenergy/readenergy.c @@ -89,6 +89,9 @@ // Default counter poll period (in milliseconds). #define DEFAULT_PERIOD 100 +// Default duration for the instrument execution (in seconds); 0 means 'forever' +#define DEFAULT_DURATION 0 + // A single reading from the energy meter. The values are the proper readings converted // to appropriate units (e.g. Watts for power); they are *not* raw counter values. struct reading @@ -143,11 +146,15 @@ void print_help() { fprintf(stderr, "Usage: readenergy [-t PERIOD] [-o OUTFILE]\n\n" "Read Juno energy counters every PERIOD milliseconds, writing them\n" - "to OUTFILE in CSV format until SIGTERM is received.\n" + "to OUTFILE in CSV format either until SIGTERM is received OR\n" + "till the specified duration elapsed.\n" "If OUTFILE is not specified, stdout will be used.\n\n" "Parameters:\n" " PERIOD is the counter poll period in milliseconds.\n" " (Defaults to 100 milliseconds.)\n" + " DURATION is the duration before execution terminates.\n" + " (Defaults to 0 seconds, meaning run till user\n" + " terminates execution.\n" " OUTFILE is the output file path\n"); } @@ -164,6 +171,7 @@ struct config { struct timespec period; char *output_file; + long duration_in_sec; }; void config_init_period_from_millis(struct config *this, long millis) @@ -176,9 +184,10 @@ void config_init(struct config *this, int argc, char *argv[]) { this->output_file = NULL; config_init_period_from_millis(this, DEFAULT_PERIOD); + this->duration_in_sec = DEFAULT_DURATION; int opt; - while ((opt = getopt(argc, argv, "ht:o:")) != -1) + while ((opt = getopt(argc, argv, "ht:o:d:")) != -1) { switch(opt) { @@ -188,6 +197,9 @@ void config_init(struct config *this, int argc, char *argv[]) case 'o': this->output_file = optarg; break; + case 'd': + this->duration_in_sec = atol(optarg); + break; case 'h': print_help(); exit(EXIT_SUCCESS); @@ -314,13 +326,19 @@ void emeter_finalize(struct emeter *this) // -------------------------------------- /emeter ---------------------------------------------------- -int done = 0; +volatile int done = 0; void term_handler(int signum) { done = 1; } +void sigalrm_handler(int signum) +{ + done = 1; +} + + int main(int argc, char *argv[]) { struct sigaction action; @@ -333,6 +351,17 @@ int main(int argc, char *argv[]) config_init(&config, argc, argv); emeter_init(&emeter, config.output_file); + if (0 != config.duration_in_sec) + { + /*Set the alarm with the duration from use only if a non-zero value is specified + else it will run forever until SIGTERM signal received from user*/ + /*Set the signal handler first*/ + signal(SIGALRM, sigalrm_handler); + /*Now set the alarm for the duration specified by the user*/ + alarm(config.duration_in_sec); + + } + if(config.output_file) { struct timespec remaining;