1 /*
2 * Copyright (c) 2017, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18 /** \file
19 * \brief Fill in statistics structure (Linux version)
20 */
21
22 #include <sys/time.h>
23 #include <sys/resource.h>
24 #include <sys/utsname.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include "timeBlk.h"
28 #include "fioMacros.h"
29
30 union ieee {
31 double d;
32 int i[2];
33 };
34
35 extern void *__fort_sbrk(int);
36
37 /* these little routines had to go somewhere, so here they are. */
38
39 void
__fort_setarg(void)40 __fort_setarg(void)
41 {
42 }
43
nodename(s)44 static void nodename(s) char *s;
45 {
46 struct utsname u0;
47
48 uname(&u0);
49 strcpy(s, u0.nodename);
50 }
51
__fort_gettb(t)52 void __fort_gettb(t) struct tb *t;
53 {
54 struct timeval tv0;
55 struct timezone tz0;
56 struct rusage rs0, rc0;
57
58 /* Use an approximation here to avoid using inexact arithmetic */
59 unsigned long long tapprox;
60 union ieee v;
61
62 gettimeofday(&tv0, &tz0);
63 getrusage(RUSAGE_SELF, &rs0);
64 getrusage(RUSAGE_CHILDREN, &rc0);
65 v.i[0] = 0;
66 v.i[1] = 0x3d700000; /* 2 ** -40 */
67 tapprox = (unsigned long long)tv0.tv_usec; /* around 2**30 */
68 tapprox = tapprox * 1099512UL; /* mpy by a 21 bit value */
69 tapprox &= 0xfffffffffffc0000ULL; /* Lop off enough to be exact */
70 t->r = (double)tv0.tv_sec + v.d * (double)tapprox;
71 /* printf("BDL %d %d %22.15le\n",tv0.tv_sec,tv0.tv_usec,t->r); */
72
73 tapprox = rs0.ru_utime.tv_usec;
74 tapprox = tapprox * 1099512UL;
75 tapprox &= 0xfffffffffffc0000ULL;
76 t->u = (double)rs0.ru_utime.tv_sec + v.d * (double)tapprox;
77
78 tapprox = rs0.ru_stime.tv_usec;
79 tapprox = tapprox * 1099512UL;
80 tapprox &= 0xfffffffffffc0000ULL;
81 t->s = (double)rs0.ru_stime.tv_sec + v.d * (double)tapprox;
82
83 tapprox = rc0.ru_utime.tv_usec;
84 tapprox = tapprox * 1099512UL;
85 tapprox &= 0xfffffffffffc0000ULL;
86 t->u += (double)rc0.ru_utime.tv_sec + v.d * (double)tapprox;
87
88 tapprox = rc0.ru_stime.tv_usec;
89 tapprox = tapprox * 1099512UL;
90 tapprox &= 0xfffffffffffc0000ULL;
91 t->s += (double)rc0.ru_stime.tv_sec + v.d * (double)tapprox;
92 t->maxrss = rs0.ru_maxrss;
93 t->minflt = rs0.ru_minflt;
94 t->majflt = rs0.ru_majflt;
95 t->nsignals = rs0.ru_nsignals;
96 t->nvcsw = rs0.ru_nvcsw;
97 t->nivcsw = rs0.ru_nivcsw;
98 t->sbrk = (double)((long)sbrk(0));
99 t->gsbrk = (GET_DIST_HEAPZ == 0 ? 0.0 : (double)((long)__fort_sbrk(0)));
100 nodename(t->host);
101 }
102
103 static double first = 0.0;
104
105 double
__fort_second()106 __fort_second()
107 {
108 struct timeval v;
109 struct timezone t;
110 double d;
111 int s;
112
113 s = gettimeofday(&v, &t);
114 if (s == -1) {
115 __fort_abortp("gettimeofday");
116 }
117 d = (double)v.tv_sec + (double)v.tv_usec / 1000000;
118 if (first == 0.0) {
119 first = d;
120 }
121 return (d - first);
122 }
123
124 void
__fort_set_second(double d)125 __fort_set_second(double d)
126 {
127 first = d;
128 }
129