blob: 5906e8426cc7698161ed09ac30e52291107d9b40 [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
Joerg Roedel1aed2672012-01-04 17:54:20 +010015bool perf_host = true;
Joerg Roedelc4a7dca2012-02-10 18:05:05 +010016bool perf_guest = false;
Joerg Roedel1aed2672012-01-04 17:54:20 +010017
18void event_attr_init(struct perf_event_attr *attr)
19{
20 if (!perf_host)
21 attr->exclude_host = 1;
22 if (!perf_guest)
23 attr->exclude_guest = 1;
Stephane Eranian7e1ccd32012-02-09 16:12:38 +010024 /* to capture ABI version */
25 attr->size = sizeof(*attr);
Joerg Roedel1aed2672012-01-04 17:54:20 +010026}
27
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020028int mkdir_p(char *path, mode_t mode)
29{
30 struct stat st;
31 int err;
32 char *d = path;
33
34 if (*d != '/')
35 return -1;
36
37 if (stat(path, &st) == 0)
38 return 0;
39
40 while (*++d == '/');
41
42 while ((d = strchr(d, '/'))) {
43 *d = '\0';
44 err = stat(path, &st) && mkdir(path, mode);
45 *d++ = '/';
46 if (err)
47 return -1;
48 while (*d == '/')
49 ++d;
50 }
51 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
52}
53
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -020054static int slow_copyfile(const char *from, const char *to)
55{
56 int err = 0;
57 char *line = NULL;
58 size_t n;
59 FILE *from_fp = fopen(from, "r"), *to_fp;
60
61 if (from_fp == NULL)
62 goto out;
63
64 to_fp = fopen(to, "w");
65 if (to_fp == NULL)
66 goto out_fclose_from;
67
68 while (getline(&line, &n, from_fp) > 0)
69 if (fputs(line, to_fp) == EOF)
70 goto out_fclose_to;
71 err = 0;
72out_fclose_to:
73 fclose(to_fp);
74 free(line);
75out_fclose_from:
76 fclose(from_fp);
77out:
78 return err;
79}
80
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020081int copyfile(const char *from, const char *to)
82{
83 int fromfd, tofd;
84 struct stat st;
85 void *addr;
86 int err = -1;
87
88 if (stat(from, &st))
89 goto out;
90
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -020091 if (st.st_size == 0) /* /proc? do it slowly... */
92 return slow_copyfile(from, to);
93
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020094 fromfd = open(from, O_RDONLY);
95 if (fromfd < 0)
96 goto out;
97
98 tofd = creat(to, 0755);
99 if (tofd < 0)
100 goto out_close_from;
101
102 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0);
103 if (addr == MAP_FAILED)
104 goto out_close_to;
105
106 if (write(tofd, addr, st.st_size) == st.st_size)
107 err = 0;
108
109 munmap(addr, st.st_size);
110out_close_to:
111 close(tofd);
112 if (err)
113 unlink(to);
114out_close_from:
115 close(fromfd);
116out:
117 return err;
118}
Arnaldo Carvalho de Meloc82ee822010-05-14 14:19:35 -0300119
120unsigned long convert_unit(unsigned long value, char *unit)
121{
122 *unit = ' ';
123
124 if (value > 1000) {
125 value /= 1000;
126 *unit = 'K';
127 }
128
129 if (value > 1000) {
130 value /= 1000;
131 *unit = 'M';
132 }
133
134 if (value > 1000) {
135 value /= 1000;
136 *unit = 'G';
137 }
138
139 return value;
140}
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200141
142int readn(int fd, void *buf, size_t n)
143{
144 void *buf_start = buf;
145
146 while (n) {
147 int ret = read(fd, buf, n);
148
149 if (ret <= 0)
150 return ret;
151
152 n -= ret;
153 buf += ret;
154 }
155
156 return buf - buf_start;
157}
Arnaldo Carvalho de Melo61e04b32012-04-19 13:15:24 -0300158
159size_t hex_width(u64 v)
160{
161 size_t n = 1;
162
163 while ((v >>= 4))
164 ++n;
165
166 return n;
167}
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300168
Jiri Olsab2aff5f2012-10-27 23:18:30 +0200169static int hex(char ch)
170{
171 if ((ch >= '0') && (ch <= '9'))
172 return ch - '0';
173 if ((ch >= 'a') && (ch <= 'f'))
174 return ch - 'a' + 10;
175 if ((ch >= 'A') && (ch <= 'F'))
176 return ch - 'A' + 10;
177 return -1;
178}
179
180/*
181 * While we find nice hex chars, build a long_val.
182 * Return number of chars processed.
183 */
184int hex2u64(const char *ptr, u64 *long_val)
185{
186 const char *p = ptr;
187 *long_val = 0;
188
189 while (*p) {
190 const int hex_val = hex(*p);
191
192 if (hex_val < 0)
193 break;
194
195 *long_val = (*long_val << 4) | hex_val;
196 p++;
197 }
198
199 return p - ptr;
200}
201
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300202/* Obtain a backtrace and print it to stdout. */
Namhyung Kim4e34d952012-10-02 01:32:51 +0900203#ifdef BACKTRACE_SUPPORT
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300204void dump_stack(void)
205{
206 void *array[16];
207 size_t size = backtrace(array, ARRAY_SIZE(array));
208 char **strings = backtrace_symbols(array, size);
209 size_t i;
210
211 printf("Obtained %zd stack frames.\n", size);
212
213 for (i = 0; i < size; i++)
214 printf("%s\n", strings[i]);
215
216 free(strings);
217}
Irina Tirdeac9f08be2012-09-08 03:43:23 +0300218#else
219void dump_stack(void) {}
220#endif