Statistics
| Branch: | Tag: | Revision:

root / xseg / peers / user / timer.c @ 0ef9c7ee

History | View | Annotate | Download (4.7 kB)

1
/*
2
 * Copyright 2012 GRNET S.A. All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or
5
 * without modification, are permitted provided that the following
6
 * conditions are met:
7
 *
8
 *   1. Redistributions of source code must retain the above
9
 *      copyright notice, this list of conditions and the following
10
 *      disclaimer.
11
 *   2. Redistributions in binary form must reproduce the above
12
 *      copyright notice, this list of conditions and the following
13
 *      disclaimer in the documentation and/or other materials
14
 *      provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
 * POSSIBILITY OF SUCH DAMAGE.
28
 *
29
 * The views and conclusions contained in the software and
30
 * documentation are those of the authors and should not be
31
 * interpreted as representing official policies, either expressed
32
 * or implied, of GRNET S.A.
33
 */
34

    
35
#include <stdio.h>
36
#include <stdlib.h>
37
#include <unistd.h>
38
#include <sys/syscall.h>
39
#include <sys/types.h>
40
#include <pthread.h>
41
#include <xseg/xseg.h>
42
#include <peer.h>
43
#include <time.h>
44
#include <sys/util.h>
45
#include <signal.h>
46
#include <bench-xseg.h>
47
#include <limits.h>
48

    
49
#define SEC 1000000000 //1sec = 10^9 nsec
50
#define SEC2 (uint64_t) SEC*SEC //1sec*1sec = 10^18 nsec^2
51

    
52
int init_timer(struct timer **tm, int insanity)
53
{
54
        *tm = malloc(sizeof(struct timer));
55
        if (!*tm) {
56
                perror("malloc");
57
                return -1;
58
        }
59

    
60
        memset(*tm, 0, sizeof(struct timer));
61
        (*tm)->insanity = insanity;
62
        return 0;
63
}
64

    
65
void timer_start(struct timer *timer)
66
{
67
        //We need a low-latency way to get current time in nanoseconds.
68
        //Is this way the best way?
69
        //RAW means that we trust the system's oscilator isn't screwed up
70
        clock_gettime(CLOCK_MONOTONIC_RAW, &timer->start_time);
71
}
72

    
73
void timer_stop(struct timer *timer, struct timespec *start)
74
{
75
        struct timespec end_time;
76
        volatile struct timespec elapsed_time;
77
        struct timespec2 elapsed_time_sq;
78
        struct timespec start_time;
79

    
80
        /*
81
         * There are timers such as rec_tm whose start_time cannot be trusted and
82
         * the submission time is stored in other structs (e.g. struct
83
         * peer_request).
84
         * In this case, the submission time must be passed explicitly to this
85
         * function using the "start" argument.
86
         */
87
        if (!start)
88
                start_time = timer->start_time;
89
        else
90
                start_time = *start;
91

    
92
        clock_gettime(CLOCK_MONOTONIC_RAW, &end_time);
93

    
94
        //Get elapsed time by subtracting start time from end time.
95
        //Subtraction can result to a negative value, so we check for both cases
96
        if (start_time.tv_nsec > end_time.tv_nsec) {
97
                elapsed_time.tv_nsec = SEC - start_time.tv_nsec + end_time.tv_nsec;
98
                elapsed_time.tv_sec = end_time.tv_sec - start_time.tv_sec - 1;
99
        } else {
100
                elapsed_time.tv_nsec = end_time.tv_nsec - start_time.tv_nsec;
101
                elapsed_time.tv_sec = end_time.tv_sec - start_time.tv_sec;
102
        }
103

    
104
        //Add the elapsed time to the current sum for this timer.
105
        //For accuracy, nanoseconds' sum has to be always less that 10^9
106
        if (elapsed_time.tv_nsec + timer->sum.tv_nsec > SEC){
107
                timer->sum.tv_nsec += elapsed_time.tv_nsec;
108
                timer->sum.tv_sec += elapsed_time.tv_sec + 1;
109
        } else {
110
                timer->sum.tv_nsec += elapsed_time.tv_nsec;
111
                timer->sum.tv_sec += elapsed_time.tv_sec;
112
        }
113

    
114
        //Add elapsed_time^2 to the current sum of squares for this timer
115
        //This is needed to calculate standard deviation.
116
        //As above, the sum of square of nanoseconds has to be less than 10^18
117
        elapsed_time_sq.tv_sec2 = elapsed_time.tv_sec*elapsed_time.tv_sec;
118
        elapsed_time_sq.tv_nsec2 = elapsed_time.tv_nsec*elapsed_time.tv_nsec;
119
        if (elapsed_time_sq.tv_nsec2 + timer->sum_sq.tv_nsec2 > SEC2) {
120
                timer->sum_sq.tv_nsec2 =
121
                        (timer->sum_sq.tv_nsec2 + elapsed_time_sq.tv_nsec2) % SEC2;
122
                timer->sum_sq.tv_sec2 += elapsed_time_sq.tv_sec2 + 1;
123
        } else {
124
                timer->sum_sq.tv_nsec2 += elapsed_time_sq.tv_nsec2;
125
                timer->sum_sq.tv_sec2 += elapsed_time_sq.tv_sec2;
126
        }
127

    
128
        //TODO: check if we need to make it volatile
129
        timer->completed++;
130

    
131
        /*
132
        printf("Start: %lu s %lu ns\n", start_time.tv_sec, start_time.tv_nsec);
133
        printf("Elpsd: %lu s %lu ns\n", elapsed_time.tv_sec, elapsed_time.tv_nsec);
134
        printf("End:   %lu s %lu ns\n", end_time.tv_sec, end_time.tv_nsec);
135
        */
136
}
137

    
138

    
139

    
140