blob: b492cb974aa0db84b49b6efc3608bf2affeec5c1 [file] [log] [blame]
rjw1f884582022-01-06 17:20:42 +08001// 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
8struct perf_env perf_env;
9
10void 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
36int 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;
58out_free:
59 zfree(&env->cmdline_argv);
60out_enomem:
61 return -ENOMEM;
62}
63
64int 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
91static 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
104static 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
112const char *perf_env__raw_arch(struct perf_env *env)
113{
114 return env && !perf_env__read_arch(env) ? env->arch : "unknown";
115}
116
117int 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
122void cpu_cache_level__free(struct cpu_cache_level *cache)
123{
124 free(cache->type);
125 free(cache->map);
126 free(cache->size);
127}