]>
sourceware.org Git - glibc.git/blob - sysdeps/unix/sysv/linux/getsysstats.c
eaacf3727c6a45a489c29ad3f75e9e31fbf0e34f
1 /* Determine various system internal values, Linux version.
2 Copyright (C) 1996-2001, 2002 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
28 #include <stdio_ext.h>
32 #include <sys/sysinfo.h>
34 #include <atomicity.h>
37 /* The default value for the /proc filesystem mount point. */
38 static const char path_proc
[] = "/proc";
40 /* Actual mount point of /proc filesystem. */
41 static char *mount_proc
;
43 /* Determine the path to the /proc filesystem if available. */
46 get_proc_path (char *buffer
, size_t bufsize
)
48 struct mntent mount_point
;
54 /* First find the mount point of the proc filesystem. */
55 fp
= __setmntent (_PATH_MOUNTED
, "r");
57 fp
= __setmntent (_PATH_MNTTAB
, "r");
60 /* We don't need locking. */
61 (void) __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
63 while ((entry
= __getmntent_r (fp
, &mount_point
, buffer
, bufsize
))
65 if (strcmp (mount_point
.mnt_type
, "proc") == 0)
67 result
= mount_point
.mnt_dir
;
73 /* If we haven't found anything this is generally a bad sign but we
74 handle it gracefully. We return what is hopefully the right
75 answer (/proc) but we don't remember this. This will enable
76 programs which started before the system is fully running to
81 /* Make a copy we can keep around. */
82 copy_result
= __strdup (result
);
83 if (copy_result
== NULL
)
86 /* Now store the copied value. But do it atomically. */
87 assert (sizeof (long int) == sizeof (void *__unbounded
));
88 if (compare_and_swap ((long int *) &mount_proc
, (long int) 0,
89 (long int) copy_result
) == 0)
90 /* Replacing the value failed. This means another thread was
91 faster and we don't need the copy anymore. */
93 #if __BOUNDED_POINTERS__
96 /* compare_and_swap only copied the pointer value, so we must
97 now copy the bounds as well. */
98 __ptrlow (mount_proc
) = __ptrlow (copy_result
);
99 __ptrhigh (mount_proc
) = __ptrhigh (copy_result
);
107 /* How we can determine the number of available processors depends on
108 the configuration. There is currently (as of version 2.0.21) no
109 system call to determine the number. It is planned for the 2.1.x
110 series to add this, though.
112 One possibility to implement it for systems using Linux 2.0 is to
113 examine the pseudo file /proc/cpuinfo. Here we have one entry for
116 But not all systems have support for the /proc filesystem. If it
117 is not available we simply return 1 since there is no way. */
119 /* Other architectures use different formats for /proc/cpuinfo. This
120 provides a hook for alternative parsers. */
121 #ifndef GET_NPROCS_PARSER
122 # define GET_NPROCS_PARSER(FP, BUFFER, RESULT) \
126 /* Read all lines and count the lines starting with the string \
127 "processor". We don't have to fear extremely long lines since \
128 the kernel will not generate them. 8192 bytes are really \
130 while (fgets_unlocked (BUFFER, sizeof (BUFFER), FP) != NULL) \
131 if (strncmp (BUFFER, "processor", 9) == 0) \
142 const char *proc_path
;
145 /* XXX Here will come a test for the new system call. */
147 /* Get mount point of proc filesystem. */
148 proc_path
= get_proc_path (buffer
, sizeof buffer
);
150 /* If we haven't found an appropriate entry return 1. */
151 if (proc_path
!= NULL
)
153 char *proc_fname
= alloca (strlen (proc_path
) + sizeof ("/cpuinfo"));
155 /* The /proc/stat format is more uniform, use it by default. */
156 __stpcpy (__stpcpy (proc_fname
, proc_path
), "/stat");
158 fp
= fopen (proc_fname
, "r");
161 /* No threads use this stream. */
162 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
165 while (fgets_unlocked (buffer
, sizeof (buffer
), fp
) != NULL
)
166 if (strncmp (buffer
, "cpu", 3) == 0 && isdigit (buffer
[3]))
173 __stpcpy (__stpcpy (proc_fname
, proc_path
), "/cpuinfo");
175 fp
= fopen (proc_fname
, "r");
178 /* No threads use this stream. */
179 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
180 GET_NPROCS_PARSER (fp
, buffer
, result
);
188 weak_alias (__get_nprocs
, get_nprocs
)
191 #ifdef GET_NPROCS_CONF_PARSER
192 /* On some architectures it is possible to distinguish between configured
199 const char *proc_path
;
202 /* XXX Here will come a test for the new system call. */
204 /* Get mount point of proc filesystem. */
205 proc_path
= get_proc_path (buffer
, sizeof buffer
);
207 /* If we haven't found an appropriate entry return 1. */
208 if (proc_path
!= NULL
)
210 char *proc_cpuinfo
= alloca (strlen (proc_path
) + sizeof ("/cpuinfo"));
211 __stpcpy (__stpcpy (proc_cpuinfo
, proc_path
), "/cpuinfo");
213 fp
= fopen (proc_cpuinfo
, "r");
216 /* No threads use this stream. */
217 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
218 GET_NPROCS_CONF_PARSER (fp
, buffer
, result
);
226 /* As far as I know Linux has no separate numbers for configured and
227 available processors. So make the `get_nprocs_conf' function an
229 strong_alias (__get_nprocs
, __get_nprocs_conf
)
231 weak_alias (__get_nprocs_conf
, get_nprocs_conf
)
233 /* General function to get information about memory status from proc
237 phys_pages_info (const char *format
)
241 const char *proc_path
;
242 long int result
= -1;
244 /* Get mount point of proc filesystem. */
245 proc_path
= get_proc_path (buffer
, sizeof buffer
);
247 /* If we haven't found an appropriate entry return 1. */
248 if (proc_path
!= NULL
)
250 char *proc_meminfo
= alloca (strlen (proc_path
) + sizeof ("/meminfo"));
251 __stpcpy (__stpcpy (proc_meminfo
, proc_path
), "/meminfo");
253 fp
= fopen (proc_meminfo
, "r");
256 /* No threads use this stream. */
257 __fsetlocking (fp
, FSETLOCKING_BYCALLER
);
260 /* Read all lines and count the lines starting with the
261 string "processor". We don't have to fear extremely long
262 lines since the kernel will not generate them. 8192
263 bytes are really enough. */
264 while (fgets_unlocked (buffer
, sizeof buffer
, fp
) != NULL
)
265 if (sscanf (buffer
, format
, &result
) == 1)
267 result
/= (__getpagesize () / 1024);
276 /* We cannot get the needed value: signal an error. */
277 __set_errno (ENOSYS
);
283 /* Return the number of pages of physical memory in the system. There
284 is currently (as of version 2.0.21) no system call to determine the
285 number. It is planned for the 2.1.x series to add this, though.
287 One possibility to implement it for systems using Linux 2.0 is to
288 examine the pseudo file /proc/cpuinfo. Here we have one entry for
291 But not all systems have support for the /proc filesystem. If it
292 is not available we return -1 as an error signal. */
296 /* XXX Here will come a test for the new system call. */
298 return phys_pages_info ("MemTotal: %ld kB");
300 weak_alias (__get_phys_pages
, get_phys_pages
)
303 /* Return the number of available pages of physical memory in the
304 system. There is currently (as of version 2.0.21) no system call
305 to determine the number. It is planned for the 2.1.x series to add
308 One possibility to implement it for systems using Linux 2.0 is to
309 examine the pseudo file /proc/cpuinfo. Here we have one entry for
312 But not all systems have support for the /proc filesystem. If it
313 is not available we return -1 as an error signal. */
315 __get_avphys_pages ()
317 /* XXX Here will come a test for the new system call. */
319 return phys_pages_info ("MemFree: %ld kB");
321 weak_alias (__get_avphys_pages
, get_avphys_pages
)
329 text_set_element (__libc_subfreeres
, free_mem
);
This page took 0.054371 seconds and 4 git commands to generate.