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