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
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