altos: Avoid modulus in task queue on parts without idiv
authorKeith Packard <keithp@keithp.com>
Sun, 13 Nov 2022 06:47:00 +0000 (22:47 -0800)
committerKeith Packard <keithp@keithp.com>
Sun, 13 Nov 2022 08:17:32 +0000 (00:17 -0800)
Cortex-M0 parts don't have a hardware divide, so doing a modulus
to compute task hash indexes is super slow. Avoid that by making the sleep
queue a power of two.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/kernel/ao_task.c

index dd278bde064740f3ed0ac1a6ef11d90ccb85ab7c..b50454167b67d70fdcea806f75ac3a21afb74b9d 100644 (file)
@@ -57,7 +57,17 @@ static inline void ao_check_stack(void) {
 #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;
@@ -75,7 +85,7 @@ _ao_task_to_run_queue(struct ao_task *task)
 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