aboutsummaryrefslogtreecommitdiffstats
path: root/proc_cpuinfo.c
blob: 842cabf4e18b5239fcd075ffc7c0d3fac32d20c9 (plain)
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
// SPDX-License-Identifier: GPL-2.0

/*
 * Copyright (C) 2015 Intel Corporation
 * Author: Tony Luck
 *
 * This software may be redistributed and/or modified under the terms of
 * the GNU General Public License ("GPL") version 2 only as published by the
 * Free Software Foundation.
 */

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>

/*
 * read /proc/cpuinfo to discover:
 * 1) number of cpu sockets
 * 2) Number of logical cpus
 * 3) Model name of the cpu
 * 4) Logical cpu# to apicd mappings
 */
void proc_cpuinfo(int *nsockets, int *ncpus, char *model, int *modelnum, int **apicmap)
{
	FILE	*fp = fopen("/proc/cpuinfo", "r");
	char	*p, line[4096];
	long	apicid, lcpu, s, sockmask = 0;
	int	i, maxcpus = 4;

	*nsockets = 0;
	*ncpus = 0;
	*apicmap = (int *)calloc(sizeof (int), maxcpus);

	if (fp == NULL)
		return;

	while (fgets(line, sizeof line, fp)) {
		if (model[0] == '\0' && strncmp(line, "model name", 10) == 0) {
			p = strchr(&line[10], ':');
			while (isspace(*++p))
				;
			strcpy(model, p);
		} else if (strncmp(line, "model\t", 6) == 0) {
			p = strchr(&line[6], ':');
			*modelnum = atoi(p+1);
		} else if (strncmp(line, "physical id", 11) == 0) {
			(*ncpus)++;
			p = strchr(&line[10], ':');
			s = strtol(p+1, NULL, 10);
			if (s > 63) {
				fprintf(stderr, "Found socket %d > max supported\n", s);
				exit(1);
			}
			sockmask |= 1 << s;
		} else if (strncmp(line, "processor", 9) == 0) {
			p = strchr(&line[8], ':');
			lcpu = strtol(p+1, NULL, 10);
		} else if (strncmp(line, "apicid", 6) == 0) {
			p = strchr(&line[5], ':');
			apicid = strtol(p+1, NULL, 10);
			if (lcpu >= maxcpus) {
				maxcpus *= 2;
				*apicmap = realloc(*apicmap, maxcpus * sizeof (int));
			}
			(*apicmap)[lcpu] = apicid;
		}
	}
	for (i = 0; i < 8 * sizeof sockmask; i++)
		if (sockmask & (1l << i))
			(*nsockets)++;

	fclose(fp);
}