tags:

views:

401

answers:

5

Hi,

EDIT: Thanks for the answers so far, at least I can compile it now, but I still get a segmentation error.

For compilation I use the following line:

gcc -g -O0 -I../include -L../ test.c -static -lrt

Source Code is as follows:

#include <sys/time.h>
#include <time.h>
#include <stdio.h>


struct timespec *diff(struct timespec *start, struct timespec *end);

int main()
{
struct timespec time1, time2;
    int i;
int temp = 0;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
for (i = 0; i< 242000000; i++)
    temp+=temp;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);
    printf("sec: %d, nsec: %f",diff(&time1,&time2)->tv_sec,    diff(&time1,&time2)->tv_nsec);
//cout<<diff(time1,time2).tv_sec<<":"<<diff(time1,time2).tv_nsec<<endl;
return 0;
}

struct timespec *diff(struct timespec *start, struct timespec *end)
{
struct timespec *temp;
if ((end->tv_nsec-start->tv_nsec)<0) {
    temp->tv_sec = end->tv_sec-start->tv_sec-1;
    temp->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec;
} else {
    temp->tv_sec = end->tv_sec-start->tv_sec;
    temp->tv_nsec = end->tv_nsec-start->tv_nsec;
}
return temp;
}

I get now the following warning:

test.c: In function ‘main’: test.c:17: warning: format ‘%d’ expects type ‘int’, but argument 2 has type ‘__time_t’ test.c:17: warning: format ‘%f’ expects type ‘double’, but argument 3 has type ‘long int’

Segmentation fault is surely caused by my handling of the structures. It is quite a while ago that i last had to deal with C....

Many thanks, Marcus

+1  A: 

Your diff function's signature is timespec diff(timespec start, timespec end), where it should be struct timespec diff(struct timespec start, struct timespec end).


EDIT Your diff function is assigning to an uninitialized struct pointer, you might want to change it to something like the following.

void diff(struct timespec *start, struct timespec *end,
    struct timespec *result);

int main()
{
    struct timespec time1, time2, result;
    int i;
    int temp = 0;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time1);
    for (i = 0; i< 242000000; i++)
        temp+=temp;
    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &time2);

    diff(&time1, &time2, &result);

    printf("sec: %ld, nsec: %ld", (long int)result.tv_sec,
        (long int)result.tv_nsec);
    return 0;
}

void diff(struct timespec *start, struct timespec *end,
    struct timespec * result)
{
    if ((end->tv_nsec-start->tv_nsec)<0) {
        result->tv_sec = end->tv_sec-start->tv_sec-1;
        result->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec;
    } else {
        result->tv_sec = end->tv_sec-start->tv_sec;
        result->tv_nsec = end->tv_nsec-start->tv_nsec;
    }
}
Hasturkun
Thanks, it compiles now at least. The only problem that is left is that the output value is 0 seconds and 0.00000 nanoseconds. THere is definitely something wrong still...
Marcus
@Marcus: Make sure your printf is correct -- if you use %f instead of %ld you'll get the 0.0000 instead of the correct value
Chris Dodd
A: 

You have to add the struct keyword before the timespec's. E.g.

struct timespec diff(struct timespec start, struct timespec end);
Makis
A: 

You are compiling it as C (gcc and .c extension), but looks like you are coding in C++ (where struct could be committed when declaring variables).

Also, in C we usually don't pass structures by value.

Another hint is to always compile with high warning level, at least -Wall -pedantic, to catch problems early.

Nikolai N Fetissov
A: 

I think you want diff() to return either a dynamically or statically allocated pointer.

Try (suggestions in comments):

struct timespec *diff(struct timespec *start, struct timespec *end)
{
struct timespec *temp;

/* allocate temp to be sizeof(struct timespec) and zero it out */
temp = malloc(sizeof(struct timespec));
/* Of course, deal with malloc (or calloc) failing */
memset(tmp, 0, sizeof(struct timespec));

if ((end->tv_nsec-start->tv_nsec)<0) {
    temp->tv_sec = end->tv_sec-start->tv_sec-1;
    temp->tv_nsec = 1000000000+end->tv_nsec-start->tv_nsec;
} else {
    temp->tv_sec = end->tv_sec-start->tv_sec;
    temp->tv_nsec = end->tv_nsec-start->tv_nsec;
}
return temp;
/* Make sure caller frees the returned pointer */
}

If dynamic allocation is taboo, then:

static struct timespec temp;
/*zero it out, watch concurrency too! */

....

temp.tv_sec = end->tv_sec-start->tv_sec;
/* Make sure caller does NOT free (or modify) the pointer */
return temp;

You need to return a pointer there (however allocated) that can actually be reached by the caller. Or, make *temp global.

Tim Post
+1  A: 

Depending on your needs, you might just want to generate the elapsed time like this:

double t_ns = (double)(end.tv_sec - start.tv_sec) * 1.0e9 + (double)(end.tv_nsec - start.tv_nsec); // get elapsed time in ns

Also, FWIW, I use CLOCK_PROCESS_CPUTIME_ID - it seems to give better accuracy and resolution on the various Linux-based systems that I've tried it on:

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &start);

// ... stuff ... //

clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &end);

Paul R