#ifdef __UCLIBC_HAS_REGEX__
#include <regex.h>
#endif
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+#include <sysdep.h>
+#include <sys/resource.h>
-#ifdef HAVE_LINUX_CPUMASK_H
-# include <linux/cpumask.h>
-#endif
-#ifndef num_present_cpus
-# define num_present_cpus() (1)
-#endif
-#ifndef num_online_cpus
-# define num_online_cpus() (1)
#endif
+#include <string.h>
+#include <dirent.h>
+#include "internal/parse_config.h"
+
+static int nprocessors_onln(void)
+{
+ char **l = NULL;
+ parser_t *p = config_open("/proc/stat");
+ int ret = 0;
+
+ if (p) {
+ while (config_read(p, &l, 2, 1, " ", 0))
+ if (l[0][0] == 'c'
+ && l[0][1] == 'p'
+ && l[0][2] == 'u'
+ && isdigit(l[0][3]))
+ ++ret;
+ } else if ((p = config_open("/proc/cpuinfo"))) {
+#if defined __sparc__
+ while (config_read(p, &l, 2, 2, "\0:", PARSE_NORMAL))
+ if (strncmp("ncpus active", l[0], 12) == 0) {
+ ret = atoi(l[1]);
+ break;
+ }
+#else
+ while (config_read(p, &l, 2, 2, "\0:\t", PARSE_NORMAL))
+ if (strcmp("processor", l[0]) == 0)
+ ++ret;
+#endif
+ }
+ config_close(p);
+ return ret != 0 ? ret : 1;
+}
+#if defined __UCLIBC__ && !defined __UCLIBC_HAS_LFS__
+# define readdir64 readdir
+# define dirent64 dirent
+#endif
+static int nprocessors_conf(void)
+{
+ int ret = 0;
+ DIR *dir = opendir("/sys/devices/system/cpu");
+
+ if (dir) {
+ struct dirent64 *dp;
+
+ while ((dp = readdir64(dir))) {
+ if (dp->d_type == DT_DIR
+ && dp->d_name[0] == 'c'
+ && dp->d_name[1] == 'p'
+ && dp->d_name[2] == 'u'
+ && isdigit(dp->d_name[3]))
+ ++ret;
+ }
+ closedir(dir);
+ } else
+ {
+#if defined __sparc__
+ char **l = NULL;
+ parser_t *p = config_open("/proc/stat");
+ while (config_read(p, &l, 2, 2, "\0:", PARSE_NORMAL))
+ if (strncmp("ncpus probed", l[0], 13) == 0) {
+ ret = atoi(l[1]);
+ break;
+ }
+ config_close(p);
+#else
+ ret = nprocessors_onln();
+#endif
+ }
+ return ret != 0 ? ret : 1;
+}
#ifndef __UCLIBC_CLK_TCK_CONST
#define RETURN_FUNCTION(f) return f;
#endif /* _UCLIBC_GENERATE_SYSCONF_ARCH */
+/* Legacy value of ARG_MAX. The macro is now not defined since the
+ actual value varies based on the stack size. */
+#define legacy_ARG_MAX 131072
+
/* Get the value of the system variable NAME. */
long int sysconf(int name)
{
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ struct rlimit rlimit;
+#endif
switch (name)
{
default:
return -1;
case _SC_ARG_MAX:
-#ifdef ARG_MAX
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ /* Use getrlimit to get the stack limit. */
+ if (getrlimit (RLIMIT_STACK, &rlimit) == 0)
+ return MAX (legacy_ARG_MAX, rlimit.rlim_cur / 4);
+#elif defined ARG_MAX
return ARG_MAX;
#else
RETURN_NEG_1;
#endif
case _SC_NPROCESSORS_CONF:
- RETURN_FUNCTION(num_present_cpus());
+ RETURN_FUNCTION(nprocessors_conf());
case _SC_NPROCESSORS_ONLN:
- RETURN_FUNCTION(num_online_cpus());
+ RETURN_FUNCTION(nprocessors_onln());
case _SC_PHYS_PAGES:
#if 0
#endif
case _SC_MONOTONIC_CLOCK:
-#if defined __UCLIBC_HAS_REALTIME__ && defined __NR_clock_getres
- /* Check using the clock_getres system call. */
+#ifdef __NR_clock_getres
+ /* Check using the clock_getres system call. */
+# ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ {
+ struct timespec ts;
+ INTERNAL_SYSCALL_DECL (err);
+ int r;
+ r = INTERNAL_SYSCALL (clock_getres, err, 2, CLOCK_MONOTONIC, &ts);
+ return INTERNAL_SYSCALL_ERROR_P (r, err) ? -1 : _POSIX_VERSION;
+ }
+# else
if (clock_getres(CLOCK_MONOTONIC, NULL) >= 0)
return _POSIX_VERSION;
+
+ RETURN_NEG_1;
+# endif
#endif
+#ifdef __UCLIBC_HAS_THREADS_NATIVE__
+ case _SC_THREAD_CPUTIME:
+# if _POSIX_THREAD_CPUTIME > 0
+ return _POSIX_THREAD_CPUTIME;
+# else
RETURN_NEG_1;
+# endif
+#endif
}
}
libc_hidden_def(sysconf)