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 |
|