#endif
#ifndef SLEEP_HASH_SIZE
+#ifdef __ARM_FEATURE_IDIV__
#define SLEEP_HASH_SIZE 17
+#else
+#define SLEEP_HASH_SIZE 16
+#endif
+#endif
+
+#if SLEEP_HASH_SIZE & (SLEEP_HASH_SIZE - 1)
+#define SLEEP_HASH_SHIFT 0
+#else
+#define SLEEP_HASH_SHIFT 2
#endif
static struct ao_list run_queue;
static struct ao_list *
ao_task_sleep_queue(void *wchan)
{
- return &ao_sleep_queue[(uintptr_t) wchan % SLEEP_HASH_SIZE];
+ return &ao_sleep_queue[(((uintptr_t) wchan) >> SLEEP_HASH_SHIFT) % SLEEP_HASH_SIZE];
}
static void
#endif
}
+#define AO_STACK_CANARY_VALUE 0xbaadf00dU
+
void
ao_add_task(struct ao_task * task, void (*task_func)(void), const char *name)
{
task->task_id = task_id;
task->name = name;
task->wchan = NULL;
+#ifdef AO_STACK_CANARY
+ task->bottom_canary = AO_STACK_CANARY_VALUE;
+ task->top_canary = AO_STACK_CANARY_VALUE;
+#endif
/*
* Construct a stack frame so that it will 'return'
* to the start of the task
);
}
+#ifdef AO_STACK_CANARY
+static void
+ao_check_stack_canary(void)
+{
+ if (ao_cur_task->bottom_canary != AO_STACK_CANARY_VALUE)
+ ao_panic(AO_PANIC_STACK);
+ if (ao_cur_task->top_canary != AO_STACK_CANARY_VALUE)
+ ao_panic(AO_PANIC_STACK);
+}
+#else
+#define ao_check_stack_canary()
+#endif
+
uint8_t ao_task_minimize_latency;
/* Task switching function. */
ao_cur_task->max_run = run;
++ao_cur_task->yields;
#endif
+ ao_check_stack_canary();
ao_arch_save_regs();
ao_arch_save_stack();
}
#if USE_TLS
_set_tls(ao_stack_top(ao_cur_task));
#endif
+ ao_check_stack_canary();
ao_arch_restore_stack();
}