]> granicus.if.org Git - procps-ng/commitdiff
ELF note scanner
authoralbert <>
Mon, 7 Oct 2002 01:48:47 +0000 (01:48 +0000)
committeralbert <>
Mon, 7 Oct 2002 01:48:47 +0000 (01:48 +0000)
proc/sysinfo.c

index be05d5c8a0280f4942312b036ab62830e0af9d37..17732913a3a9b25f52b3afa51aded428fd4923ad 100644 (file)
@@ -117,9 +117,10 @@ int uptime(double *uptime_secs, double *idle_secs) {
  * used with a kernel that doesn't support the ELF note. On some other
  * architectures there may be a system call or sysctl() that will work.
  */
+
 unsigned long long Hertz;
-static void init_Hertz_value(void) __attribute__((constructor));
-static void init_Hertz_value(void){
+
+static void init_Hertz_value_old(void){
   unsigned long long user_j, nice_j, sys_j, other_j;  /* jiffies (clock ticks) */
   double up_1, up_2, seconds;
   unsigned long long jiffies;
@@ -170,6 +171,34 @@ static void init_Hertz_value(void){
   }
 }
 
+#ifndef AT_CLKTCK
+#define AT_CLKTCK       17    /* frequency of times() */
+#endif
+
+extern char** environ;
+
+/* for ELF executables, notes are pushed before environment and args */
+static unsigned long find_elf_note(unsigned long findme){
+  unsigned long *ep = (unsigned long *)environ;
+  unsigned long ret = 42;
+  while(*ep++);
+  while(*ep++);
+  while(*ep){
+//  printf("%08lx %08lx %011ld %011ld%s\n",ep[0],ep[1],ep[0],ep[1],ep[0]==findme?" <<<":"");
+    if(ep[0]==findme) ret=ep[1];
+    ep+=2;
+  }
+  return ret;
+}
+
+static void init_Hertz_value(void) __attribute__((constructor));
+static void init_Hertz_value(void){
+  Hertz = find_elf_note(AT_CLKTCK);
+  if(Hertz==42) init_Hertz_value_old();
+  else smp_num_cpus = sysconf(_SC_NPROCESSORS_CONF);
+  if(smp_num_cpus<1) smp_num_cpus=1; /* SPARC glibc is buggy */
+}
+
 /***********************************************************************
  * The /proc filesystem calculates idle=jiffies-(user+nice+sys) and we
  * recover jiffies by adding up the 4 or 5 numbers we are given. SMP kernels