Add general purpose waiting future
diff --git a/examples/adc.rs b/examples/adc.rs
index 8ba602b..5af2521 100644
--- a/examples/adc.rs
+++ b/examples/adc.rs
@@ -16,6 +16,6 @@
 
     loop {
         adc.sample(0).unwrap();
-        timer::sleep(Duration::from_ms(2000));
+        timer::sleep_sync(Duration::from_ms(2000));
     }
 }
diff --git a/examples/blink.rs b/examples/blink.rs
index 8e8980e..c011be0 100644
--- a/examples/blink.rs
+++ b/examples/blink.rs
@@ -1,5 +1,6 @@
 #![no_std]
 
+use core::executor;
 use libtock::led;
 use libtock::timer;
 use libtock::timer::Duration;
@@ -21,6 +22,6 @@
         count = count.wrapping_add(1);
 
         // This delay uses an underlying timer in the kernel.
-        timer::sleep(Duration::from_ms(250));
+        executor::block_on(timer::sleep(Duration::from_ms(250)));
     }
 }
diff --git a/examples/blink_random.rs b/examples/blink_random.rs
index d114d39..748de9a 100644
--- a/examples/blink_random.rs
+++ b/examples/blink_random.rs
@@ -16,9 +16,9 @@
 
         for &x in buf.iter() {
             blink_nibble(x);
-            timer::sleep(Duration::from_ms(100));
+            timer::sleep_sync(Duration::from_ms(100));
             blink_nibble(x >> 4);
-            timer::sleep(Duration::from_ms(100));
+            timer::sleep_sync(Duration::from_ms(100));
         }
     }
 }
diff --git a/examples/button_leds.rs b/examples/button_leds.rs
index 2ab7615..ba91486 100644
--- a/examples/button_leds.rs
+++ b/examples/button_leds.rs
@@ -22,6 +22,6 @@
     }
 
     loop {
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
     }
 }
diff --git a/examples/button_read.rs b/examples/button_read.rs
index 539fa6c..507449b 100644
--- a/examples/button_read.rs
+++ b/examples/button_read.rs
@@ -20,6 +20,6 @@
             ButtonState::Released => writeln!(console, "released"),
         }
         .unwrap();
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
     }
 }
diff --git a/examples/button_subscribe.rs b/examples/button_subscribe.rs
index 6644e8d..2d35679 100644
--- a/examples/button_subscribe.rs
+++ b/examples/button_subscribe.rs
@@ -31,6 +31,6 @@
     }
 
     loop {
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
     }
 }
diff --git a/examples/gpio.rs b/examples/gpio.rs
index a09a2b2..1e918e2 100644
--- a/examples/gpio.rs
+++ b/examples/gpio.rs
@@ -11,8 +11,8 @@
 
     loop {
         pin.set_high();
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
         pin.set_low();
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
     }
 }
diff --git a/examples/gpio_read.rs b/examples/gpio_read.rs
index a5d7f5b..b5ec69b 100644
--- a/examples/gpio_read.rs
+++ b/examples/gpio_read.rs
@@ -18,6 +18,6 @@
         } else {
             writeln!(console, "false").unwrap();
         }
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
     }
 }
diff --git a/examples/hello.rs b/examples/hello.rs
index a1e30f2..0117c74 100644
--- a/examples/hello.rs
+++ b/examples/hello.rs
@@ -10,6 +10,6 @@
 
     for i in 0.. {
         writeln!(console, "Hello world! {}", i).unwrap();
-        timer::sleep(Duration::from_ms(500))
+        timer::sleep_sync(Duration::from_ms(500))
     }
 }
diff --git a/examples/sensors.rs b/examples/sensors.rs
index 7b3afd3..f565629 100644
--- a/examples/sensors.rs
+++ b/examples/sensors.rs
@@ -17,6 +17,6 @@
         writeln!(console, "Temperature: {}\n", temperature.read()).unwrap();
         writeln!(console, "Light:       {}\n", light.read()).unwrap();
         writeln!(console, "Accel:       {}\n", ninedof.read_acceleration()).unwrap();
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
     }
 }
