os161-1.99
 All Data Structures
uw-vmstats.c
00001 /* UW specific code - This won't be needed or used until assignment 3 */
00002 
00003 /* belongs in kern/vm/uw-vmstats.c */
00004 
00005 /* NOTE !!!!!! WARNING !!!!!
00006  * All of the functions whose names begin with '_'
00007  * assume that atomicity is ensured elsewhere
00008  * (i.e., outside of these routines) by acquiring stats_lock.
00009  * All of the functions whose names do not begin
00010  * with '_' ensure atomicity locally.
00011  */
00012 
00013 #include <types.h>
00014 #include <lib.h>
00015 #include <synch.h>
00016 #include <spl.h>
00017 #include <uw-vmstats.h>
00018 
00019 /* Counters for tracking statistics */
00020 static unsigned int stats_counts[VMSTAT_COUNT];
00021 
00022 struct spinlock stats_lock = SPINLOCK_INITIALIZER;
00023 
00024 /* Strings used in printing out the statistics */
00025 static const char *stats_names[] = {
00026  /*  0 */ "TLB Faults", 
00027  /*  1 */ "TLB Faults with Free",
00028  /*  2 */ "TLB Faults with Replace",
00029  /*  3 */ "TLB Invalidations",
00030  /*  4 */ "TLB Reloads",
00031  /*  5 */ "Page Faults (Zeroed)",
00032  /*  6 */ "Page Faults (Disk)",
00033  /*  7 */ "Page Faults from ELF",
00034  /*  8 */ "Page Faults from Swapfile",
00035  /*  9 */ "Swapfile Writes",
00036 };
00037 
00038 
00039 /* ---------------------------------------------------------------------- */
00040 /* Assumes vmstat_init has already been called */
00041 void
00042 vmstats_inc(unsigned int index)
00043 {
00044     spinlock_acquire(&stats_lock);
00045       _vmstats_inc(index);
00046     spinlock_release(&stats_lock);
00047 }
00048 
00049 /* ---------------------------------------------------------------------- */
00050 void
00051 vmstats_init(void)
00052 {
00053   /* Although the spinlock is initialized at declaration time we do it here
00054    * again in case we want use/reset these stats repeatedly without shutting down the kernel.
00055    */
00056   spinlock_init(&stats_lock);
00057 
00058   spinlock_acquire(&stats_lock);
00059     _vmstats_init();
00060   spinlock_release(&stats_lock);
00061 }
00062 
00063 /* ---------------------------------------------------------------------- */
00064 void
00065 _vmstats_inc(unsigned int index)
00066 {
00067   KASSERT(index < VMSTAT_COUNT);
00068   stats_counts[index]++;
00069 }
00070 
00071 /* ---------------------------------------------------------------------- */
00072 void
00073 _vmstats_init(void)
00074 {
00075   int i = 0;
00076 
00077   if (sizeof(stats_names) / sizeof(char *) != VMSTAT_COUNT) {
00078     kprintf("vmstats_init: number of stats_names = %d != VMSTAT_COUNT = %d\n",
00079       (sizeof(stats_names) / sizeof(char *)), VMSTAT_COUNT);
00080     panic("Should really fix this before proceeding\n");
00081   }
00082 
00083   for (i=0; i<VMSTAT_COUNT; i++) {
00084     stats_counts[i] = 0;
00085   }
00086 
00087 }
00088 
00089 /* ---------------------------------------------------------------------- */
00090 /* Assumes vmstat_init has already been called */
00091 /* NOTE: We do not grab the spinlock here because kprintf may block
00092  * and we can't block while holding a spinlock.
00093  * Just use this when there is only one thread remaining.
00094  */
00095 
00096 void
00097 vmstats_print(void)
00098 {
00099   int i = 0;
00100   int free_plus_replace = 0;
00101   int disk_plus_zeroed_plus_reload = 0;
00102   int tlb_faults = 0;
00103   int elf_plus_swap_reads = 0;
00104   int disk_reads = 0;
00105 
00106   kprintf("VMSTATS:\n");
00107   for (i=0; i<VMSTAT_COUNT; i++) {
00108     kprintf("VMSTAT %25s = %10d\n", stats_names[i], stats_counts[i]);
00109   }
00110 
00111   tlb_faults = stats_counts[VMSTAT_TLB_FAULT];
00112   free_plus_replace = stats_counts[VMSTAT_TLB_FAULT_FREE] + stats_counts[VMSTAT_TLB_FAULT_REPLACE];
00113   disk_plus_zeroed_plus_reload = stats_counts[VMSTAT_PAGE_FAULT_DISK] +
00114     stats_counts[VMSTAT_PAGE_FAULT_ZERO] + stats_counts[VMSTAT_TLB_RELOAD];
00115   elf_plus_swap_reads = stats_counts[VMSTAT_ELF_FILE_READ] + stats_counts[VMSTAT_SWAP_FILE_READ];
00116   disk_reads = stats_counts[VMSTAT_PAGE_FAULT_DISK];
00117 
00118   kprintf("VMSTAT TLB Faults with Free + TLB Faults with Replace = %d\n", free_plus_replace);
00119   if (tlb_faults != free_plus_replace) {
00120     kprintf("WARNING: TLB Faults (%d) != TLB Faults with Free + TLB Faults with Replace (%d)\n",
00121       tlb_faults, free_plus_replace); 
00122   }
00123 
00124   kprintf("VMSTAT TLB Reloads + Page Faults (Zeroed) + Page Faults (Disk) = %d\n",
00125     disk_plus_zeroed_plus_reload);
00126   if (tlb_faults != disk_plus_zeroed_plus_reload) {
00127     kprintf("WARNING: TLB Faults (%d) != TLB Reloads + Page Faults (Zeroed) + Page Faults (Disk) (%d)\n",
00128       tlb_faults, disk_plus_zeroed_plus_reload); 
00129   }
00130 
00131   kprintf("VMSTAT ELF File reads + Swapfile reads = %d\n", elf_plus_swap_reads);
00132   if (disk_reads != elf_plus_swap_reads) {
00133     kprintf("WARNING: ELF File reads + Swapfile reads != Page Faults (Disk) %d\n",
00134       elf_plus_swap_reads);
00135   }
00136 }
00137 /* ---------------------------------------------------------------------- */
 All Data Structures