2.9
[glibc/nacl-glibc.git] / sysdeps / unix / sysv / linux / getsysstats.c
blob6d4c9c06e8a5de1b97da448909aa0874df5f6c88
1 /* Determine various system internal values, Linux version.
2 Copyright (C) 1996-2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1996.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
21 #include <alloca.h>
22 #include <assert.h>
23 #include <ctype.h>
24 #include <dirent.h>
25 #include <errno.h>
26 #include <fcntl.h>
27 #include <mntent.h>
28 #include <paths.h>
29 #include <stdio.h>
30 #include <stdio_ext.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <unistd.h>
34 #include <sys/sysinfo.h>
36 #include <atomic.h>
37 #include <not-cancel.h>
40 /* How we can determine the number of available processors depends on
41 the configuration. There is currently (as of version 2.0.21) no
42 system call to determine the number. It is planned for the 2.1.x
43 series to add this, though.
45 One possibility to implement it for systems using Linux 2.0 is to
46 examine the pseudo file /proc/cpuinfo. Here we have one entry for
47 each processor.
49 But not all systems have support for the /proc filesystem. If it
50 is not available we simply return 1 since there is no way. */
52 /* Other architectures use different formats for /proc/cpuinfo. This
53 provides a hook for alternative parsers. */
54 #ifndef GET_NPROCS_PARSER
55 # define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
56 do \
57 { \
58 (RESULT) = 0; \
59 /* Read all lines and count the lines starting with the string \
60 "processor". We don't have to fear extremely long lines since \
61 the kernel will not generate them. 8192 bytes are really \
62 enough. */ \
63 while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
64 if (strncmp (BUFFER, "processor", 9) == 0) \
65 ++(RESULT); \
66 } \
67 while (0)
68 #endif
71 int
72 __get_nprocs ()
74 /* XXX Here will come a test for the new system call. */
76 char buffer[8192];
77 int result = 1;
79 /* The /proc/stat format is more uniform, use it by default. */
80 FILE *fp = fopen ("/proc/stat", "rc");
81 if (fp != NULL)
83 /* No threads use this stream. */
84 __fsetlocking (fp, FSETLOCKING_BYCALLER);
86 result = 0;
87 while (fgets_unlocked (buffer, sizeof (buffer), fp) != NULL)
88 if (strncmp (buffer, "cpu", 3) == 0 && isdigit (buffer[3]))
89 ++result;
91 fclose (fp);
93 else
95 fp = fopen ("/proc/cpuinfo", "rc");
96 if (fp != NULL)
98 /* No threads use this stream. */
99 __fsetlocking (fp, FSETLOCKING_BYCALLER);
100 GET_NPROCS_PARSER (fp, buffer, result);
101 fclose (fp);
105 return result;
107 weak_alias (__get_nprocs, get_nprocs)
110 /* On some architectures it is possible to distinguish between configured
111 and active cpus. */
113 __get_nprocs_conf ()
115 /* XXX Here will come a test for the new system call. */
117 /* Try to use the sysfs filesystem. It has actual information about
118 online processors. */
119 DIR *dir = __opendir ("/sys/devices/system/cpu");
120 if (dir != NULL)
122 int count = 0;
123 struct dirent64 *d;
125 while ((d = __readdir64 (dir)) != NULL)
126 /* NB: the sysfs has d_type support. */
127 if (d->d_type == DT_DIR && strncmp (d->d_name, "cpu", 3) == 0)
129 char *endp;
130 unsigned long int nr = strtoul (d->d_name + 3, &endp, 10);
131 if (nr != ULONG_MAX && endp != d->d_name + 3 && *endp == '\0')
132 ++count;
135 __closedir (dir);
137 return count;
140 int result = 1;
142 #ifdef GET_NPROCS_CONF_PARSER
143 /* If we haven't found an appropriate entry return 1. */
144 FILE *fp = fopen ("/proc/cpuinfo", "rc");
145 if (fp != NULL)
147 char buffer[8192];
149 /* No threads use this stream. */
150 __fsetlocking (fp, FSETLOCKING_BYCALLER);
151 GET_NPROCS_CONF_PARSER (fp, buffer, result);
152 fclose (fp);
154 #else
155 result = __get_nprocs ();
156 #endif
158 return result;
160 weak_alias (__get_nprocs_conf, get_nprocs_conf)
162 /* General function to get information about memory status from proc
163 filesystem. */
164 static long int
165 internal_function
166 phys_pages_info (const char *format)
168 char buffer[8192];
169 long int result = -1;
171 /* If we haven't found an appropriate entry return 1. */
172 FILE *fp = fopen ("/proc/meminfo", "rc");
173 if (fp != NULL)
175 /* No threads use this stream. */
176 __fsetlocking (fp, FSETLOCKING_BYCALLER);
178 result = 0;
179 /* Read all lines and count the lines starting with the
180 string "processor". We don't have to fear extremely long
181 lines since the kernel will not generate them. 8192
182 bytes are really enough. */
183 while (fgets_unlocked (buffer, sizeof buffer, fp) != NULL)
184 if (sscanf (buffer, format, &result) == 1)
186 result /= (__getpagesize () / 1024);
187 break;
190 fclose (fp);
193 if (result == -1)
194 /* We cannot get the needed value: signal an error. */
195 __set_errno (ENOSYS);
197 return result;
201 /* Return the number of pages of physical memory in the system. There
202 is currently (as of version 2.0.21) no system call to determine the
203 number. It is planned for the 2.1.x series to add this, though.
205 One possibility to implement it for systems using Linux 2.0 is to
206 examine the pseudo file /proc/cpuinfo. Here we have one entry for
207 each processor.
209 But not all systems have support for the /proc filesystem. If it
210 is not available we return -1 as an error signal. */
211 long int
212 __get_phys_pages ()
214 /* XXX Here will come a test for the new system call. */
216 return phys_pages_info ("MemTotal: %ld kB");
218 weak_alias (__get_phys_pages, get_phys_pages)
221 /* Return the number of available pages of physical memory in the
222 system. There is currently (as of version 2.0.21) no system call
223 to determine the number. It is planned for the 2.1.x series to add
224 this, though.
226 One possibility to implement it for systems using Linux 2.0 is to
227 examine the pseudo file /proc/cpuinfo. Here we have one entry for
228 each processor.
230 But not all systems have support for the /proc filesystem. If it
231 is not available we return -1 as an error signal. */
232 long int
233 __get_avphys_pages ()
235 /* XXX Here will come a test for the new system call. */
237 return phys_pages_info ("MemFree: %ld kB");
239 weak_alias (__get_avphys_pages, get_avphys_pages)