monitor.c

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