]> mj.ucw.cz Git - eval.git/blob - lib/profile.c
Handle exit code translation failures gracefully.
[eval.git] / lib / profile.c
1 /*
2  *      UCW Library -- Poor Man's Profiler
3  *
4  *      (c) 2001 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "lib/lib.h"
11 #include "lib/profile.h"
12
13 #include <stdio.h>
14
15 /* PROFILE_TOD */
16
17 #include <sys/time.h>
18
19 void
20 prof_tod_init(struct prof_tod *c)
21 {
22   c->sec = c->usec = 0;
23 }
24
25 void
26 prof_tod_switch(struct prof_tod *o, struct prof_tod *n)
27 {
28   struct timeval tv;
29   gettimeofday(&tv, NULL);
30   if (n)
31     {
32       n->start_sec = tv.tv_sec;
33       n->start_usec = tv.tv_usec;
34     }
35   if (o)
36     {
37       o->sec += tv.tv_sec - o->start_sec;
38       o->usec += tv.tv_usec - o->start_usec;
39       if (o->usec < 0)
40         {
41           o->usec += 1000000;
42           o->sec--;
43         }
44       else while (o->usec >= 1000000)
45         {
46           o->usec -= 1000000;
47           o->sec++;
48         }
49     }
50 }
51
52 int
53 prof_tod_format(char *buf, struct prof_tod *c)
54 {
55   return sprintf(buf, "%d.%06d", c->sec, c->usec);
56 }
57
58 /* PROFILE_TSC */
59
60 #ifdef CPU_I386
61
62 void
63 prof_tsc_init(struct prof_tsc *c)
64 {
65   c->ticks = 0;
66 }
67
68 int
69 prof_tsc_format(char *buf, struct prof_tsc *c)
70 {
71   return sprintf(buf, "%lld", c->ticks);
72 }
73
74 #endif
75
76 /* PROFILE_KTSC */
77
78 #ifdef CONFIG_LINUX
79
80 #include <fcntl.h>
81 #include <unistd.h>
82 static int self_prof_fd = -1;
83
84 void
85 prof_ktsc_init(struct prof_ktsc *c)
86 {
87   if (self_prof_fd < 0)
88     {
89       self_prof_fd = open("/proc/self/profile", O_RDONLY, 0);
90       if (self_prof_fd < 0)
91         die("Unable to open /proc/self/profile: %m");
92     }
93   c->ticks_user = 0;
94   c->ticks_sys = 0;
95 }
96
97 void
98 prof_ktsc_switch(struct prof_ktsc *o, struct prof_ktsc *n)
99 {
100   unsigned long long u, s;
101   byte buf[256];
102
103   int l = pread(self_prof_fd, buf, sizeof(buf)-1, 0);
104   ASSERT(l > 0 && l < (int)sizeof(buf)-1);
105   buf[l] = 0;
106   l = sscanf(buf, "%lld%lld", &u, &s);
107   ASSERT(l == 2);
108
109   if (n)
110     {
111       n->start_user = u;
112       n->start_sys = s;
113     }
114   if (o)
115     {
116       u -= o->start_user;
117       o->ticks_user += u;
118       s -= o->start_sys;
119       o->ticks_sys += s;
120     }
121 }
122
123 int
124 prof_ktsc_format(char *buf, struct prof_ktsc *c)
125 {
126   return sprintf(buf, "%lld+%lld", (long long) c->ticks_user, (long long) c->ticks_sys);
127 }
128
129 #endif