How to define C API to get current time count in nanosecond? - c

I need to define C API ex. GetTimerCountInNS(void) to get current TimerCount in Nanosecond, so using this API call I can calculate total execution time of some work done in nanosecond. Can someone suggest me what is wrong with my GetTimerCountInNS function as when I am calculating total execution time it shows incorrect execution time however for MilliSecond it shows correct one.
I already checked other query related to same one but I could not found exact answer.As I dont want to write all equation into main code when calculating time in nanosecond.
I need to use custom API to get count in Nanosecond and by getting different of start and stop time count I need to get total execution time.
How to get current timestamp in nanoseconds in linux using c
Calculating Function time in nanoseconds in C code
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdint.h>
#include <time.h>
#define BILLION 1000000000L;
// This API provides incorrect time in NS duration
uint64_t GetTimerCountInNS(void)
{
struct timespec currenttime;
clock_gettime( CLOCK_REALTIME, &currenttime);
//I am not sure here how to calculate count in NS
return currenttime.tv_nsec;
}
// This API provides correct time in MS duration
uint64_t GetTimerCountInMS(void)
{
struct timespec currenttime;
clock_gettime( CLOCK_REALTIME, &currenttime);
return (1000 * currenttime.tv_sec) + ((double)currenttime.tv_nsec / 1e6);
}
int main( int argc, char** argv )
{
struct timespec start, stop;
uint64_t start_ns,end_ns;
uint64_t start_ms,end_ms;
clock_gettime( CLOCK_REALTIME, &start);
start_ms = GetTimerCountInMS();
start_ns = GetTimerCountInNS();
int f = 0;
sleep(3);
clock_gettime( CLOCK_REALTIME, &stop);
end_ms = GetTimerCountInMS();
end_ns = GetTimerCountInNS();
double total_time_sec = ( stop.tv_sec - start.tv_sec ) + (double)( stop.tv_nsec - start.tv_nsec ) / (double)BILLION;
printf( "time in sec \t: %lf\n", total_time_sec );
printf( "time in ms \t: %ld\n", (end_ms - start_ms) );
printf( "time in ns \t: %ld\n", (end_ns - start_ns) );
return EXIT_SUCCESS;
}
Output:
time in sec : 3.000078
time in ms : 3000
time in ns : 76463 // This shows wrong time

A fix:
uint64_t GetTimerCountInNS(void) {
struct timespec currenttime;
clock_gettime(CLOCK_REALTIME, &currenttime);
return UINT64_C(1000000000) * currenttime.tv_sec + currenttime.tv_nsec;
}
In the return, a uint64_t constant is used to promote all other operands of the binary arithmetic operators to uint64_t, in addition to converting seconds to nanoseconds.

Related

Error trying getting clock resolution time

I'm using C and I'm trying to get Clock resolution but I get this value: 0.000000
Here is the code I'm using
#include <time.h>
#include<stdio.h>
double duration(struct timespec start, struct timespec end) {
return end.tv_sec - start.tv_sec
+ ((end.tv_nsec - start.tv_nsec ) / (double) 1000000000.0);
}
double getResolution(){
struct timespec start, end;
clock_gettime(CLOCK_MONOTONIC, &start);
do {
clock_gettime(CLOCK_MONOTONIC, &end);
} while (duration(start, end) == 0.0);
return duration(start, end);
}
int main(){
printf("%f",getResolution());
return 0;
}
You need to increase the precision in your printf("%f");. Using printf("%.12f"); would probably be enough to show some non-zero decimals.
Calculating the floating point duration in the while loop may cause the program to actually perform that calculation if the compiler isn't clever enough to figure out that you only need to see if the clock has changed at all. You could just do a memcmp to compare start and end instead.
Don't take the struct timespecs by value in your duration function. Supply pointers to the function instead. It should be cheaper.
Use the clock_getres function to get the resolution. The runtime value you get with your homebrewed solution depends on what speed the CPU is currently running at etc.
Example:
#include <stdio.h>
#include <string.h>
#include <time.h>
// taking the arguments via pointers:
double duration(const struct timespec* start, const struct timespec* end) {
return end->tv_sec - start->tv_sec +
((end->tv_nsec - start->tv_nsec) / 1000000000.0);
}
double getResolution() {
struct timespec start = {0}, end = {0};
clock_gettime(CLOCK_MONOTONIC, &start);
do {
clock_gettime(CLOCK_MONOTONIC, &end);
// using memcmp below:
} while (memcmp(&start, &end, sizeof start) == 0);
return duration(&start, &end);
}
int main() {
struct timespec base = {0}, res;
// using the proper function to get the resolution:
clock_getres(CLOCK_MONOTONIC, &res);
// comparing the results:
printf("clock_getres = %.12f\n", duration(&base, &res));
printf("getResolution = %.12f\n", getResolution());
}
Demo

