pike.git / src / builtin_functions.c

version» Context lines:

pike.git/src/builtin_functions.c:7435:    */   PMOD_EXPORT void f__memory_usage(INT32 args)   {    size_t num,size;    struct svalue *ss;   #ifdef USE_DL_MALLOC    struct mallinfo mi = dlmallinfo();   #elif HAVE_MALLINFO    struct mallinfo mi = mallinfo();   #endif +     pop_n_elems(args);    ss=Pike_sp;       /* TODO: If USE_DL_MALLOC is defined then this will report the    * statistics from our bundled Doug Lea malloc, and not the    * underlying system malloc. Ideally we should include both. */      #if defined(HAVE_MALLINFO) || defined(USE_DL_MALLOC)       push_text("num_malloc_blocks");    push_ulongest(1 + mi.hblks); /* 1 for the arena. */    push_text("malloc_block_bytes"); -  +  if (mi.arena < 0) { +  /* Kludge for broken Linux libc, where the fields are ints. +  * +  * 31-bit overflow, so perform an unsigned read. +  */ +  size = (unsigned int)mi.arena; +  } else { +  /* On Solaris the fields are unsigned long (and may thus be 64-bit). */ +  size = mi.arena; +  }    /* NB: Kludge for glibc: hblkhd is intended for malloc overhead    * according to the Solaris manpages, but glibc keeps the    * amount of mmapped memory there, and uses the arena only    * for the amount from sbrk.    *    * The hblkhd value on proper implementations should be    * small enough not to affect the total much, so no need    * for a special case.    */ -  push_ulongest(mi.arena + mi.hblkhd); +  if (mi.hblkhd < 0) { +  size += (unsigned int)mi.hblkhd; +  } else { +  size += mi.hblkhd; +  } +  push_ulongest(size);       push_text("num_malloc");    push_ulongest(mi.ordblks + mi.smblks);    push_text("malloc_bytes"); -  if (!mi.smblks) { -  /* NB: Kludge for dlmalloc: usmblks contains the max uordblks value. */ -  push_ulongest(mi.uordblks); +  if (mi.uordblks < 0) { +  size = (unsigned int)mi.uordblks;    } else { -  push_ulongest(mi.usmblks + mi.uordblks); +  size = mi.uordblks;    } -  +  if (mi.smblks) { +  /* NB: Not dlmalloc where usmblks contains the max uordblks value. */ +  if (mi.usmblks < 0) { +  size += (unsigned int)mi.usmblks; +  } else { +  size += mi.usmblks; +  } +  } +  push_ulongest(size);       push_text("num_free_blocks");    push_int(1);    push_text("free_block_bytes"); -  push_ulongest(mi.fsmblks + mi.fordblks); +  if (mi.fsmblks < 0) { +  size = (unsigned int)mi.fsmblks; +  } else { +  size = mi.fsmblks; +  } +  if (mi.fordblks < 0) { +  size += (unsigned int)mi.fordblks; +  } else { +  size += mi.fordblks; +  } +  push_ulongest(size);      #endif      #define COUNT(TYPE) do { \    PIKE_CONCAT3(count_memory_in_, TYPE, s)(&num, &size); \    push_text("num_" #TYPE "s"); \    push_ulongest(num); \    push_text(#TYPE "_bytes"); \    push_ulongest(size); \    } while(0)