* More feedback for debug (many memory information)
Sylvestre Ledru [Wed, 6 Feb 2008 14:57:52 +0000 (14:57 +0000)]
* First returned values are the dynamic data
* licence file updated since LGPL code is used
* comment in the function getmemory() which is not retrieve interesting values\n* beginning of the debugging info of umfpack

scilab/modules/core/license.txt
scilab/modules/core/sci_gateway/c/sci_getdebuginfo.c
scilab/modules/core/src/c/getdynamicdebuginfo.c
scilab/modules/core/src/c/getmemory.c
scilab/modules/core/src/c/getstaticdebuginfo.c

index b5796bd..ff82e32 100644 (file)
@@ -1 +1,7 @@
-INRIA 2006
\ No newline at end of file
+INRIA 2006
+
+
+Some code in the file src/c/getdynamicdebuginfo.c has been released
+under the term of the LGPL license.
+This piece of code is used to detect the memory available on the system and
+is from the "free" command (package procps).
index 7a975ba..59c4963 100644 (file)
@@ -24,12 +24,13 @@ int C2F(sci_getdebuginfo) _PARAMS((char *fname,unsigned long fname_len))
        
 
 #ifndef _MSC_VER
-       char **outputStaticList=getStaticDebugInfo(&m1);
-       char **outputDynamicList=getDynamicDebugInfo(&m2);
 
-       CreateVarFromPtr(Rhs+1,MATRIX_OF_STRING_DATATYPE, &m1, &n1, outputStaticList);
+       char **outputDynamicList=getDynamicDebugInfo(&m1);
+       char **outputStaticList=getStaticDebugInfo(&m2);
+
+       CreateVarFromPtr(Rhs+1,MATRIX_OF_STRING_DATATYPE, &m1, &n1, outputDynamicList);
        LhsVar(1) = Rhs+1;
-       CreateVarFromPtr(Rhs+2,MATRIX_OF_STRING_DATATYPE, &m2, &n2, outputDynamicList);
+       CreateVarFromPtr(Rhs+2,MATRIX_OF_STRING_DATATYPE, &m2, &n2, outputStaticList);
        LhsVar(2) = Rhs+2;
 #else
        /* TO DO : Windows part */
@@ -38,74 +39,5 @@ int C2F(sci_getdebuginfo) _PARAMS((char *fname,unsigned long fname_len))
 #endif
        C2F(putlhsvar)();
 return 0;
-       /*
-         C2F(getcomp)( C2F(cha1).buf,&nbuf,128);
-         Str[n1]=C2F(cha1).buf;
-         n1++;
-
-         C2F(withpvm)(&irep);
-         if (irep)
-         {
-         Str[n1]=pvm;
-         n1++;
-         }
-
-         C2F(withtk)(&irep);
-         if (irep)
-         {
-         Str[n1]=tk;
-         n1++;
-         }
-
-         C2F(withmodelicac)(&irep);
-         if (irep)
-         {
-         Str[n1]=modelicac;
-         n1++;
-         }
-
-         C2F(withjavasci)(&irep);
-         if (irep)
-         {
-         Str[n1]=javasci;
-         n1++;
-         }
-
-         #ifdef WITH_ATLAS
-         {
-         Str[n1]=atlas;
-         n1++;
-         }
-         #endif
-
-         #ifdef _MSC_VER
-         #ifdef _DEBUG
-         {
-         Str[n1]=debugmode;
-         n1++;
-         }
-         #else
-         {
-         Str[n1]=releasemode;
-         n1++;
-         }
-         #endif
-         #else
-         #ifdef NDEBUG
-         {
-         Str[n1]=releasemode;
-         n1++;
-         }
-         #else
-         {
-         Str[n1]=debugmode;
-         n1++;
-         }
-         #endif
-         #endif
-
-
-         #endif
-       */
 }
 /*--------------------------------------------------------------------------*/
index 6a740b2..33125a1 100644 (file)
@@ -9,10 +9,24 @@
        #include <unistd.h>
        #include <errno.h>
 #endif
