diff options
| author | Keith Packard <keithp@keithp.com> | 2012-06-26 23:21:04 -0700 | 
|---|---|---|
| committer | Keith Packard <keithp@keithp.com> | 2012-06-26 23:21:04 -0700 | 
| commit | 8efac8eb99a9aabb45d9fbf742e4be91e4b331a5 (patch) | |
| tree | 079ddc84f0c7e9a47fd71ee35436e6285726c246 /src/core | |
| parent | ebeac02a990da3fa6dd71487141d0bc6f78b42de (diff) | |
altos: Add debugging code to check for stack overflow
Stack overflow often happens from interrupt handlers sitting on top of
a task stack. Check for this during ao_wakeup as that is often called
during interrupt processing.
Signed-off-by: Keith Packard <keithp@keithp.com>
Diffstat (limited to 'src/core')
| -rw-r--r-- | src/core/ao_task.c | 24 | 
1 files changed, 23 insertions, 1 deletions
diff --git a/src/core/ao_task.c b/src/core/ao_task.c index 910f1587..4011a36e 100644 --- a/src/core/ao_task.c +++ b/src/core/ao_task.c @@ -15,7 +15,7 @@   * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.   */ -#include "ao.h" +#include <ao.h>  #define AO_NO_TASK_INDEX	0xff @@ -28,6 +28,20 @@ __xdata struct ao_task *__data ao_cur_task;  ao_arch_task_globals  #endif +#define AO_CHECK_STACK	0 + +#if AO_CHECK_STACK +static uint8_t	in_yield; + +static inline void ao_check_stack(void) { +	uint8_t	q; +	if (!in_yield && ao_cur_task && &q < &ao_cur_task->stack[0]) +		ao_panic(AO_PANIC_STACK); +} +#else +#define ao_check_stack() +#endif +  void  ao_add_task(__xdata struct ao_task * task, void (*start)(void), __code char *name) __reentrant  { @@ -68,6 +82,9 @@ ao_yield(void) ao_arch_naked_define  	ao_arch_isr_stack(); +#if CHECK_STACK +	in_yield = 1; +#endif  	/* Find a task to run. If there isn't any runnable task,  	 * this loop will run forever, which is just fine  	 */ @@ -97,6 +114,10 @@ ao_yield(void) ao_arch_naked_define  			}  		}  	} +#if CHECK_STACK +	cli(); +	in_yield = 0; +#endif  	ao_arch_restore_stack();  } @@ -117,6 +138,7 @@ ao_wakeup(__xdata void *wchan)  {  	uint8_t	i; +	ao_check_stack();  	for (i = 0; i < ao_num_tasks; i++)  		if (ao_tasks[i]->wchan == wchan)  			ao_tasks[i]->wchan = NULL;  | 
