blob: 805d1f52c5b48034772a6f1c44cb29776e82e886 [file] [log] [blame]
Joerg Roedel1aed2672012-01-04 17:54:20 +01001#include "../perf.h"
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -02002#include "util.h"
Frederic Weisbecker69e3f522010-01-16 14:21:15 +01003#include <sys/mman.h>
Namhyung Kim4e34d952012-10-02 01:32:51 +09004#ifdef BACKTRACE_SUPPORT
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -03005#include <execinfo.h>
Irina Tirdeac9f08be2012-09-08 03:43:23 +03006#endif
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -03007#include <stdio.h>
8#include <stdlib.h>
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -02009
Joerg Roedel1aed2672012-01-04 17:54:20 +010010/*
11 * XXX We need to find a better place for these things...
12 */
Arnaldo Carvalho de Melo0c1fe6b2012-10-06 14:57:10 -030013unsigned int page_size;
14
Arnaldo Carvalho de Melo0c6332e2012-12-13 16:43:04 -030015bool test_attr__enabled;
16
Joerg Roedel1aed2672012-01-04 17:54:20 +010017bool perf_host = true;
Joerg Roedelc4a7dca2012-02-10 18:05:05 +010018bool perf_guest = false;
Joerg Roedel1aed2672012-01-04 17:54:20 +010019
20void event_attr_init(struct perf_event_attr *attr)
21{
22 if (!perf_host)
23 attr->exclude_host = 1;
24 if (!perf_guest)
25 attr->exclude_guest = 1;
Stephane Eranian7e1ccd32012-02-09 16:12:38 +010026 /* to capture ABI version */
27 attr->size = sizeof(*attr);
Joerg Roedel1aed2672012-01-04 17:54:20 +010028}
29
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020030int mkdir_p(char *path, mode_t mode)
31{
32 struct stat st;
33 int err;
34 char *d = path;
35
36 if (*d != '/')
37 return -1;
38
39 if (stat(path, &st) == 0)
40 return 0;
41
42 while (*++d == '/');
43
44 while ((d = strchr(d, '/'))) {
45 *d = '\0';
46 err = stat(path, &st) && mkdir(path, mode);
47 *d++ = '/';
48 if (err)
49 return -1;
50 while (*d == '/')
51 ++d;
52 }
53 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
54}
55
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -020056static int slow_copyfile(const char *from, const char *to)
57{
58 int err = 0;
59 char *line = NULL;
60 size_t n;
61 FILE *from_fp = fopen(from, "r"), *to_fp;
62
63 if (from_fp == NULL)
64 goto out;
65
66 to_fp = fopen(to, "w");
67 if (to_fp == NULL)
68 goto out_fclose_from;
69
70 while (getline(&line, &n, from_fp) > 0)
71 if (fputs(line, to_fp) == EOF)
72 goto out_fclose_to;
73 err = 0;
74out_fclose_to:
75 fclose(to_fp);
76 free(line);
77out_fclose_from:
78 fclose(from_fp);
79out:
80 return err;
81}
82
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020083int copyfile(const char *from, const char *to)
84{
85 int fromfd, tofd;
86 struct stat st;
87 void *addr;
88 int err = -1;
89
90 if (stat(from, &st))
91 goto out;
92
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -020093 if (st.st_size == 0) /* /proc? do it slowly... */
94 return slow_copyfile(from, to);
95
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020096 fromfd = open(from, O_RDONLY);
97 if (fromfd < 0)
98 goto out;
99
100 tofd = creat(to, 0755);
101 if (tofd < 0)
102 goto out_close_from;
103
104 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0);
105 if (addr == MAP_FAILED)
106 goto out_close_to;
107
108 if (write(tofd, addr, st.st_size) == st.st_size)
109 err = 0;
110
111 munmap(addr, st.st_size);
112out_close_to:
113 close(tofd);
114 if (err)
115 unlink(to);
116out_close_from:
117 close(fromfd);
118out:
119 return err;
120}
Arnaldo Carvalho de Meloc82ee822010-05-14 14:19:35 -0300121
122unsigned long convert_unit(unsigned long value, char *unit)
123{
124 *unit = ' ';
125
126 if (value > 1000) {
127 value /= 1000;
128 *unit = 'K';
129 }
130
131 if (value > 1000) {
132 value /= 1000;
133 *unit = 'M';
134 }
135
136 if (value > 1000) {
137 value /= 1000;
138 *unit = 'G';
139 }
140
141 return value;
142}
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200143
144int readn(int fd, void *buf, size_t n)
145{
146 void *buf_start = buf;
147
148 while (n) {
149 int ret = read(fd, buf, n);
150
151 if (ret <= 0)
152 return ret;
153
154 n -= ret;
155 buf += ret;
156 }
157
158 return buf - buf_start;
159}
Arnaldo Carvalho de Melo61e04b32012-04-19 13:15:24 -0300160
161size_t hex_width(u64 v)
162{
163 size_t n = 1;
164
165 while ((v >>= 4))
166 ++n;
167
168 return n;
169}
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300170
Jiri Olsab2aff5f2012-10-27 23:18:30 +0200171static int hex(char ch)
172{
173 if ((ch >= '0') && (ch <= '9'))
174 return ch - '0';
175 if ((ch >= 'a') && (ch <= 'f'))
176 return ch - 'a' + 10;
177 if ((ch >= 'A') && (ch <= 'F'))
178 return ch - 'A' + 10;
179 return -1;
180}
181
182/*
183 * While we find nice hex chars, build a long_val.
184 * Return number of chars processed.
185 */
186int hex2u64(const char *ptr, u64 *long_val)
187{
188 const char *p = ptr;
189 *long_val = 0;
190
191 while (*p) {
192 const int hex_val = hex(*p);
193
194 if (hex_val < 0)
195 break;
196
197 *long_val = (*long_val << 4) | hex_val;
198 p++;
199 }
200
201 return p - ptr;
202}
203
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300204/* Obtain a backtrace and print it to stdout. */
Namhyung Kim4e34d952012-10-02 01:32:51 +0900205#ifdef BACKTRACE_SUPPORT
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300206void dump_stack(void)
207{
208 void *array[16];
209 size_t size = backtrace(array, ARRAY_SIZE(array));
210 char **strings = backtrace_symbols(array, size);
211 size_t i;
212
213 printf("Obtained %zd stack frames.\n", size);
214
215 for (i = 0; i < size; i++)
216 printf("%s\n", strings[i]);
217
218 free(strings);
219}
Irina Tirdeac9f08be2012-09-08 03:43:23 +0300220#else
221void dump_stack(void) {}
222#endif
David Ahern2c803e52013-01-14 10:48:01 -0700223
224void get_term_dimensions(struct winsize *ws)
225{
226 char *s = getenv("LINES");
227
228 if (s != NULL) {
229 ws->ws_row = atoi(s);
230 s = getenv("COLUMNS");
231 if (s != NULL) {
232 ws->ws_col = atoi(s);
233 if (ws->ws_row && ws->ws_col)
234 return;
235 }
236 }
237#ifdef TIOCGWINSZ
238 if (ioctl(1, TIOCGWINSZ, ws) == 0 &&
239 ws->ws_row && ws->ws_col)
240 return;
241#endif
242 ws->ws_row = 25;
243 ws->ws_col = 80;
244}