Tracking a task's execution time in C (ignoring time task is suspended)

I have to track how long a task executes for. I am working on Linux, but I do not have access to the kernel itself.
My task simply busy-loops until the process has been executing for a certain amount of time. Then the process is supposed to break out of this loop.
I had a somewhat working version that used clock_gettime() from time.h. I stored the time since Epoch right before I busy looped in a "start" variable. Then in each iteration of the loop, I checked the time since Epoch again in another variable called "current".
Oh each iteration of the loop, I took the difference between "current" and "start". If that difference was greater than or equal to my requested execution time, I broke out of the loop.
The trouble is clock_gettime() does not factor in suspension of a task. So if my task suspends, the way I am doing this now will treat the time a task is suspended as if it were still executing.
Does anyone have an alternative to clock_gettime() that will allow a timer to somehow ignore the suspension time? Code of my current method below.
//DOES NOT HANDLE TASK SUSPENSION
#include <time.h>
#define BILLION 1E9
//Set execution time to 2 seconds
double executionTime = 2;
//Variable used later to compute difference in time
double elapsedTime = -1;
struct timespec start;
struct timespec current;
//Get time before we busy-loop
clock_gettime(CLOCK_REALTIME, &start);
int i;
for (i = 0; i < 10000000000; i++)
{
//Get time on each busy-loop iteration
clock_gettime(CLOCK_REALTIME, &current);
elapsedTime = (current.tv_sec - start.tv_sec) + ((current.tv_nsec - start.tv_nsec) / BILLION);
//If we have been executing for the specified execution time, break.
if (elapsedTime >= executionTime)
{
break;
}
}
Change CLOCK_REALTIME to CLOCK_PROCESS_CPU_TIME.
using sleep() takes several seconds to accumulate a small amount of CPU time.
#include <stdio.h>
#include <unistd.h>
#include <time.h>
#define BILLION 1E9
int main ( void) {
double executionTime = 0.0001;
double elapsedTime = -1;
double elapsedTimertc = -1;
struct timespec startrtc;
struct timespec start;
struct timespec currentrtc;
struct timespec current;
clock_gettime(CLOCK_REALTIME, &startrtc);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);
for (;;)
{
sleep ( 1);
clock_gettime(CLOCK_REALTIME, &currentrtc);
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &current);
elapsedTime = (current.tv_sec - start.tv_sec) + ((current.tv_nsec - start.tv_nsec) / BILLION);
elapsedTimertc = (currentrtc.tv_sec - startrtc.tv_sec) + ((currentrtc.tv_nsec - startrtc.tv_nsec) / BILLION);
if (elapsedTime >= executionTime)
{
break;
}
}
printf ( "elapsed time %f\n", elapsedTime);
printf ( "elapsed time %f\n", elapsedTimertc);
}

clock_gettime API is giving negative values

I want current system time in micro seconds, so i have written a program using clock_gettime But it is returning negative values some times. Can someone help me on this.
int main(void) {
struct timespec tms;
/* The C11 way */
/* if (! timespec_get(&tms, TIME_UTC)) { */
/* POSIX.1-2008 way */
if (clock_gettime(CLOCK_REALTIME,&tms)) {
return -1;
}
/* seconds, multiplied with 1 million */
long long micros = tms.tv_sec * 1000000;
/* Add full microseconds */
micros += tms.tv_nsec/1000;
printf("Microseconds: %lld\n",micros);
return 0;
}
Hope the below code helps you:
#include<stdio.h>
#include<math.h>
#include<time.h>
void get_time_in_ms()
{
long ms;
time_t time;
struct timespec spec;
char tm[14];
clock_gettime(CLOCK_REALTIME, &spec);
time = spec.tv_sec;
ms = round(spec.tv_nsec / 1000000 ); // Convert nanoseconds to milliseconds
printf("Current time: %lu.%03ld seconds since the Epoch\n", time, ms);
sprintf(tm,"%lu%03ld",time, ms);
printf("Time : %s\n", tm);
}
void main() {
get_time_in_ms();
}

