Merge pull request #261 from joncham/bug-null-interface-bitset
[mono.git] / mono / metadata / mono-perfcounters.c
index 48b666df947c598a56bf65728a684c2c9178e57a..dfe7b4b4d3dc837f4c5fbc35061e66931203128e 100644 (file)
@@ -6,15 +6,28 @@
  * Author: Paolo Molaro (lupus@ximian.com)
  *
  * Copyright 2008-2009 Novell, Inc (http://www.novell.com)
+ * 2011 Xamarin, Inc
  */
 
 #include "config.h"
 #include <time.h>
 #include <string.h>
 #include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#if defined (__OpenBSD__)
+#include <sys/param.h>
+#endif
+#ifdef HAVE_SYS_TYPES_H
+#include <sys/types.h>
+#endif
 #ifdef HAVE_SYS_TIME_H
 #include <sys/time.h>
 #endif
+#if defined (__NetBSD__) || defined (__APPLE__)
+#include <sys/sysctl.h>
+#endif
 #include "metadata/mono-perfcounters.h"
 #include "metadata/appdomain.h"
 #include "metadata/object-internals.h"
@@ -380,6 +393,60 @@ predef_cleanup (ImplVtable *vtable)
        perfctr_unlock ();
 }
 
+static guint64
+mono_determine_physical_ram_size (void)
+{
+#if defined (TARGET_WIN32)
+       MEMORYSTATUSEX memstat;
+
+       memstat.dwLength = sizeof (memstat);
+       GlobalMemoryStatusEx (&memstat);
+       return (guint64)memstat.ullTotalPhys;
+#elif defined (__NetBSD__) || defined (__APPLE__)
+#ifdef __NetBSD__
+       unsigned long value;
+#else
+       guint64 value;
+#endif
+       int mib[2] = {
+               CTL_HW,
+#ifdef __NetBSD__
+               HW_PHYSMEM
+#else
+               HW_MEMSIZE
+#endif
+       };
+       size_t size_sys = sizeof (value);
+
+       sysctl (mib, 2, &value, &size_sys, NULL, 0);
+       if (value == 0)
+               return 134217728;
+
+       return (guint64)value;
+#elif defined (HAVE_SYSCONF)
+       guint64 page_size = 0, num_pages = 0;
+
+       /* sysconf works on most *NIX operating systems, if your system doesn't have it or if it
+        * reports invalid values, please add your OS specific code below. */
+#ifdef _SC_PAGESIZE
+       page_size = (guint64)sysconf (_SC_PAGESIZE);
+#endif
+
+#ifdef _SC_PHYS_PAGES
+       num_pages = (guint64)sysconf (_SC_PHYS_PAGES);
+#endif
+
+       if (!page_size || !num_pages) {
+               g_warning ("Your operating system's sysconf (3) function doesn't correctly report physical memory size!");
+               return 134217728;
+       }
+
+       return page_size * num_pages;
+#else
+       return 134217728;
+#endif
+}
+
 void
 mono_perfcounters_init (void)
 {
@@ -829,6 +896,9 @@ mono_mem_counter (ImplVtable *vtable, MonoBoolean only_value, MonoCounterSample
        case COUNTER_MEM_NUM_OBJECTS:
                sample->rawValue = mono_stats.new_object_count;
                return TRUE;
+       case COUNTER_MEM_PHYS_TOTAL:
+               sample->rawValue = mono_determine_physical_ram_size ();;
+               return TRUE;
        }
        return FALSE;
 }
@@ -929,6 +999,31 @@ predef_writable_counter (ImplVtable *vtable, MonoBoolean only_value, MonoCounter
                case COUNTER_THREADPOOL_IOWORKITEMS:
                        sample->rawValue = mono_perfcounters->threadpool_ioworkitems;
                        return TRUE;
+               case COUNTER_THREADPOOL_THREADS:
+                       sample->rawValue = mono_perfcounters->threadpool_threads;
+                       return TRUE;
+               case COUNTER_THREADPOOL_IOTHREADS:
+                       sample->rawValue = mono_perfcounters->threadpool_iothreads;
+                       return TRUE;
+               }
+               break;
+       case CATEGORY_JIT:
+               switch (id) {
+               case COUNTER_JIT_BYTES:
+                       sample->rawValue = mono_perfcounters->jit_bytes;
+                       return TRUE;
+               case COUNTER_JIT_METHODS:
+                       sample->rawValue = mono_perfcounters->jit_methods;
+                       return TRUE;
+               case COUNTER_JIT_TIME:
+                       sample->rawValue = mono_perfcounters->jit_time;
+                       return TRUE;
+               case COUNTER_JIT_BYTES_PSEC:
+                       sample->rawValue = mono_perfcounters->jit_bytes;
+                       return TRUE;
+               case COUNTER_JIT_FAILURES:
+                       sample->rawValue = mono_perfcounters->jit_failures;
+                       return TRUE;
                }
                break;
        }
@@ -954,6 +1049,8 @@ predef_writable_update (ImplVtable *vtable, MonoBoolean do_incr, gint64 value)
                switch (id) {
                case COUNTER_THREADPOOL_WORKITEMS: ptr64 = (gint64 *) &mono_perfcounters->threadpool_workitems; break;
                case COUNTER_THREADPOOL_IOWORKITEMS: ptr64 = (gint64 *) &mono_perfcounters->threadpool_ioworkitems; break;
+               case COUNTER_THREADPOOL_THREADS: ptr = &mono_perfcounters->threadpool_threads; break;
+               case COUNTER_THREADPOOL_IOTHREADS: ptr = &mono_perfcounters->threadpool_iothreads; break;
                }
                break;
        }