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)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 perf_env__set_cmdline(struct perf_env * env,int argc,const char * argv[])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; 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)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 perf_env__read_arch(struct perf_env * env)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 perf_env__read_nr_cpus_avail(struct perf_env * env)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 perf_env__raw_arch(struct perf_env * env)112const 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)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 cpu_cache_level__free(struct cpu_cache_level * cache)122void cpu_cache_level__free(struct cpu_cache_level *cache) 123 { 124 free(cache->type); 125 free(cache->map); 126 free(cache->size); 127 } 128