1/*
2 *   Copyright (c) 2012 Fujitsu Ltd.
3 *   Author: Wanlong Gao <gaowanlong@cn.fujitsu.com>
4 *
5 *   This program is free software;  you can redistribute it and/or modify
6 *   it under the terms of the GNU General Public License as published by
7 *   the Free Software Foundation; either version 2 of the License, or
8 *   (at your option) any later version.
9 *
10 *   This program is distributed in the hope that it will be useful,
11 *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
12 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
13 *   the GNU General Public License for more details.
14 *
15 *   You should have received a copy of the GNU General Public License
16 *   along with this program;  if not, write to the Free Software
17 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20#include <stdlib.h>
21#include <unistd.h>
22#include "test.h"
23#include "safe_macros.h"
24
25long tst_ncpus(void)
26{
27	long ncpus = -1;
28#ifdef _SC_NPROCESSORS_ONLN
29	ncpus = SAFE_SYSCONF(NULL, _SC_NPROCESSORS_ONLN);
30#else
31	tst_brkm(TBROK, NULL, "could not determine number of CPUs online");
32#endif
33	return ncpus;
34}
35
36long tst_ncpus_conf(void)
37{
38	long ncpus_conf = -1;
39#ifdef _SC_NPROCESSORS_CONF
40	ncpus_conf = SAFE_SYSCONF(NULL, _SC_NPROCESSORS_CONF);
41#else
42	tst_brkm(TBROK, NULL, "could not determine number of CPUs configured");
43#endif
44	return ncpus_conf;
45}
46
47#define KERNEL_MAX "/sys/devices/system/cpu/kernel_max"
48
49long tst_ncpus_max(void)
50{
51	long ncpus_max = -1;
52	struct stat buf;
53
54	/* sched_getaffinity() and sched_setaffinity() cares about number of
55	 * possible CPUs the OS or hardware can support, which can be larger
56	 * than what sysconf(_SC_NPROCESSORS_CONF) currently provides
57	 * (by enumarating /sys/devices/system/cpu/cpu* entries).
58	 *
59	 *  Use /sys/devices/system/cpu/kernel_max, if available. This
60	 *  represents NR_CPUS-1, a compile time option which specifies
61	 *  "maximum number of CPUs which this kernel will support".
62	 *  This should provide cpu mask size large enough for any purposes. */
63	if (stat(KERNEL_MAX, &buf) == 0) {
64		SAFE_FILE_SCANF(NULL, KERNEL_MAX, "%ld", &ncpus_max);
65		/* this is maximum CPU index allowed by the kernel
66		 * configuration, so # of cpus allowed by config is +1 */
67		ncpus_max++;
68	} else {
69		/* fall back to _SC_NPROCESSORS_CONF */
70		ncpus_max = tst_ncpus_conf();
71	}
72	return ncpus_max;
73}
74