/* Copyright 2017 The Australian National University Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ #include #include #include #include #include "callback.h" #define DEFAULT_FLOAT_FORMAT_PREC 6 // 1 microsec #include #ifdef __MACH__ // Use mach_absolute_time on macOS typedef uint64_t timestamp_t; #include static inline void get_nano_timestamp(timestamp_t* tstamp) { *tstamp = mach_absolute_time(); } double get_elapsed_time(timestamp_t* t0, timestamp_t* t1) { mach_timebase_info_data_t tb; timestamp_t elapsed; uint64_t elapsed_nano; mach_timebase_info(&tb); elapsed = *t1 - *t0; elapsed_nano = elapsed * tb.numer / tb.denom; return ((double)elapsed_nano) * 1e-9; } #else // Use clock_gettime on Linux typedef struct timespec timestamp_t; static inline void get_nano_timestamp(timestamp_t* tstamp) { clock_gettime(CLOCK_PROCESS_CPUTIME_ID, tstamp); } double get_elapsed_time(timestamp_t* t0, timestamp_t* t1) { return ((double)(t1->tv_sec - t0->tv_sec)) + ((double)(t1->tv_nsec - t0->tv_nsec)) * 1e-9; } #endif // records a series of readings struct Callback { int fltfmtprec; // float format precision timestamp_t t0; // begin time timestamp_t t1; // end time }; typedef struct Callback Callback; /** * param_s: accept an at most two digit integer string for float format precision */ struct Callback *cb_init(const char *param_s) { Callback *cb; cb = (Callback *)malloc(sizeof(Callback)); cb->fltfmtprec = strlen(param_s) > 0 ? atoi(param_s) : DEFAULT_FLOAT_FORMAT_PREC; return cb; } // NOTE: assuming current strategy of only one data point per run. void cb_begin(struct Callback *cb) { // call time measurement function get_nano_timestamp(&cb->t0); } void cb_end(struct Callback *cb) { get_nano_timestamp(&cb->t1); } void cb_report(struct Callback *cb) { char fmtstr [6]; // NOTE: assume precision number is at most two digit sprintf(fmtstr, "%%.%dlf", cb->fltfmtprec); printf(fmtstr, get_elapsed_time(&cb->t0, &cb->t1)); printf("\n"); }