diff --git a/examples/seven_segment.rs b/examples/seven_segment.rs
index 9f767e6..22ece37 100644
--- a/examples/seven_segment.rs
+++ b/examples/seven_segment.rs
@@ -33,6 +33,6 @@
     loop {
         i = (i + 1) % 11;
         shift_register.write_bits(&number_to_bits(i));
-        timer::sleep(Duration::from_ms(200));
+        timer::sleep_sync(Duration::from_ms(200));
     }
 }
diff --git a/examples/simple_ble.rs b/examples/simple_ble.rs
index a467f97..65f6d42 100644
--- a/examples/simple_ble.rs
+++ b/examples/simple_ble.rs
@@ -44,8 +44,8 @@
 
     loop {
         led.on();
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
         led.off();
-        timer::sleep(Duration::from_ms(500));
+        timer::sleep_sync(Duration::from_ms(500));
     }
 }
diff --git a/src/console.rs b/src/console.rs
index ecd7ad1..7942fb7 100644
--- a/src/console.rs
+++ b/src/console.rs
@@ -1,5 +1,7 @@
+use crate::futures;
 use crate::syscalls;
 use core::cell::Cell;
+use core::executor;
 use core::fmt;
 
 const DRIVER_NUMBER: usize = 1;
@@ -65,7 +67,7 @@
             return;
         }
 
-        syscalls::yieldk_for(|| is_written.get());
+        executor::block_on(futures::wait_until(|| is_written.get()));
     }
 }
 
diff --git a/src/futures.rs b/src/futures.rs
new file mode 100644
index 0000000..0223507
--- /dev/null
+++ b/src/futures.rs
@@ -0,0 +1,29 @@
+use core::future::Future;
+use core::pin::Pin;
+use core::task::Context;
+use core::task::Poll;
+
+// TODO: Consider using FnMut
+pub async fn wait_until<F: Fn() -> bool>(condition: F) {
+    wait_for_value(move || if condition() { Some(()) } else { None }).await
+}
+
+pub async fn wait_for_value<T, F: Fn() -> Option<T>>(value_provider: F) -> T {
+    WaitForValue { value_provider }.await
+}
+
+struct WaitForValue<F> {
+    value_provider: F,
+}
+
+impl<T, F: Fn() -> Option<T>> Future for WaitForValue<F> {
+    type Output = T;
+
+    fn poll(self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<Self::Output> {
+        if let Some(value) = (self.value_provider)() {
+            Poll::Ready(value)
+        } else {
+            Poll::Pending
+        }
+    }
+}
diff --git a/src/lang_items.rs b/src/lang_items.rs
index 6d91bb0..39deb02 100644
--- a/src/lang_items.rs
+++ b/src/lang_items.rs
@@ -48,11 +48,11 @@
         for led in led::all() {
             led.on();
         }
-        timer::sleep(Duration::from_ms(100));
+        timer::sleep_sync(Duration::from_ms(100));
         for led in led::all() {
             led.off();
         }
-        timer::sleep(Duration::from_ms(100));
+        timer::sleep_sync(Duration::from_ms(100));
     }
 }
 
@@ -61,7 +61,7 @@
     loop {
         for led in led::all() {
             led.on();
-            timer::sleep(Duration::from_ms(100));
+            timer::sleep_sync(Duration::from_ms(100));
             led.off();
         }
     }
diff --git a/src/lib.rs b/src/lib.rs
index 1d4f26b..004c4d3 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -19,6 +19,7 @@
 pub mod console;
 pub mod debug;
 pub mod electronics;
+pub mod futures;
 pub mod gpio;
 pub mod led;
 pub mod memop;
diff --git a/src/rng.rs b/src/rng.rs
index 411030e..915745c 100644
--- a/src/rng.rs
+++ b/src/rng.rs
@@ -1,5 +1,7 @@
+use crate::futures;
 use crate::syscalls;
 use core::cell::Cell;
+use core::executor;
 
 const DRIVER_NUMBER: usize = 0x40001;
 
@@ -40,6 +42,6 @@
         return false;
     }
 
