]> rtime.felk.cvut.cz Git - l4.git/blobdiff - l4/pkg/uclibc/lib/contrib/uclibc/libc/unistd/sysconf.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / unistd / sysconf.c
index af4389bad595a072fb52807683ed1083e447b548..be58f111fd723f67ae68e0b58781c01dfaf31594 100644 (file)
 #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:
@@ -91,7 +164,11 @@ long int sysconf(int name)
       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;
@@ -666,10 +743,10 @@ long int sysconf(int name)
 #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
@@ -906,13 +983,32 @@ long int sysconf(int name)
 #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)