blob: 1b8775c3707d483676c170bbf67d220d8ef1c14a [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>
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -03004#include <execinfo.h>
5#include <stdio.h>
6#include <stdlib.h>
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -02007
Joerg Roedel1aed2672012-01-04 17:54:20 +01008/*
9 * XXX We need to find a better place for these things...
10 */
11bool perf_host = true;
Joerg Roedelc4a7dca2012-02-10 18:05:05 +010012bool perf_guest = false;
Joerg Roedel1aed2672012-01-04 17:54:20 +010013
14void event_attr_init(struct perf_event_attr *attr)
15{
16 if (!perf_host)
17 attr->exclude_host = 1;
18 if (!perf_guest)
19 attr->exclude_guest = 1;
Stephane Eranian7e1ccd32012-02-09 16:12:38 +010020 /* to capture ABI version */
21 attr->size = sizeof(*attr);
Joerg Roedel1aed2672012-01-04 17:54:20 +010022}
23
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020024int mkdir_p(char *path, mode_t mode)
25{
26 struct stat st;
27 int err;
28 char *d = path;
29
30 if (*d != '/')
31 return -1;
32
33 if (stat(path, &st) == 0)
34 return 0;
35
36 while (*++d == '/');
37
38 while ((d = strchr(d, '/'))) {
39 *d = '\0';
40 err = stat(path, &st) && mkdir(path, mode);
41 *d++ = '/';
42 if (err)
43 return -1;
44 while (*d == '/')
45 ++d;
46 }
47 return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
48}
49
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -020050static int slow_copyfile(const char *from, const char *to)
51{
52 int err = 0;
53 char *line = NULL;
54 size_t n;
55 FILE *from_fp = fopen(from, "r"), *to_fp;
56
57 if (from_fp == NULL)
58 goto out;
59
60 to_fp = fopen(to, "w");
61 if (to_fp == NULL)
62 goto out_fclose_from;
63
64 while (getline(&line, &n, from_fp) > 0)
65 if (fputs(line, to_fp) == EOF)
66 goto out_fclose_to;
67 err = 0;
68out_fclose_to:
69 fclose(to_fp);
70 free(line);
71out_fclose_from:
72 fclose(from_fp);
73out:
74 return err;
75}
76
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020077int copyfile(const char *from, const char *to)
78{
79 int fromfd, tofd;
80 struct stat st;
81 void *addr;
82 int err = -1;
83
84 if (stat(from, &st))
85 goto out;
86
Arnaldo Carvalho de Melo9e201442010-01-14 18:30:06 -020087 if (st.st_size == 0) /* /proc? do it slowly... */
88 return slow_copyfile(from, to);
89
Arnaldo Carvalho de Melo4cf40132009-12-27 21:37:06 -020090 fromfd = open(from, O_RDONLY);
91 if (fromfd < 0)
92 goto out;
93
94 tofd = creat(to, 0755);
95 if (tofd < 0)
96 goto out_close_from;
97
98 addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0);
99 if (addr == MAP_FAILED)
100 goto out_close_to;
101
102 if (write(tofd, addr, st.st_size) == st.st_size)
103 err = 0;
104
105 munmap(addr, st.st_size);
106out_close_to:
107 close(tofd);
108 if (err)
109 unlink(to);
110out_close_from:
111 close(fromfd);
112out:
113 return err;
114}
Arnaldo Carvalho de Meloc82ee822010-05-14 14:19:35 -0300115
116unsigned long convert_unit(unsigned long value, char *unit)
117{
118 *unit = ' ';
119
120 if (value > 1000) {
121 value /= 1000;
122 *unit = 'K';
123 }
124
125 if (value > 1000) {
126 value /= 1000;
127 *unit = 'M';
128 }
129
130 if (value > 1000) {
131 value /= 1000;
132 *unit = 'G';
133 }
134
135 return value;
136}
Arnaldo Carvalho de Melo1e7972c2011-01-03 16:50:55 -0200137
138int readn(int fd, void *buf, size_t n)
139{
140 void *buf_start = buf;
141
142 while (n) {
143 int ret = read(fd, buf, n);
144
145 if (ret <= 0)
146 return ret;
147
148 n -= ret;
149 buf += ret;
150 }
151
152 return buf - buf_start;
153}
Arnaldo Carvalho de Melo61e04b32012-04-19 13:15:24 -0300154
155size_t hex_width(u64 v)
156{
157 size_t n = 1;
158
159 while ((v >>= 4))
160 ++n;
161
162 return n;
163}
Arnaldo Carvalho de Melodc4552b2012-08-07 23:32:05 -0300164
165/* Obtain a backtrace and print it to stdout. */
166void dump_stack(void)
167{
168 void *array[16];
169 size_t size = backtrace(array, ARRAY_SIZE(array));
170 char **strings = backtrace_symbols(array, size);
171 size_t i;
172
173 printf("Obtained %zd stack frames.\n", size);
174
175 for (i = 0; i < size; i++)
176 printf("%s\n", strings[i]);
177
178 free(strings);
179}