-    syscalls::yieldk_for(|| is_filled.get());
+    executor::block_on(futures::wait_until(|| is_filled.get()));
     return true;
 }
diff --git a/src/sensors/mod.rs b/src/sensors/mod.rs
index f15a9db..7e62d8e 100644
--- a/src/sensors/mod.rs
+++ b/src/sensors/mod.rs
@@ -1,6 +1,8 @@
-use crate::syscalls::{self, yieldk_for};
+use crate::futures;
+use crate::syscalls;
 use core::cell::Cell;
 use core::convert::From;
+use core::executor;
 use core::fmt;
 use core::mem;
 
@@ -30,7 +32,7 @@
                 mem::transmute(&res),
             );
             syscalls::command(driver_num, 1, 0, 0);
-            yieldk_for(|| res.get().is_some());
+            executor::block_on(futures::wait_until(|| res.get().is_some()));
             res.get().unwrap()
         }
     }
diff --git a/src/sensors/ninedof.rs b/src/sensors/ninedof.rs
index a7a3a7e..7c347c8 100644
--- a/src/sensors/ninedof.rs
+++ b/src/sensors/ninedof.rs
@@ -1,5 +1,7 @@
-use crate::syscalls::{self, yieldk_for};
+use crate::futures;
+use crate::syscalls;
 use core::cell::Cell;
+use core::executor;
 use core::fmt;
 use core::mem;
 
@@ -36,7 +38,7 @@
         unsafe {
             subscribe(Self::cb, mem::transmute(&res));
             start_accel_reading();
-            yieldk_for(|| res.ready.get());
+            executor::block_on(futures::wait_until(|| res.ready.get()));
         }
         res.res.get()
     }
@@ -46,7 +48,7 @@
         unsafe {
             subscribe(Self::cb, mem::transmute(&res));
             start_magnetometer_reading();
-            yieldk_for(|| res.ready.get());
+            executor::block_on(futures::wait_until(|| res.ready.get()));
         }
         res.res.get()
     }
diff --git a/src/syscalls.rs b/src/syscalls.rs
index f4caca0..8aed414 100644
--- a/src/syscalls.rs
+++ b/src/syscalls.rs
@@ -56,12 +56,6 @@
     }
 }
 
-pub fn yieldk_for<F: Fn() -> bool>(cond: F) {
-    while !cond() {
-        yieldk();
-    }
-}
-
 pub fn subscribe<CB: SubscribableCallback>(
     driver_number: usize,
     subscribe_number: usize,
diff --git a/src/timer.rs b/src/timer.rs
index ae60b07..94359c1 100644
--- a/src/timer.rs
+++ b/src/timer.rs
@@ -1,10 +1,12 @@
 use crate::callback::CallbackSubscription;
 use crate::callback::SubscribableCallback;
+use crate::futures;
 use crate::result;
 use crate::result::TockResult;
 use crate::result::TockValue;
 use crate::syscalls;
 use core::cell::Cell;
+use core::executor;
 use core::isize;
 use core::ops::{Add, AddAssign, Sub};
 
@@ -22,14 +24,24 @@
     pub const SUBSCRIBE_CALLBACK: usize = 0;
 }
 
-pub fn sleep(duration: Duration<isize>) {
+pub fn sleep_sync(duration: Duration<isize>) {
     let expired = Cell::new(false);
     let mut with_callback = with_callback(|_, _| expired.set(true));
 
     let mut timer = with_callback.init().unwrap();
     timer.set_alarm(duration).unwrap();
 
-    syscalls::yieldk_for(|| expired.get());
+    executor::block_on(futures::wait_until(|| expired.get()));
+}
+
+pub async fn sleep(duration: Duration<isize>) {
+    let expired = Cell::new(false);
+    let mut with_callback = with_callback(|_, _| expired.set(true));
+
+    let mut timer = with_callback.init().unwrap();
+    timer.set_alarm(duration).unwrap();
+
+    futures::wait_until(|| expired.get()).await;
 }
 
 pub fn with_callback<CB>(callback: CB) -> WithCallback<CB> {