+
+
+// UNAME 
 #ifdef HAVE_UNAME
 #include <sys/utsname.h>
 #endif
+
+
+
+#include <unistd.h>
+#include <fcntl.h>
+#include <ctype.h>
+#include <string.h>
+#include <getopt.h>
+#include <stdlib.h> /* bsearch / strtoul */
+
 #include "MALLOC.h"
+#include "getmemory.h"
 #include "getdynamicdebuginfo.h"
 
 /**
@@ -29,6 +43,215 @@ static void SetDebugMsg(debug_message *msg, char* desc, char* value){
        strcpy((*msg).value,value);
 }
 
+
+#ifndef _MSC_VER
+/***********************************************************************/
+/*
+ * Copyright 1999 by Albert Cahalan; all rights reserved.
+ * This file may be used subject to the terms and conditions of the
+ * GNU Library General Public License Version 2, or any later version
+ * at your option, as published by the Free Software Foundation.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Library General Public License for more details.
+ */
+
+
+#define MEMINFO_FILE "/proc/meminfo"
+#define S(X) ( ((unsigned long long)(X) << 10) >> shift)
+
+#if defined(k64test) || (defined(_ABIN32) && _MIPS_SIM == _ABIN32)
+#define KLONG long long    // not typedef; want "unsigned KLONG" to work
+#else
+#define KLONG long
+#endif
+
+
+static char buf[1024];
+static int meminfo_fd = -1;
+/* This macro opens filename only if necessary and seeks to 0 so
+ * that successive calls to the functions are more efficient.
+ * It also reads the current contents of the file into the global buf.
+ */
+#define FILE_TO_BUF(filename, fd) do{                          \
+    static int local_n;                                                \
+    if (fd == -1 && (fd = open(filename, O_RDONLY)) == -1) {   \
+       fputs(BAD_OPEN_MESSAGE, stderr);                        \
+       fflush(NULL);                                           \
+       _exit(102);                                             \
+    }                                                          \
+    lseek(fd, 0L, SEEK_SET);                                   \
+    if ((local_n = read(fd, buf, sizeof buf - 1)) < 0) {       \
+       perror(filename);                                       \
+       fflush(NULL);                                           \
+       _exit(103);                                             \
+    }                                                          \
+    buf[local_n] = '\0';                                       \
+}while(0)
+
+
+#define BAD_OPEN_MESSAGE                                       \
+"Error: /proc must be mounted\n"                               \
+"  To mount /proc at boot you need an /etc/fstab line like:\n" \
+"      /proc   /proc   proc    defaults\n"                     \
+"  In the meantime, run \"mount /proc /proc -t proc\"\n"
+
+typedef struct mem_table_struct {
+  const char *name;     /* memory type name */
+  unsigned long *slot; /* slot in return struct */
+} mem_table_struct;
+
+static int compare_mem_table_structs(const void *a, const void *b){
+  return strcmp(((const mem_table_struct*)a)->name,((const mem_table_struct*)b)->name);
+}
+
+/* example data, following junk, with comments added:
+ *
+ * MemTotal:        61768 kB    old
+ * MemFree:          1436 kB    old
+ * MemShared:           0 kB    old (now always zero; not calculated)
+ * Buffers:          1312 kB    old
+ * Cached:          20932 kB    old
+ * Active:          12464 kB    new
+ * Inact_dirty:      7772 kB    new
+ * Inact_clean:      2008 kB    new
+ * Inact_target:        0 kB    new
+ * Inact_laundry:       0 kB    new, and might be missing too
+ * HighTotal:           0 kB
+ * HighFree:            0 kB
+ * LowTotal:        61768 kB
+ * LowFree:          1436 kB
+ * SwapTotal:      122580 kB    old
+ * SwapFree:        60352 kB    old
+ * Inactive:        20420 kB    2.5.41+
+ * Dirty:               0 kB    2.5.41+
+ * Writeback:           0 kB    2.5.41+
+ * Mapped:           9792 kB    2.5.41+
+ * Slab:             4564 kB    2.5.41+
+ * Committed_AS:     8440 kB    2.5.41+
+ * PageTables:        304 kB    2.5.41+
+ * ReverseMaps:      5738       2.5.41+
+ * SwapCached:          0 kB    2.5.??+
+ * HugePages_Total:   220       2.5.??+
+ * HugePages_Free:    138       2.5.??+
+ * Hugepagesize:     4096 kB    2.5.??+
+ */
+
+/* obsolete */
+unsigned long kb_main_shared;
+/* old but still kicking -- the important stuff */
+unsigned long kb_main_buffers;
+unsigned long kb_main_cached;
+unsigned long kb_main_free;
+unsigned long kb_main_total;
+unsigned long kb_swap_free;
+unsigned long kb_swap_total;
+/* recently introduced */
+unsigned long kb_high_free;
+unsigned long kb_high_total;
+unsigned long kb_low_free;
+unsigned long kb_low_total;
+/* 2.4.xx era */
+unsigned long kb_active;
+unsigned long kb_inact_laundry;
+unsigned long kb_inact_dirty;
+unsigned long kb_inact_clean;
+unsigned long kb_inact_target;
+unsigned long kb_swap_cached;  /* late 2.4 and 2.6+ only */
+/* derived values */
+unsigned long kb_swap_used;
+unsigned long kb_main_used;
+/* 2.5.41+ */
+unsigned long kb_writeback;
+unsigned long kb_slab;
+unsigned long nr_reversemaps;
+unsigned long kb_committed_as;
+unsigned long kb_dirty;
+unsigned long kb_inactive;
+unsigned long kb_mapped;
+unsigned long kb_pagetables;
+// seen on a 2.6.x kernel:
+static unsigned long kb_vmalloc_chunk;
+static unsigned long kb_vmalloc_total;
+static unsigned long kb_vmalloc_used;
+
+static void meminfo(void){
+  char namebuf[16]; /* big enough to hold any row name */
+  mem_table_struct findme = { namebuf, NULL};
+  mem_table_struct *found;
+  char *head;
+  char *tail;
+  static const mem_table_struct mem_table[] = {
+  {"Active",       &kb_active},       // important
+  {"Buffers",      &kb_main_buffers}, // important
+  {"Cached",       &kb_main_cached},  // important
+  {"Committed_AS", &kb_committed_as},
+  {"Dirty",        &kb_dirty},        // kB version of vmstat nr_dirty
+  {"HighFree",     &kb_high_free},
+  {"HighTotal",    &kb_high_total},
+  {"Inact_clean",  &kb_inact_clean},
+  {"Inact_dirty",  &kb_inact_dirty},
+  {"Inact_laundry",&kb_inact_laundry},
+  {"Inact_target", &kb_inact_target},
+  {"Inactive",     &kb_inactive},     // important
+  {"LowFree",      &kb_low_free},
+  {"LowTotal",     &kb_low_total},
+  {"Mapped",       &kb_mapped},       // kB version of vmstat nr_mapped
+  {"MemFree",      &kb_main_free},    // important
+  {"MemShared",    &kb_main_shared},  // important, but now gone!
+  {"MemTotal",     &kb_main_total},   // important
+  {"PageTables",   &kb_pagetables},   // kB version of vmstat nr_page_table_pages
+  {"ReverseMaps",  &nr_reversemaps},  // same as vmstat nr_page_table_pages
+  {"Slab",         &kb_slab},         // kB version of vmstat nr_slab
+  {"SwapCached",   &kb_swap_cached},
+  {"SwapFree",     &kb_swap_free},    // important
+  {"SwapTotal",    &kb_swap_total},   // important
+  {"VmallocChunk", &kb_vmalloc_chunk},
+  {"VmallocTotal", &kb_vmalloc_total},
+  {"VmallocUsed",  &kb_vmalloc_used},
+  {"Writeback",    &kb_writeback},    // kB version of vmstat nr_writeback
+  };
+  const int mem_table_count = sizeof(mem_table)/sizeof(mem_table_struct);
+
+  FILE_TO_BUF(MEMINFO_FILE,meminfo_fd);
+
+  kb_inactive = ~0UL;
+
+  head = buf;
+  for(;;){
+    tail = strchr(head, ':');
+    if(!tail) break;
+    *tail = '\0';
+    if(strlen(head) >= sizeof(namebuf)){
+      head = tail+1;
+      goto nextline;
+    }
+    strcpy(namebuf,head);
+    found = bsearch(&findme, mem_table, mem_table_count,
+        sizeof(mem_table_struct), compare_mem_table_structs
+    );
+    head = tail+1;
+    if(!found) goto nextline;
+    *(found->slot) = strtoul(head,&tail,10);
+nextline:
+    tail = strchr(head, '\n');
+    if(!tail) break;
+    head = tail+1;
+  }
+  if(!kb_low_total){  /* low==main except with large-memory support */
+    kb_low_total = kb_main_total;
+    kb_low_free  = kb_main_free;
+  }
+  if(kb_inactive==~0UL){
+    kb_inactive = kb_inact_dirty + kb_inact_clean + kb_inact_laundry;
+  }
+  kb_swap_used = kb_swap_total - kb_swap_free;
+  kb_main_used = kb_main_total - kb_main_free;
+}
+/*****************************************************************/
+#endif
+
 char **getDynamicDebugInfo(int *sizeArray)
 {
        char *value=NULL;
@@ -36,6 +259,12 @@ char **getDynamicDebugInfo(int *sizeArray)
        int i,position=0;
        static debug_message dynamicDebug[NB_DEBUG_ELEMENT];
 
+#ifndef _MSC_VER
+       /* Stuff for the function meminfo() */
+    int shift = 10;
+       unsigned KLONG buffers_plus_cached=0;
+#endif
+
 #ifdef _MSC_VER
        *sizeArray = 0;
        return outputDynamicList;
@@ -45,29 +274,75 @@ char **getDynamicDebugInfo(int *sizeArray)
        /* Host info */
        struct utsname name;
 #endif
+       value=(char*)MALLOC(255*sizeof(char));
 
-       /* Memory */
-       long numPages, pageSize, freePages, totalSize, totalFree, totalUsed;
 
-       numPages = sysconf(_SC_PHYS_PAGES)/1024;
-       pageSize = sysconf(_SC_PAGESIZE)/1024;
-       freePages = sysconf( _SC_AVPHYS_PAGES)/1024;
-       totalSize = numPages * pageSize;
-       totalFree = pageSize * freePages;
-       totalUsed = totalSize - totalFree;
-       value=(char*)MALLOC(255*sizeof(char));
-       sprintf(value,"%u MB",totalSize);
-       SetDebugMsg(&dynamicDebug[position],"Total memory",value);
-       position++;
+#ifndef _MSC_VER
+       if (meminfo_fd == -1 && (meminfo_fd = open(MEMINFO_FILE, O_RDONLY)) == -1) {
 
+               sprintf(value,"%u",getfreememory());
+               SetDebugMsg(&dynamicDebug[position],"Total free memory",value);
+               position++;
 
-       sprintf(value,"%u MB",totalFree);
-       SetDebugMsg(&dynamicDebug[position],"Total free memory",value);
-       position++;
+               sprintf(value,"%u",getmemorysize() );
+               SetDebugMsg(&dynamicDebug[position],"Total memory",value);
+               position++;
+       }else{
+               meminfo();
+
+               sprintf(value,"%10Lu",S(kb_main_total));
+               SetDebugMsg(&dynamicDebug[position],"Total memory",value);
+               position++;
+
+
+               sprintf(value,"%10Lu",S(kb_main_used));
+               SetDebugMsg(&dynamicDebug[position],"Used memory",value);
+               position++;
+
+               sprintf(value,"%10Lu",S(kb_main_free));
+               SetDebugMsg(&dynamicDebug[position],"Free memory",value);
+               position++;
+
+               sprintf(value,"%10Lu",S(kb_main_shared));
+               SetDebugMsg(&dynamicDebug[position],"Shared memory",value);
+               position++;
+
+               sprintf(value,"%10Lu",S(kb_main_buffers));
+               SetDebugMsg(&dynamicDebug[position],"Buffers memory",value);
+               position++;
+
+               sprintf(value,"%10Lu",S(kb_main_cached));
+               SetDebugMsg(&dynamicDebug[position],"Cached memory",value);
+               position++;
+
+               buffers_plus_cached = kb_main_buffers + kb_main_cached;
+
+
+               sprintf(value,"%10Lu",S(kb_main_used - buffers_plus_cached));
+               SetDebugMsg(&dynamicDebug[position],"Used -/+ buffers/cache",value);
+               position++;
+
+
+               sprintf(value,"%10Lu",S(kb_main_free + buffers_plus_cached));
+               SetDebugMsg(&dynamicDebug[position],"Free -/+ buffers/cache",value);
+               position++;
+
+               sprintf(value,"%10Lu",S(kb_swap_total));
+               SetDebugMsg(&dynamicDebug[position],"Total swap",value);
+               position++;
+
+               sprintf(value,"%10Lu",S(kb_swap_used));
+               SetDebugMsg(&dynamicDebug[position],"Used swap",value);
+               position++;
+
+               sprintf(value,"%10Lu",S(kb_swap_free));
+               SetDebugMsg(&dynamicDebug[position],"Free swap",value);
+               position++;
+
+       }
+
+#endif
 
-       sprintf(value,"%u MB",totalUsed );
-       SetDebugMsg(&dynamicDebug[position],"Total used memory",value);
-       position++;
 #ifdef HAVE_UNAME
        if (uname(&name) < 0) {
                sprintf(value, "Unknown OS version (uname failed - %s)", strerror(errno));
@@ -107,3 +382,6 @@ char **getDynamicDebugInfo(int *sizeArray)
        return outputDynamicList;
 #endif
 }
+
+
+
index 7147d9f..9a48318 100644 (file)
@@ -6,6 +6,9 @@
 @sa http://nixdoc.net/man-pages/Tru64/man2/getsysinfo.2.html
 @sa http://www.opensource.apple.com/darwinsource/projects/other/gccfast-1621.1/libiberty/physmem.c
 @sa http://lists.gnu.org/archive/html/bug-gnulib/2003-08/msg00102.html
+* @TODO (Sylvestre Ledru)
+* This file needs some work because the Linux Kernel is caching many memory
+* therefor, the free memory value is pretty wrong
 */
 #include "getmemory.h"
 
index 2a4652a..f3b70d6 100644 (file)
                #include <tk.h>
        #endif
 #endif
+
+#ifdef WITH_PVM
+#include <pvm.h>
+#endif 
+
+#ifdef WITH_UMFPACK
+#ifdef UMFPACK_SUITESPARSE
+#include <suitesparse/umfpack.h>
+#else
+#include <umfpack.h>
+#endif
+#endif
+
 #include "MALLOC.h"
 #include "getstaticdebuginfo.h"
 
@@ -71,6 +84,9 @@ char **getStaticDebugInfo(int *sizeArray)
 #endif
 #ifdef WITH_PVM
                {"PVM","Enable"},
+#ifdef PVM_VER
+               {"PVM version",PVM_VER},
+#endif
 #endif 
 #ifdef PATH_SEPARATOR
                {"Path separator",PATH_SEPARATOR},
@@ -78,6 +94,12 @@ char **getStaticDebugInfo(int *sizeArray)
 #ifdef DIR_SEPARATOR
                {"Directory separator",DIR_SEPARATOR},
 #endif
+#ifdef WITH_UMFPACK
+               {"UMFPACK","Enable"},
+#ifdef UMFPACK_VERSION
+               {"UMFPACK version",UMFPACK_VERSION},
+#endif
+#endif
        };
 
        for (i=0; i<NB_DEBUG_ELEMENT; i++){