Linux Kernel
3.7.1
Main Page
Related Pages
Modules
Namespaces
Data Structures
Files
File List
Globals
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Macros
Groups
Pages
tools
power
cpupower
utils
helpers
topology.c
Go to the documentation of this file.
1
/*
2
* (C) 2010,2011 Thomas Renninger <
[email protected]
>, Novell Inc.
3
*
4
* Licensed under the terms of the GNU GPL License version 2.
5
*
6
* ToDo: Needs to be done more properly for AMD/Intel specifics
7
*/
8
9
/* Helper struct for qsort, must be in sync with cpupower_topology.cpu_info */
10
/* Be careful: Need to pass unsigned to the sort, so that offlined cores are
11
in the end, but double check for -1 for offlined cpus at other places */
12
13
#include <
stdlib.h
>
14
#include <
stdio.h
>
15
#include <unistd.h>
16
#include <errno.h>
17
#include <fcntl.h>
18
19
#include <
helpers/helpers.h
>
20
#include <
helpers/sysfs.h
>
21
22
/* returns -1 on failure, 0 on success */
23
int
sysfs_topology_read_file
(
unsigned
int
cpu
,
const
char
*
fname
)
24
{
25
unsigned
long
value
;
26
char
linebuf[
MAX_LINE_LEN
];
27
char
*endp;
28
char
path
[
SYSFS_PATH_MAX
];
29
30
snprintf
(path,
sizeof
(path),
PATH_TO_CPU
"cpu%u/topology/%s"
,
31
cpu, fname);
32
if
(
sysfs_read_file
(path, linebuf,
MAX_LINE_LEN
) == 0)
33
return
-1;
34
value = strtoul(linebuf, &endp, 0);
35
if
(endp == linebuf ||
errno
==
ERANGE
)
36
return
-1;
37
return
value
;
38
}
39
40
struct
cpuid_core_info
{
41
unsigned
int
pkg
;
42
unsigned
int
thread
;
43
unsigned
int
cpu
;
44
/* flags */
45
unsigned
int
is_online
:1;
46
};
47
48
static
int
__compare(
const
void
*
t1
,
const
void
*
t2
)
49
{
50
struct
cpuid_core_info
*top1 = (
struct
cpuid_core_info
*)t1;
51
struct
cpuid_core_info
*top2 = (
struct
cpuid_core_info
*)t2;
52
if
(top1->
pkg
< top2->
pkg
)
53
return
-1;
54
else
if
(top1->
pkg
> top2->
pkg
)
55
return
1;
56
else
if
(top1->
thread
< top2->
thread
)
57
return
-1;
58
else
if
(top1->
thread
> top2->
thread
)
59
return
1;
60
else
if
(top1->
cpu
< top2->
cpu
)
61
return
-1;
62
else
if
(top1->
cpu
> top2->
cpu
)
63
return
1;
64
else
65
return
0;
66
}
67
68
/*
69
* Returns amount of cpus, negative on error, cpu_top must be
70
* passed to cpu_topology_release to free resources
71
*
72
* Array is sorted after ->pkg, ->core, then ->cpu
73
*/
74
int
get_cpu_topology
(
struct
cpupower_topology
*cpu_top)
75
{
76
int
cpu
,
cpus
= sysconf(_SC_NPROCESSORS_CONF);
77
78
cpu_top->
core_info
=
malloc
(
sizeof
(
struct
cpupower_topology
) * cpus);
79
if
(cpu_top->
core_info
==
NULL
)
80
return
-
ENOMEM
;
81
cpu_top->
pkgs
= cpu_top->
cores
= 0;
82
for
(cpu = 0; cpu <
cpus
; cpu++) {
83
cpu_top->
core_info
[
cpu
].cpu =
cpu
;
84
cpu_top->
core_info
[
cpu
].is_online =
sysfs_is_cpu_online
(cpu);
85
cpu_top->
core_info
[
cpu
].pkg =
86
sysfs_topology_read_file
(cpu,
"physical_package_id"
);
87
if
((
int
)cpu_top->
core_info
[cpu].pkg != -1 &&
88
cpu_top->
core_info
[cpu].pkg > cpu_top->
pkgs
)
89
cpu_top->
pkgs
= cpu_top->
core_info
[
cpu
].pkg;
90
cpu_top->
core_info
[
cpu
].core =
91
sysfs_topology_read_file
(cpu,
"core_id"
);
92
}
93
cpu_top->
pkgs
++;
94
95
qsort(cpu_top->
core_info
, cpus,
sizeof
(
struct
cpuid_core_info
),
96
__compare);
97
98
/* Intel's cores count is not consecutively numbered, there may
99
* be a core_id of 3, but none of 2. Assume there always is 0
100
* Get amount of cores by counting duplicates in a package
101
for (cpu = 0; cpu_top->core_info[cpu].pkg = 0 && cpu < cpus; cpu++) {
102
if (cpu_top->core_info[cpu].core == 0)
103
cpu_top->cores++;
104
*/
105
return
cpus
;
106
}
107
108
void
cpu_topology_release
(
struct
cpupower_topology
cpu_top)
109
{
110
free
(cpu_top.
core_info
);
111
}
Generated on Thu Jan 10 2013 12:56:25 for Linux Kernel by
1.8.2