BeRTOS
|
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 */