* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*/
-#include "ao.h"
+#include <ao.h>
#define AO_NO_TASK_INDEX 0xff
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
{
ao_arch_isr_stack();
+#if AO_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
*/
{
- __pdata uint8_t ao_next_task_index = ao_cur_task_index;
+ __pdata uint8_t ao_last_task_index = ao_cur_task_index;
for (;;) {
- ++ao_next_task_index;
- if (ao_next_task_index == ao_num_tasks)
- ao_next_task_index = 0;
+ ++ao_cur_task_index;
+ if (ao_cur_task_index == ao_num_tasks)
+ ao_cur_task_index = 0;
+
+ ao_cur_task = ao_tasks[ao_cur_task_index];
- ao_cur_task = ao_tasks[ao_next_task_index];
- if (ao_cur_task->wchan == NULL) {
- ao_cur_task_index = ao_next_task_index;
+ /* Check for ready task */
+ if (ao_cur_task->wchan == NULL)
break;
- }
/* Check if the alarm is set for a time which has passed */
if (ao_cur_task->alarm &&
- (int16_t) (ao_time() - ao_cur_task->alarm) >= 0) {
- ao_cur_task_index = ao_next_task_index;
+ (int16_t) (ao_time() - ao_cur_task->alarm) >= 0)
break;
- }
/* Enter lower power mode when there isn't anything to do */
- if (ao_next_task_index == ao_cur_task_index) {
+ if (ao_cur_task_index == ao_last_task_index)
ao_arch_cpu_idle();
- }
}
}
+#if AO_CHECK_STACK
+ cli();
+ in_yield = 0;
+#endif
ao_arch_restore_stack();
}
ao_yield();
if (ao_cur_task->wchan) {
ao_cur_task->wchan = NULL;
+ ao_cur_task->alarm = 0;
return 1;
}
return 0;
{
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;
ao_cur_task->alarm = 0;
}
+static __xdata uint8_t ao_forever;
+
+void
+ao_delay(uint16_t ticks)
+{
+ ao_alarm(ticks);
+ ao_sleep(&ao_forever);
+ ao_clear_alarm();
+}
+
void
ao_exit(void)
{
void
ao_task_info(void)
{
- uint8_t i;
+ uint8_t i;
__xdata struct ao_task *task;
for (i = 0; i < ao_num_tasks; i++) {