Import TBBT (NFS trace replay).
[bluesky.git] / TBBT / trace_play / profile.c
1 /*
2  * profile.c
3  *
4  * $Id: profile.c,v 1.1 2002/08/21 22:08:01 ningning Exp $
5  * Changes:
6  *      $Log: profile.c,v $
7  *      Revision 1.1  2002/08/21 22:08:01  ningning
8  *      *** empty log message ***
9  *      
10  */
11
12 #include <sys/time.h>
13 #include <sys/sem.h>
14 #include <unistd.h>
15 #include <stdio.h>
16 #include "profile.h"
17 #include "rfs_assert.h"
18 //#include "rfs_c_def.h"
19 extern FILE * profile_fp;
20
21 static struct timezone tz;
22 inline void calculate_interval 
23         (struct timeval * ts, struct timeval * te, struct timeval * interval)
24 {
25         if (te->tv_usec < ts->tv_usec) {
26                 if (te->tv_sec <= ts->tv_sec) {
27                         printf ("te->tv_sec %d ts->tv_sec %d\n", te->tv_sec, ts->tv_sec);
28                         printf ("te->tv_usec %d ts->tv_usec %d\n", te->tv_usec, ts->tv_usec);
29                 }
30                 RFS_ASSERT (te->tv_sec > ts->tv_sec);
31                 te->tv_usec += 1000000;
32                 te->tv_sec -= 1;
33         }
34
35         interval->tv_sec  = te->tv_sec - ts->tv_sec;
36         interval->tv_usec = te->tv_usec - ts->tv_usec;
37         if (interval->tv_usec > 1000000) {
38                 if (interval->tv_usec > 2000000) {
39                         printf ("interval->tv_sec %d interval->tv_usec %d \n", interval->tv_sec, interval->tv_usec);
40                         printf ("ts->tv_sec %d ts->tv_usec %d \n", ts->tv_sec, ts->tv_usec);
41                         printf ("te->tv_sec %d te->tv_usec %d \n", te->tv_sec, te->tv_usec);
42                 }
43                 /* Sometimes it can happend that te->tv_usec > 1000000 */
44                 interval->tv_sec += 1;
45                 interval->tv_usec -= 1000000;
46                 RFS_ASSERT (interval->tv_usec < 1000000);
47         }
48 }
49
50 inline void normalize_profile (int pos, struct timeval * time)
51 {
52         if (!(time->tv_sec >=0 && time->tv_usec >=0 && time->tv_usec < 2000000)) {
53                 printf ("pos %d tv_sec %d tv_usec %d\n", pos, time->tv_sec, time->tv_usec);
54         };
55         RFS_ASSERT (time->tv_sec >=0 && time->tv_usec >=0 && time->tv_usec < 2000000);
56         while (time->tv_usec >= 1000000) {
57                 time->tv_usec -= 1000000;
58                 time->tv_sec += 1;
59         }
60 }
61
62 inline void start_real_profile (profile_t * profile)
63 {
64         start_profile(profile);
65 }
66
67 inline void end_real_profile (profile_t * profile)
68 {
69         end_profile(profile);
70 }
71
72 inline void start_profile (profile_t * profile)
73 {
74 /*
75         if (strlen(profile->about) < 3) {
76                 printf ("total_profile address: %x %x\n", &total_profile, profile);
77         }
78 */
79
80         gettimeofday(&(profile->ts), &tz);
81         normalize_profile (1, &(profile->ts));
82 }
83
84 inline void end_profile (profile_t * profile)
85 {
86         struct timeval te, teorg;
87         struct timeval * ts; 
88         struct timeval * in;
89         struct timeval oldin;
90         
91 /*
92         //printf ("end_profile %s\n", profile->about);
93
94         if (strlen(profile->about) < 3) {
95                 printf ("total_profile address: %x %x\n", &total_profile, profile);
96         }
97 */
98
99         oldin = profile->in;
100         in = &(profile->in);
101         ts = &(profile->ts);
102
103         gettimeofday(&te, &tz);
104         normalize_profile (2, &te);
105         teorg = te;
106
107         RFS_ASSERT (te.tv_sec >= ts->tv_sec);
108         RFS_ASSERT (te.tv_usec >=0 && ts->tv_usec >=0);
109         while (te.tv_usec < ts->tv_usec) {
110                 if (te.tv_sec <= ts->tv_sec) {
111                         printf ("%s ts.tv_sec %d ts.tv_usec %d\n", profile->about, ts->tv_sec, ts->tv_usec);
112                         printf ("teorg.tv_sec %d teorg.tv_usec %d\n", teorg.tv_sec, teorg.tv_usec);
113                 }
114                 RFS_ASSERT (te.tv_sec > ts->tv_sec);
115                 te.tv_usec += 1000000;
116                 te.tv_sec -= 1;
117         }
118
119         if (!(in->tv_sec >=0 && in->tv_usec >=0)) {
120                 printf ("in->tv_sec %d, in->tv_usec %d\n", in->tv_sec, in->tv_usec);
121         };
122         RFS_ASSERT (in->tv_sec >=0 && in->tv_usec >=0);
123         in->tv_sec  += te.tv_sec - ts->tv_sec;
124         in->tv_usec += te.tv_usec - ts->tv_usec;
125         normalize_profile (3, in);
126
127         if (!(in->tv_sec >=0 && in->tv_sec <864000)) {
128                  printf (" ts.tv_sec %d ts.tv_usec %d\n", ts->tv_sec, ts->tv_usec);
129                  printf (" te.tv_sec %d te.tv_usec %d\n", te.tv_sec, te.tv_usec);
130                  printf (" in.tv_sec %d in.tv_usec %d\n", in->tv_sec, in->tv_usec);
131                  printf (" oldin.tv_sec %d oldin.tv_usec %d\n", oldin.tv_sec, oldin.tv_usec);
132         }
133
134         profile->num ++;
135         profile->ts = teorg;
136 }
137
138 inline void init_profile (char * string, profile_t * profile)
139 {
140         RFS_ASSERT (strlen(string) < sizeof (profile->about));
141         memset (profile, 0, sizeof(profile_t));
142         strcpy (profile->about, string);
143 }
144
145 inline int calculate_avg_timeval (struct timeval * in, int num)
146 {
147         unsigned long long i;
148         int ret;
149
150         if (in->tv_sec < 2000) {
151                 return ((in->tv_sec*1000000+in->tv_usec)/num );
152         } else {
153                 i = ((unsigned long long)in->tv_sec)*1000000 + in->tv_usec;
154                 i/= num;
155                 RFS_ASSERT (i<2000000000);
156                 ret = i;
157                 return ret;
158         }
159 }
160
161 inline void print_profile (char * string, profile_t * profile)
162 {
163         struct timeval * ts = &(profile->ts);
164         struct timeval * in = &(profile->in);
165
166 /*
167         if (strcmp (string, profile->about)) {
168                 printf ("print_profile string %s about %s\n", string, profile->about);
169         }
170 */
171
172         //RFS_ASSERT (!strcmp (string, profile->about));
173         if (in->tv_usec<0 || in->tv_usec>1000000) {
174                 printf ("%s in->tv_usec %d, in->tv_sec %d num %d\n", profile->about, in->tv_usec, in->tv_sec, profile->num);
175         }
176
177         RFS_ASSERT (in->tv_usec>=0 && in->tv_usec<1000000);
178         
179         if (!(in->tv_sec >=0 && in->tv_sec <864000)) {
180                  printf ("%s ts.tv_sec %d ts.tv_usec %d\n", profile->about, ts->tv_sec, ts->tv_usec);
181                  printf ("%s in.tv_sec %d in.tv_usec %d\n", profile->about, in->tv_sec, in->tv_usec);
182         }
183         RFS_ASSERT (in->tv_sec >=0 && in->tv_sec <864000);      /* it's about 10 days */
184
185         if (profile->num == 0) {
186                 printf("... %40s %3d.%06d num %d \n", profile->about, in->tv_sec, in->tv_usec, 
187                         profile->num);
188
189                 if (profile_fp) {
190                         fprintf(profile_fp, "... %40s %3d.%06d num %d \n", profile->about, in->tv_sec,
191                                 in->tv_usec, profile->num );
192                         //perror("print_profile_1");
193                 }
194         } else {
195
196                 int avg = calculate_avg_timeval (in, profile->num);
197                 printf("... %40s %3d.%06d num %d avg %d \n", profile->about, in->tv_sec, in->tv_usec, 
198                         profile->num, avg);
199
200                 if (profile_fp) {
201                         fprintf(profile_fp, "... %40s %3d.%06d num %d avg %d \n", profile->about, in->tv_sec,
202                                 in->tv_usec, profile->num, avg);
203                 }
204
205 /*
206                 printf("... %40s %3d.%06d num %d avg %d \n", string, in->tv_sec, in->tv_usec, 
207                         profile->num, (in->tv_sec*1000000+in->tv_usec)/profile->num );
208
209                 if (profile_fp) {
210                         fprintf(profile_fp, "... %40s %3d.%06d num %d avg %d \n", string, in->tv_sec,
211                                 in->tv_usec, profile->num, (in->tv_sec*1000000+in->tv_usec)/profile->num );
212                 }
213 */
214         }
215 }