Clock_Gettime() Jitter?

I am using clock_gettime() (from time.h) on Linux 2.6 to control timing in my thread loop. I need 500mS within +/- 5mS timing. It seems to be giving me 500mS for a while then starts drifting or jittering to +/- 30mS:
I am using the CLOCK_REALTIME call with it. Is there any way to improve the deviation it is having? I'm simply counting every mS with it and once the counter hits 500 fire off an interrupt.
This is also within the QT 4.3 Framework. The QTimer seemed even more jittery than this.
Based on the wording of your question, I have a feeling you might be accumulating your time differences incorrectly.
Try this approach:
#include <stdio.h>
#include <time.h>
long elapsed_milli( struct timespec * t1, struct timespec *t2 )
{
return (long)(t2->tv_sec - t1->tv_sec) * 1000L
+ (t2->tv_nsec - t1->tv_nsec) / 1000000L;
}
int main()
{
const long period_milli = 500;
struct timespec ts_last;
struct timespec ts_next;
const struct timespec ts_sleep = { 0, 1000000L };
clock_gettime( CLOCK_REALTIME, &ts_last );
while( 1 )
{
nanosleep( &ts_sleep, NULL );
clock_gettime( CLOCK_REALTIME, &ts_next );
long elapsed = elapsed_milli( &ts_last, &ts_next );
if( elapsed >= period_milli )
{
printf( "Elapsed : %ld\n", elapsed );
ts_last.tv_nsec += period_milli * 1000000L;
if( ts_last.tv_nsec >= 1000000000L )
{
ts_last.tv_nsec -= 1000000000L;
ts_last.tv_sec++;
}
}
}
return 0;
}
Every time the required period has elapsed, the "previous" time is updated to use the expected time at which that period elapsed, rather than the actual time. This example uses a 1ms sleep between each poll, which might be over the top.

how to solve this linux Timer error

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <time.h>
#define BILLION 1000000000L;
int main( int argc, char** argv )
{
struct timespec start, stop;
double accum;
uint32 StartTime, StopTime;
if( StartTime = clock_gettime( CLOCK_REALTIME, &start) == -1 ) {
perror( "clock gettime" );
return EXIT_FAILURE;
}
StartTime = start.tv_sec + 0.0000000001 * start.tv_nsec;
system( argv[1] ); // or it could be any calculation
if( StopTime = clock_gettime( CLOCK_REALTIME, &stop) == -1 ) {
perror( "clock gettime" );
return EXIT_FAILURE;
}
StopTime = stop.tv_sec + 0.0000000001 * stop.tv_nsec;
accum = StopTime - StartTime;
printf( "%lf\n", accum );
return EXIT_SUCCESS;
}
This program calculates the time required to
execute the program specified as its first argument.
The time is printed in seconds, on standard out.
I am calculating the start time and stop time to perform some computaion. I am able to get the start time and stop time for the computation but not able to find the difference between the start ans stop time i.e. accum. could anyone help me in this ?
Remove StartTime and StopTime. Declare this function :
double to_double(struct timespec t) {
return t.tv_sec + 0.0000000001 * t.tv_nsec;
}
And you'll get your deltatime this way :
accum = to_double(stop) - to_double(start);
The problem is that StartTime and StopTime are both defined as integer types. The results of your calculations are not whole numbers but because the left hand side of the expressions are integers the results are getting truncated down to the integer part. Essentially, you are loosing the details provided by the tv_nsec field.
As suggested in the comments, declare StartTime and StopTime as doubles to fix that.
Change
uint32 StartTime, StopTime;
to
double StartTime, StopTime;

Resources