File: dt_conf.c

package info (click to toggle)
dtrace 2.0.5-1
  • links: PTS
  • area: main
  • in suites: sid
  • size: 24,408 kB
  • sloc: ansic: 61,247; sh: 17,997; asm: 1,717; lex: 947; awk: 754; yacc: 695; perl: 37; sed: 17; makefile: 15
file content (124 lines) | stat: -rw-r--r-- 2,434 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
/*
 * Oracle Linux DTrace.
 * Copyright (c) 2020, 2024, Oracle and/or its affiliates. All rights reserved.
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <dt_impl.h>

#define SYSFS_CPU	"/sys/devices/system/cpu/"
#define	ONLINE_CPUS	SYSFS_CPU "online"
#define	POSSIBLE_CPUS	SYSFS_CPU "possible"
#define	CPU_CHIP_ID	SYSFS_CPU "cpu%d/topology/physical_package_id"

static uint32_t
dt_cpuinfo_read(dtrace_hdl_t *dtp, const char *fn, cpuinfo_t **cip)
{
	FILE		*fp;
	int		cnt = 0;
	cpuinfo_t	*ci = NULL;

	uint32_t	num, start = 0;
	int		range = 0;
	char		c[2];

	fp = fopen(fn, "r");
	if (fp == NULL)
		goto out;

again:
	cnt = 0;
	for (;;) {
		c[0] = 0;
		switch (fscanf(fp, "%u%1[,-]", &num, c)) {
		case 2:
			if (c[0] == '-') {
				range = 1;
				start = num;
				continue;
			}
			/* fall-through */
		case 1:
			if (range) {
				range = 0;
				cnt += num - start + 1;
			} else {
				start = num;
				cnt++;
			}

			if (ci) {
				uint32_t	i;

				for (i = start; i <= num; i++)
					(ci++)->cpu_id = i;
			}

			if (c[0] == ',')
				continue;
		default:
			break;
		}

		break;
	}

	if (ci == NULL && cip != NULL && cnt > 0) {
		ci = dt_calloc(dtp, cnt, sizeof(cpuinfo_t));
		*cip = ci;
		rewind(fp);
		goto again;
	}

	fclose(fp);
out:
	return cnt;
}

void
dt_conf_init(dtrace_hdl_t *dtp)
{
	size_t		len;
	char		*fn;
	int		i;
	dtrace_conf_t	*conf = &dtp->dt_conf;
	cpuinfo_t	*ci;

	/*
	 * Determine number of possible and online CPUs, and obtain the list of
	 * cpuinfo_t structures for the online CPUs.
	 */
	conf->num_possible_cpus = dt_cpuinfo_read(dtp, POSSIBLE_CPUS, NULL);
	conf->num_online_cpus = dt_cpuinfo_read(dtp, ONLINE_CPUS, &conf->cpus);

	if (conf->num_online_cpus == 0 || conf->cpus == NULL)
		return;

	assert(conf->num_possible_cpus >= conf->num_online_cpus);

	conf->max_cpuid = conf->cpus[conf->num_online_cpus - 1].cpu_id;

	/* Retrieve the chip ID (physical_package_id) for each CPU. */
	len = snprintf(NULL, 0, CPU_CHIP_ID, dtp->dt_conf.max_cpuid) + 1;
	fn = dt_alloc(dtp, len);
	if (fn == NULL)
		return;

	for (i = 0, ci = &dtp->dt_conf.cpus[0]; i < conf->num_online_cpus;
	     i++, ci++) {
		FILE	*fp;

		snprintf(fn, len, CPU_CHIP_ID, ci->cpu_id);
		fp = fopen(fn, "r");
		if (fp != NULL) {
			fscanf(fp, "%u", &ci->cpu_chip);
			fclose(fp);
		}
	}

	dt_free(dtp, fn);
}