root / drivers / profile.h @ abdb293f
History | View | Annotate | Download (3.3 kB)
1 |
/* Copyright (c) 2007, XenSource Inc.
|
---|---|
2 |
* All rights reserved.
|
3 |
*/
|
4 |
|
5 |
#ifndef __TAP_PROFILE_H__
|
6 |
#define __TAP_PROFILE_H__
|
7 |
|
8 |
#ifndef _GNU_SOURCE
|
9 |
#define _GNU_SOURCE
|
10 |
#endif
|
11 |
|
12 |
#include <stdio.h> |
13 |
#include <stdlib.h> |
14 |
#include <unistd.h> |
15 |
#include <string.h> |
16 |
#include <syslog.h> |
17 |
#include <sys/time.h> |
18 |
#include <time.h> |
19 |
#include <fcntl.h> |
20 |
#include <inttypes.h> |
21 |
|
22 |
//#define PROFILING
|
23 |
//#define LOGGING
|
24 |
|
25 |
#define TAPPROF_IN 1 |
26 |
#define TAPPROF_OUT 2 |
27 |
|
28 |
struct profile_times {
|
29 |
char *fn_name;
|
30 |
uint64_t in, out_sum, cnt; |
31 |
}; |
32 |
|
33 |
struct profile_info {
|
34 |
FILE *log; |
35 |
int size;
|
36 |
char *name;
|
37 |
unsigned long long seq; |
38 |
struct profile_times *pt;
|
39 |
}; |
40 |
|
41 |
#ifdef PROFILING
|
42 |
|
43 |
static inline void |
44 |
tp_open(struct profile_info *prof, char *tap_name, char *log_name, int size) |
45 |
{ |
46 |
memset(prof, 0, sizeof(struct profile_info)); |
47 |
#ifdef LOGGING
|
48 |
prof->log = fopen(log_name, "w");
|
49 |
#endif
|
50 |
prof->size = size; |
51 |
prof->name = strdup(tap_name); |
52 |
prof->pt = malloc(sizeof(struct profile_times) * prof->size); |
53 |
if (prof->pt)
|
54 |
memset(prof->pt, 0, sizeof(struct profile_times) * prof->size); |
55 |
} |
56 |
|
57 |
static inline void |
58 |
tp_close(struct profile_info *prof)
|
59 |
{ |
60 |
int i;
|
61 |
struct profile_times *pt;
|
62 |
|
63 |
for (i = 0; i < prof->size; i++) { |
64 |
pt = &prof->pt[i]; |
65 |
if (pt->fn_name) {
|
66 |
syslog(LOG_DEBUG, "%s: %s: cnt: %llu, avg time: %llu\n",
|
67 |
prof->name, pt->fn_name, pt->cnt, |
68 |
((pt->cnt) ? (pt->out_sum / pt->cnt) : 0));
|
69 |
free(pt->fn_name); |
70 |
} |
71 |
} |
72 |
|
73 |
#ifdef LOGGING
|
74 |
if (prof->log)
|
75 |
fclose(prof->log); |
76 |
#endif
|
77 |
free(prof->name); |
78 |
if (prof->pt)
|
79 |
free(prof->pt); |
80 |
} |
81 |
|
82 |
static inline u64 |
83 |
tp_get_id(struct profile_info *prof)
|
84 |
{ |
85 |
return prof->seq++;
|
86 |
} |
87 |
|
88 |
static inline int |
89 |
tp_fn_id(struct profile_info *prof, const char *name) |
90 |
{ |
91 |
int i;
|
92 |
struct profile_times *pt;
|
93 |
|
94 |
for (i = 0; i < prof->size; i++) { |
95 |
pt = &prof->pt[i]; |
96 |
if (!pt->fn_name)
|
97 |
return i;
|
98 |
if (!strcmp(pt->fn_name, name))
|
99 |
return i;
|
100 |
} |
101 |
|
102 |
return prof->size - 1; |
103 |
} |
104 |
|
105 |
static inline void |
106 |
__tp_in(struct profile_info *prof, const char *func) |
107 |
{ |
108 |
long long _time; |
109 |
int idx = tp_fn_id(prof, func);
|
110 |
struct profile_times *pt = &prof->pt[idx];
|
111 |
|
112 |
if (!pt->fn_name)
|
113 |
pt->fn_name = strdup(func); |
114 |
|
115 |
asm volatile(".byte 0x0f, 0x31" : "=A" (_time)); |
116 |
pt->in = _time; |
117 |
} |
118 |
|
119 |
#define tp_in(prof) __tp_in(prof, __func__)
|
120 |
|
121 |
static inline void |
122 |
__tp_out(struct profile_info *prof, const char *func) |
123 |
{ |
124 |
long long _time; |
125 |
int idx = tp_fn_id(prof, func);
|
126 |
struct profile_times *pt = &prof->pt[idx];
|
127 |
|
128 |
if (!pt->fn_name || !pt->in)
|
129 |
return;
|
130 |
|
131 |
asm volatile(".byte 0x0f, 0x31" : "=A" (_time)); |
132 |
pt->cnt++; |
133 |
pt->out_sum += (_time - pt->in); |
134 |
pt->in = 0;
|
135 |
} |
136 |
|
137 |
#define tp_out(prof) __tp_out(prof, __func__)
|
138 |
|
139 |
static inline void |
140 |
__tp_log(struct profile_info *prof, u64 id, const char *func, int direction) |
141 |
{ |
142 |
long long _time; |
143 |
asm volatile(".byte 0x0f, 0x31" : "=A" (_time)); |
144 |
|
145 |
if (direction == TAPPROF_IN)
|
146 |
__tp_in(prof, func); |
147 |
else
|
148 |
__tp_out(prof, func); |
149 |
|
150 |
#ifdef LOGGING
|
151 |
if (prof->log)
|
152 |
fprintf(prof->log, "%s: %s: %llu, %lld\n", func,
|
153 |
((direction == TAPPROF_IN) ? "in" : "out"), id, _time); |
154 |
#endif
|
155 |
} |
156 |
|
157 |
#define tp_log(prof, id, direction) __tp_log(prof, id, __func__, direction)
|
158 |
|
159 |
#else
|
160 |
#define tp_open(prof, tname, lname, size) ((void)0) |
161 |
#define tp_close(prof) ((void)0) |
162 |
#define tp_in(prof) ((void)0) |
163 |
#define tp_out(prof) ((void)0) |
164 |
#define tp_log(prof, sec, direction) ((void)0) |
165 |
#endif
|
166 |
|
167 |
#endif
|