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
30 #include <stdio_ext.h>
34 #include <sys/sysinfo.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
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) \
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 \
63 while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
64 if (strncmp (BUFFER, "processor", 9) == 0) \
74 /* XXX Here will come a test for the new system call. */
79 /* The /proc/stat format is more uniform, use it by default. */
80 FILE *fp
= fopen ("/proc/stat", "rc");
83 /* No threads use this stream. */
84 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
87 while (fgets_unlocked (buffer
, sizeof (buffer
), fp
) != NULL
)
88 if (strncmp (buffer
, "cpu", 3) == 0 && isdigit (buffer
[3]))
95 fp
= fopen ("/proc/cpuinfo", "rc");
98 /* No threads use this stream. */
99 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
100 GET_NPROCS_PARSER (fp
, buffer
, result
);
107 weak_alias (__get_nprocs
, get_nprocs
)
110 /* On some architectures it is possible to distinguish between configured
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");
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)
130 unsigned long int nr
= strtoul (d
->d_name
+ 3, &endp
, 10);
131 if (nr
!= ULONG_MAX
&& endp
!= d
->d_name
+ 3 && *endp
== '\0')
142 #ifdef GET_NPROCS_CONF_PARSER
143 /* If we haven't found an appropriate entry return 1. */
144 FILE *fp
= fopen ("/proc/cpuinfo", "rc");
149 /* No threads use this stream. */
150 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
151 GET_NPROCS_CONF_PARSER (fp
, buffer
, result
);
155 result
= __get_nprocs ();
160 weak_alias (__get_nprocs_conf
, get_nprocs_conf
)
162 /* General function to get information about memory status from proc
166 phys_pages_info (const char *format
)
169 long int result
= -1;
171 /* If we haven't found an appropriate entry return 1. */
172 FILE *fp
= fopen ("/proc/meminfo", "rc");
175 /* No threads use this stream. */
176 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
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);
194 /* We cannot get the needed value: signal an error. */
195 __set_errno (ENOSYS
);
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
209 But not all systems have support for the /proc filesystem. If it
210 is not available we return -1 as an error signal. */
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
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
230 But not all systems have support for the /proc filesystem. If it
231 is not available we return -1 as an error signal. */
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
)