altos: eliminate ao_wake_task
authorKeith Packard <keithp@keithp.com>
Sat, 27 Nov 2010 01:39:40 +0000 (17:39 -0800)
committerKeith Packard <keithp@keithp.com>
Thu, 23 Dec 2010 04:39:40 +0000 (20:39 -0800)
Waking up a task waiting on some random object is a bad idea. Fix
the waiters to look for suitable signalling.

Signed-off-by: Keith Packard <keithp@keithp.com>
src/ao.h
src/ao_packet.c
src/ao_packet_master.c
src/ao_packet_slave.c
src/ao_radio.c
src/ao_task.c

index 58659af578416754a95bc99872959405eb796352..9682e42fb33c9cde8d69122f632acd0f969ecb81 100644 (file)
--- a/src/ao.h
+++ b/src/ao.h
@@ -69,10 +69,6 @@ ao_sleep(__xdata void *wchan);
 void
 ao_wakeup(__xdata void *wchan);
 
-/* Wake up a specific task */
-void
-ao_wake_task(__xdata struct ao_task *task);
-
 /* set an alarm to go off in 'delay' ticks */
 void
 ao_alarm(uint16_t delay);
index 9896149cbff480efe10c67d5e3846c670554fe14..f627e02b4022ee8004fd5400a4eb20d0d0ed60d8 100644 (file)
@@ -117,7 +117,7 @@ ao_packet_flush(void)
         * then poke the master to send all queued data
         */
        if (ao_packet_tx_used && ao_packet_master_sleeping)
-               ao_wake_task(&ao_packet_task);
+               ao_wakeup(&ao_packet_master_sleeping);
 }
 #endif /* PACKET_HAS_MASTER */
 
index 3b23ad92c882396f543a169c02053dbe1b7afcd7..0808bc80af419c68efbfa4f8869eb8526bef634a 100644 (file)
@@ -21,16 +21,13 @@ static char
 ao_packet_getchar(void) __critical
 {
        char c;
-       while ((c = ao_packet_pollchar()) == AO_READ_AGAIN)
-       {
+       while ((c = ao_packet_pollchar()) == AO_READ_AGAIN) {
                if (!ao_packet_enable)
                        break;
                if (ao_packet_master_sleeping)
-                       ao_wake_task(&ao_packet_task);
+                       ao_wakeup(&ao_packet_master_sleeping);
                ao_usb_flush();
                ao_sleep(&ao_stdin_ready);
-               if (!ao_packet_enable)
-                       break;
        }
        return c;
 }
@@ -41,7 +38,7 @@ ao_packet_echo(void) __reentrant
        uint8_t c;
        while (ao_packet_enable) {
                c = ao_packet_getchar();
-               if (ao_packet_enable)
+               if (c != AO_READ_AGAIN)
                        ao_usb_putchar(c);
        }
        ao_exit();
@@ -97,7 +94,8 @@ ao_packet_master(void)
                        if (ao_rx_packet.packet.len)
                                ao_packet_master_busy();
                        ao_packet_master_sleeping = 1;
-                       ao_delay(ao_packet_master_delay);
+                       ao_alarm(ao_packet_master_delay);
+                       ao_sleep(&ao_packet_master_sleeping);
                        ao_packet_master_sleeping = 0;
                }
        }
@@ -126,8 +124,8 @@ ao_packet_forward(void) __reentrant
                ao_delay(AO_MS_TO_TICKS(100));
        ao_packet_enable = 0;
        while (ao_packet_echo_task.wchan || ao_packet_task.wchan) {
-               if (ao_packet_echo_task.wchan)
-                       ao_wake_task(&ao_packet_echo_task);
+               ao_radio_recv_abort();
+               ao_wakeup(&ao_stdin_ready);
                ao_delay(AO_MS_TO_TICKS(10));
        }
 }
index 3040d781091fd88c0956f6258879938ec3dcbb4b..39d04bbb2e8a70ca43450b9a7457f8991a1198b9 100644 (file)
@@ -44,12 +44,13 @@ ao_packet_slave_stop(void)
 {
        if (ao_packet_enable) {
                ao_packet_enable = 0;
-               ao_radio_recv_abort();
                while (ao_packet_task.wchan) {
-                       ao_wake_task(&ao_packet_task);
-                       ao_yield();
+                       ao_radio_recv_abort();
+                       ao_delay(AO_MS_TO_TICKS(10));
                }
+               ao_radio_get();
                ao_radio_set_telemetry();
+               ao_radio_put();
        }
 }
 
index 362b73aa3053c67452ace38ce15fa879aed4d0bb..7b7c5161fb0ac95c2d730f7f44b91136a292c84b 100644 (file)
@@ -377,8 +377,13 @@ ao_radio_recv(__xdata void *packet, uint8_t size) __reentrant
                            DMA_CFG1_PRIORITY_HIGH);
        ao_dma_start(ao_radio_dma);
        RFST = RFST_SRX;
+
+       /* Wait for DMA to be done, for the radio receive process to
+        * get aborted or for a receive timeout to fire
+        */
        __critical while (!ao_radio_dma_done && !ao_radio_abort)
-                          ao_sleep(&ao_radio_dma_done);
+                          if (ao_sleep(&ao_radio_dma_done))
+                                  break;
 
        /* If recv was aborted, clean up by stopping the DMA engine
         * and idling the radio
index 72c9d7d61f67216a71436ce9ffd7c4d0989c5bef..35f34b491eef2a92d507756504cb47e8222c6ecc 100644 (file)
@@ -204,12 +204,11 @@ ao_sleep(__xdata void *wchan)
                ao_cur_task->wchan = wchan;
        }
        ao_yield();
+       ao_cur_task->alarm = 0;
        if (ao_cur_task->wchan) {
                ao_cur_task->wchan = NULL;
-               ao_cur_task->alarm = 0;
                return 1;
        }
-       ao_cur_task->alarm = 0;
        return 0;
 }
 
@@ -233,12 +232,6 @@ ao_alarm(uint16_t delay)
                ao_cur_task->alarm = 1;
 }
 
-void
-ao_wake_task(__xdata struct ao_task *task)
-{
-       task->wchan = NULL;
-}
-
 void
 ao_exit(void) __critical
 {