suricata
util-cpu.c
Go to the documentation of this file.
1/* Copyright (C) 2007-2013 Open Information Security Foundation
2 *
3 * You can copy, redistribute or modify this Program under the terms of
4 * the GNU General Public License version 2 as published by the Free
5 * Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * version 2 along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15 * 02110-1301, USA.
16 */
17
18/**
19 * \file
20 *
21 * \author Pablo Rincon Crespo <pablo.rincon.crespo@gmail.com>
22 *
23 * Retrieve CPU information (configured CPUs, online CPUs)
24 */
25
26#include "suricata-common.h"
27#include "util-error.h"
28#include "util-debug.h"
29#include "util-cpu.h"
30#include "util-byte.h"
31
32/**
33 * Ok, if they should use sysconf, check that they have the macro's
34 * (syscalls) defined;
35 *
36 * Note: For windows it's different; Check the following:
37 * SYSTEM_INFO info;
38 * GetSystemInfo(&info);
39 * -> info.dwNumberOfProcessors;
40 */
41#ifdef _SC_NPROCESSORS_CONF
42#define SYSCONF_NPROCESSORS_CONF_COMPAT
43#endif
44
45#ifdef _SC_NPROCESSORS_ONLN
46#define SYSCONF_NPROCESSORS_ONLN_COMPAT
47#endif
48
49/* This one is available on Solaris 10 */
50#ifdef _SC_NPROCESSORS_MAX
51#define SYSCONF_NPROCESSORS_MAX_COMPAT
52#endif
53
54/**
55 * \brief Get the number of cpus configured in the system
56 * \retval 0 if the syscall is not available or we have an error;
57 * otherwise it will return the number of cpus configured
58 */
60{
61#ifdef SYSCONF_NPROCESSORS_CONF_COMPAT
62 long nprocs = -1;
63 nprocs = sysconf(_SC_NPROCESSORS_CONF);
64 if (nprocs < 1) {
65 SCLogError("Couldn't retrieve the number of cpus "
66 "configured (%s)",
67 strerror(errno));
68 return 0;
69 }
70
71 if (nprocs > UINT16_MAX) {
72 SCLogDebug("It seems that there are more than %d CPUs "
73 "configured on this system. You can modify util-cpu.{c,h} "
74 "to use uint32_t to support it", UINT16_MAX);
75 return UINT16_MAX;
76 }
77
78 return (uint16_t)nprocs;
79#elif OS_WIN32
80 int64_t nprocs = 0;
81 const char* envvar = getenv("NUMBER_OF_PROCESSORS");
82 if (envvar != NULL) {
83 if (StringParseInt64(&nprocs, 10, 0, envvar) < 0) {
84 SCLogWarning("Invalid value for number of "
85 "processors: %s",
86 envvar);
87 return 0;
88 }
89 }
90 if (nprocs < 1) {
91 SCLogError("Couldn't retrieve the number of cpus "
92 "configured from the NUMBER_OF_PROCESSORS environment variable");
93 return 0;
94 }
95 return (uint16_t)nprocs;
96#else
97 SCLogError("Couldn't retrieve the number of cpus "
98 "configured, sysconf macro unavailable");
99 return 0;
100#endif
101}
102
103/**
104 * \brief Get the number of cpus online in the system
105 * \retval 0 if the syscall is not available or we have an error;
106 * otherwise it will return the number of cpus online
107 */
109{
110#ifdef SYSCONF_NPROCESSORS_ONLN_COMPAT
111 long nprocs = -1;
112 nprocs = sysconf(_SC_NPROCESSORS_ONLN);
113 if (nprocs < 1) {
114 SCLogError("Couldn't retrieve the number of cpus "
115 "online (%s)",
116 strerror(errno));
117 return 0;
118 }
119
120 if (nprocs > UINT16_MAX) {
121 SCLogDebug("It seems that there are more than %d CPUs online. "
122 "You can modify util-cpu.{c,h} to use uint32_t to "
123 "support it", UINT16_MAX);
124 return UINT16_MAX;
125 }
126
127 return (uint16_t)nprocs;
128#elif OS_WIN32
130#else
131 SCLogError("Couldn't retrieve the number of cpus online, "
132 "synconf macro unavailable");
133 return 0;
134#endif
135}
136
137/**
138 * \brief Print a summary of CPUs detected (configured and online)
139 */
141{
142 uint16_t cpus_conf = UtilCpuGetNumProcessorsConfigured();
143 uint16_t cpus_online = UtilCpuGetNumProcessorsOnline();
144
145 SCLogDebug("CPUs Summary: ");
146 if (cpus_conf > 0)
147 SCLogDebug("CPUs configured: %"PRIu16, cpus_conf);
148 if (cpus_online > 0)
149 SCLogInfo("CPUs/cores online: %"PRIu16, cpus_online);
150 if (cpus_online == 0 && cpus_conf == 0)
151 SCLogInfo("Couldn't retrieve any information of CPU's, please, send your operating "
152 "system info and check util-cpu.{c,h}");
153}
154
155/**
156 * Get the current number of ticks from the CPU.
157 *
158 * \todo We'll have to deal with removing ticks from the extra cpuids in between
159 * 2 calls.
160 */
161uint64_t UtilCpuGetTicks(void)
162{
163 uint64_t val;
164#if defined(__GNUC__) && (defined(__x86_64) || defined(_X86_64_) || defined(ia_64) || defined(__i386__))
165#if defined(__x86_64) || defined(_X86_64_) || defined(ia_64)
166 __asm__ __volatile__ (
167 "xorl %%eax,%%eax\n\t"
168 "cpuid\n\t"
169 ::: "%rax", "%rbx", "%rcx", "%rdx");
170#else
171 __asm__ __volatile__ (
172 "xorl %%eax,%%eax\n\t"
173 "pushl %%ebx\n\t"
174 "cpuid\n\t"
175 "popl %%ebx\n\t"
176 ::: "%eax", "%ecx", "%edx");
177#endif
178 uint32_t a, d;
179 __asm__ __volatile__ ("rdtsc" : "=a" (a), "=d" (d));
180 val = ((uint64_t)a) | (((uint64_t)d) << 32);
181#if defined(__x86_64) || defined(_X86_64_) || defined(ia_64)
182 __asm__ __volatile__ (
183 "xorl %%eax,%%eax\n\t"
184 "cpuid\n\t"
185 ::: "%rax", "%rbx", "%rcx", "%rdx");
186#else
187 __asm__ __volatile__ (
188 "xorl %%eax,%%eax\n\t"
189 "pushl %%ebx\n\t"
190 "cpuid\n\t"
191 "popl %%ebx\n\t"
192 ::: "%eax", "%ecx", "%edx");
193#endif
194
195#else /* #if defined(__GNU__) */
196//#warning Using inferior version of UtilCpuGetTicks
197 struct timeval now;
198 gettimeofday(&now, NULL);
199 val = (now.tv_sec * 1000000) + now.tv_usec;
200#endif
201 return val;
202}
int StringParseInt64(int64_t *res, int base, size_t len, const char *str)
Definition util-byte.c:617
uint16_t UtilCpuGetNumProcessorsConfigured(void)
Get the number of cpus configured in the system.
Definition util-cpu.c:59
void UtilCpuPrintSummary(void)
Print a summary of CPUs detected (configured and online)
Definition util-cpu.c:140
uint16_t UtilCpuGetNumProcessorsOnline(void)
Get the number of cpus online in the system.
Definition util-cpu.c:108
uint64_t UtilCpuGetTicks(void)
Definition util-cpu.c:161
#define SCLogDebug(...)
Definition util-debug.h:275
#define SCLogWarning(...)
Macro used to log WARNING messages.
Definition util-debug.h:255
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition util-debug.h:225
#define SCLogError(...)
Macro used to log ERROR messages.
Definition util-debug.h:267