![Arnaldo Carvalho de Melo](/assets/img/avatar_default.png)
Number of samples is meaningless after we switched to auto-freq, so report the number of events, i.e. not the sum of the different periods, but the number PERF_RECORD_SAMPLE emitted by the kernel. While doing this I noticed that naming "count" to the sum of all the event periods can be confusing, so rename it to .period, just like in struct sample.data, so that we become more consistent. This helps with the next step, that was to record in struct hist_entry the number of sample events for each instance, we need that because we use it to generate the number of events when applying filters to the tree of hist entries like it is being done in the TUI report browser. Suggested-by: Ingo Molnar <mingo@elte.hu> Cc: Frédéric Weisbecker <fweisbec@gmail.com> Cc: Mike Galbraith <efault@gmx.de> Cc: Paul Mackerras <paulus@samba.org> Cc: Peter Zijlstra <a.p.zijlstra@chello.nl> Cc: Tom Zanussi <tzanussi@gmail.com> LKML-Reference: <new-submission> Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
117 lines
1.8 KiB
C
117 lines
1.8 KiB
C
#include "util.h"
|
|
#include <sys/mman.h>
|
|
|
|
int mkdir_p(char *path, mode_t mode)
|
|
{
|
|
struct stat st;
|
|
int err;
|
|
char *d = path;
|
|
|
|
if (*d != '/')
|
|
return -1;
|
|
|
|
if (stat(path, &st) == 0)
|
|
return 0;
|
|
|
|
while (*++d == '/');
|
|
|
|
while ((d = strchr(d, '/'))) {
|
|
*d = '\0';
|
|
err = stat(path, &st) && mkdir(path, mode);
|
|
*d++ = '/';
|
|
if (err)
|
|
return -1;
|
|
while (*d == '/')
|
|
++d;
|
|
}
|
|
return (stat(path, &st) && mkdir(path, mode)) ? -1 : 0;
|
|
}
|
|
|
|
static int slow_copyfile(const char *from, const char *to)
|
|
{
|
|
int err = 0;
|
|
char *line = NULL;
|
|
size_t n;
|
|
FILE *from_fp = fopen(from, "r"), *to_fp;
|
|
|
|
if (from_fp == NULL)
|
|
goto out;
|
|
|
|
to_fp = fopen(to, "w");
|
|
if (to_fp == NULL)
|
|
goto out_fclose_from;
|
|
|
|
while (getline(&line, &n, from_fp) > 0)
|
|
if (fputs(line, to_fp) == EOF)
|
|
goto out_fclose_to;
|
|
err = 0;
|
|
out_fclose_to:
|
|
fclose(to_fp);
|
|
free(line);
|
|
out_fclose_from:
|
|
fclose(from_fp);
|
|
out:
|
|
return err;
|
|
}
|
|
|
|
int copyfile(const char *from, const char *to)
|
|
{
|
|
int fromfd, tofd;
|
|
struct stat st;
|
|
void *addr;
|
|
int err = -1;
|
|
|
|
if (stat(from, &st))
|
|
goto out;
|
|
|
|
if (st.st_size == 0) /* /proc? do it slowly... */
|
|
return slow_copyfile(from, to);
|
|
|
|
fromfd = open(from, O_RDONLY);
|
|
if (fromfd < 0)
|
|
goto out;
|
|
|
|
tofd = creat(to, 0755);
|
|
if (tofd < 0)
|
|
goto out_close_from;
|
|
|
|
addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0);
|
|
if (addr == MAP_FAILED)
|
|
goto out_close_to;
|
|
|
|
if (write(tofd, addr, st.st_size) == st.st_size)
|
|
err = 0;
|
|
|
|
munmap(addr, st.st_size);
|
|
out_close_to:
|
|
close(tofd);
|
|
if (err)
|
|
unlink(to);
|
|
out_close_from:
|
|
close(fromfd);
|
|
out:
|
|
return err;
|
|
}
|
|
|
|
unsigned long convert_unit(unsigned long value, char *unit)
|
|
{
|
|
*unit = ' ';
|
|
|
|
if (value > 1000) {
|
|
value /= 1000;
|
|
*unit = 'K';
|
|
}
|
|
|
|
if (value > 1000) {
|
|
value /= 1000;
|
|
*unit = 'M';
|
|
}
|
|
|
|
if (value > 1000) {
|
|
value /= 1000;
|
|
*unit = 'G';
|
|
}
|
|
|
|
return value;
|
|
}
|