• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
perf_env__exit(struct perf_env * env)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 
perf_env__set_cmdline(struct perf_env * env,int argc,const char * argv[])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 
perf_env__read_cpu_topology_map(struct perf_env * env)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 
perf_env__read_arch(struct perf_env * env)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 
perf_env__read_nr_cpus_avail(struct perf_env * env)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 
perf_env__raw_arch(struct perf_env * env)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 
perf_env__nr_cpus_avail(struct perf_env * env)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 
cpu_cache_level__free(struct cpu_cache_level * cache)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 }
128