monitor.c

Go to the documentation of this file.
00001 
00041 #include "monitor.h"
00042 
00043 #if CONFIG_KERN_MONITOR
00044 
00045 #include "proc_p.h"
00046 #include <mware/list.h>
00047 #include <drv/timer.h>
00048 #include <kern/proc.h>
00049 #include <cfg/macros.h>
00050 #include <cfg/debug.h>
00051 
00052 
00053 static List MonitorProcs;
00054 
00055 
00056 void monitor_init(void)
00057 {
00058     LIST_INIT(&MonitorProcs);
00059 }
00060 
00061 
00062 void monitor_add(Process* proc, const char* name, cpustack_t* stack_base, size_t stack_size)
00063 {
00064     proc->monitor.name = name;
00065     proc->monitor.stack_base = stack_base;
00066     proc->monitor.stack_size = stack_size;
00067 
00068     ADDTAIL(&MonitorProcs, &proc->monitor.link);
00069 }
00070 
00071 
00072 void monitor_remove(Process* proc)
00073 {
00074     REMOVE(&proc->monitor.link);
00075 }
00076 
00077 void monitor_rename(Process *proc, const char* name)
00078 {
00079     proc->monitor.name = name;
00080 }
00081 
00082 /* TODO: use containerof() */
00083 #define MONITOR_NODE_TO_PROCESS(node) \
00084     (struct Process *)((intptr_t)(node) - offsetof(struct Process, monitor.link))
00085 
00086 size_t monitor_checkStack(cpustack_t* stack_base, size_t stack_size)
00087 {
00088     cpustack_t* beg;
00089     cpustack_t* cur;
00090     cpustack_t* end;
00091     size_t sp_free;
00092 
00093     beg = stack_base;
00094     end = stack_base + stack_size / sizeof(cpustack_t) - 1;
00095 
00096     if (CPU_STACK_GROWS_UPWARD)
00097     {
00098         cur = beg;
00099         beg = end;
00100         end = cur;
00101     }
00102 
00103     cur = beg;
00104     while (cur != end)
00105     {
00106         if (*cur != CONFIG_KERN_STACKFILLCODE)
00107             break;
00108 
00109         if (CPU_STACK_GROWS_UPWARD)
00110             cur--;
00111         else
00112             cur++;
00113     }
00114 
00115     sp_free = ABS(cur - beg) * sizeof(cpustack_t);
00116     return sp_free;
00117 }
00118 
00119 
00120 void monitor_report(void)
00121 {
00122     struct Process* p;
00123     int i;
00124 
00125     if (LIST_EMPTY(&MonitorProcs))
00126     {
00127         kputs("No stacks registered in the monitor\n");
00128         return;
00129     }
00130 
00131     kprintf("%-24s%-8s%-8s%-8s%-8s\n", "Process name", "TCB", "SPbase", "SPsize", "SPfree");
00132     for (i=0;i<56;i++)
00133         kputchar('-');
00134     kputchar('\n');
00135 
00136     for (p = MONITOR_NODE_TO_PROCESS(LIST_HEAD(&MonitorProcs));
00137          p->monitor.link.succ;
00138          p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ))
00139     {
00140         size_t free = monitor_checkStack(p->monitor.stack_base, p->monitor.stack_size);
00141         kprintf("%-24s%-8p%-8p%-8lu%-8lu\n",
00142             p->monitor.name, p, p->monitor.stack_base, p->monitor.stack_size, free);
00143     }
00144 }
00145 
00146 
00147 static void NORETURN monitor(void)
00148 {
00149     struct Process *p;
00150 
00151     while (1)
00152     {
00153         for (p = MONITOR_NODE_TO_PROCESS(LIST_HEAD(&MonitorProcs));
00154             p->monitor.link.succ;
00155             p = MONITOR_NODE_TO_PROCESS(p->monitor.link.succ))
00156         {
00157             size_t free = monitor_checkStack(p->monitor.stack_base, p->monitor.stack_size);
00158 
00159             if (free < 0x20)
00160                 kprintf("MONITOR: WARNING: Free stack for process '%s' is only %u chars\n",
00161                         p->monitor.name, (unsigned int)free);
00162 
00163             timer_delay(500);
00164         }
00165     }
00166 }
00167 
00168 
00169 void monitor_start(size_t stacksize, cpustack_t *stack)
00170 {
00171     proc_new(monitor, NULL, stacksize, stack);
00172 }
00173 
00174 #endif /* CONFIG_KERN_MONITOR */