GNU Linux-libre 4.14.319-gnu1
[releases.git] / tools / perf / util / env.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include "cpumap.h"
3 #include "env.h"
4 #include "util.h"
5 #include <errno.h>
6 #include <sys/utsname.h>
7
8 struct perf_env perf_env;
9
10 void perf_env__exit(struct perf_env *env)
11 {
12         int i;
13
14         zfree(&env->hostname);
15         zfree(&env->os_release);
16         zfree(&env->version);
17         zfree(&env->arch);
18         zfree(&env->cpu_desc);
19         zfree(&env->cpuid);
20         zfree(&env->cmdline);
21         zfree(&env->cmdline_argv);
22         zfree(&env->sibling_cores);
23         zfree(&env->sibling_threads);
24         zfree(&env->pmu_mappings);
25         zfree(&env->cpu);
26
27         for (i = 0; i < env->nr_numa_nodes; i++)
28                 cpu_map__put(env->numa_nodes[i].map);
29         zfree(&env->numa_nodes);
30
31         for (i = 0; i < env->caches_cnt; i++)
32                 cpu_cache_level__free(&env->caches[i]);
33         zfree(&env->caches);
34 }
35
36 int perf_env__set_cmdline(struct perf_env *env, int argc, const char *argv[])
37 {
38         int i;
39
40         /* do not include NULL termination */
41         env->cmdline_argv = calloc(argc, sizeof(char *));
42         if (env->cmdline_argv == NULL)
43                 goto out_enomem;
44
45         /*
46          * Must copy argv contents because it gets moved around during option
47          * parsing:
48          */
49         for (i = 0; i < argc ; i++) {
50                 env->cmdline_argv[i] = argv[i];
51                 if (env->cmdline_argv[i] == NULL)
52                         goto out_free;
53         }
54
55         env->nr_cmdline = argc;
56
57         return 0;
58 out_free:
59         zfree(&env->cmdline_argv);
60 out_enomem:
61         return -ENOMEM;
62 }
63
64 int perf_env__read_cpu_topology_map(struct perf_env *env)
65 {
66         int cpu, nr_cpus;
67
68         if (env->cpu != NULL)
69                 return 0;
70
71         if (env->nr_cpus_avail == 0)
72                 env->nr_cpus_avail = cpu__max_present_cpu();
73
74         nr_cpus = env->nr_cpus_avail;
75         if (nr_cpus == -1)
76                 return -EINVAL;
77
78         env->cpu = calloc(nr_cpus, sizeof(env->cpu[0]));
79         if (env->cpu == NULL)
80                 return -ENOMEM;
81
82         for (cpu = 0; cpu < nr_cpus; ++cpu) {
83                 env->cpu[cpu].core_id   = cpu_map__get_core_id(cpu);
84                 env->cpu[cpu].socket_id = cpu_map__get_socket_id(cpu);
85         }
86
87         env->nr_cpus_avail = nr_cpus;
88         return 0;
89 }
90
91 static int perf_env__read_arch(struct perf_env *env)
92 {
93         struct utsname uts;
94
95         if (env->arch)
96                 return 0;
97
98         if (!uname(&uts))
99                 env->arch = strdup(uts.machine);
100
101         return env->arch ? 0 : -ENOMEM;
102 }
103
104 static int perf_env__read_nr_cpus_avail(struct perf_env *env)
105 {
106         if (env->nr_cpus_avail == 0)
107                 env->nr_cpus_avail = cpu__max_present_cpu();
108
109         return env->nr_cpus_avail ? 0 : -ENOENT;
110 }
111
112 const char *perf_env__raw_arch(struct perf_env *env)
113 {
114         return env && !perf_env__read_arch(env) ? env->arch : "unknown";
115 }
116
117 int perf_env__nr_cpus_avail(struct perf_env *env)
118 {
119         return env && !perf_env__read_nr_cpus_avail(env) ? env->nr_cpus_avail : 0;
120 }
121
122 void cpu_cache_level__free(struct cpu_cache_level *cache)
123 {
124         free(cache->type);
125         free(cache->map);
126         free(cache->size);
127 }