+
+static void
+kdp_mem_and_io_snapshot(struct mem_and_io_snapshot *memio_snap)
+{
+ unsigned int pages_reclaimed;
+ unsigned int pages_wanted;
+ kern_return_t kErr;
+
+ memio_snap->snapshot_magic = STACKSHOT_MEM_AND_IO_SNAPSHOT_MAGIC;
+ memio_snap->free_pages = vm_page_free_count;
+ memio_snap->active_pages = vm_page_active_count;
+ memio_snap->inactive_pages = vm_page_inactive_count;
+ memio_snap->purgeable_pages = vm_page_purgeable_count;
+ memio_snap->wired_pages = vm_page_wire_count;
+ memio_snap->speculative_pages = vm_page_speculative_count;
+ memio_snap->throttled_pages = vm_page_throttled_count;
+ memio_snap->busy_buffer_count = count_busy_buffers();
+ kErr = mach_vm_pressure_monitor(FALSE, VM_PRESSURE_TIME_WINDOW, &pages_reclaimed, &pages_wanted);
+ if ( ! kErr ) {
+ memio_snap->pages_wanted = (uint32_t)pages_wanted;
+ memio_snap->pages_reclaimed = (uint32_t)pages_reclaimed;
+ memio_snap->pages_wanted_reclaimed_valid = 1;
+ } else {
+ memio_snap->pages_wanted = 0;
+ memio_snap->pages_reclaimed = 0;
+ memio_snap->pages_wanted_reclaimed_valid = 0;
+ }
+}
+
+
+
+/*
+ * Method for grabbing timer values safely, in the sense that no infinite loop will occur
+ * Certain flavors of the timer_grab function, which would seem to be the thing to use,
+ * can loop infinitely if called while the timer is in the process of being updated.
+ * Unfortunately, it is (rarely) possible to get inconsistent top and bottom halves of
+ * the timer using this method. This seems insoluble, since stackshot runs in a context
+ * where the timer might be half-updated, and has no way of yielding control just long
+ * enough to finish the update.
+ */
+
+static uint64_t safe_grab_timer_value(struct timer *t)
+{
+#if defined(__LP64__)
+ return t->all_bits;
+#else
+ uint64_t time = t->high_bits; /* endian independent grab */
+ time = (time << 32) | t->low_bits;
+ return time;
+#endif
+}
+