diff --git a/.cargo/config b/.cargo/config
new file mode 100644
index 0000000000000000000000000000000000000000..6f290348bda557ea46416913b79dd160fd625253
--- /dev/null
+++ b/.cargo/config
@@ -0,0 +1,10 @@
+[target.thumbv7m-none-eabi]
+runner = 'arm-none-eabi-gdb'
+rustflags = [
+  "-C", "link-arg=-Tlink.x",
+  "-C", "linker=arm-none-eabi-ld",
+  "-Z", "linker-flavor=ld",
+]
+
+[build]
+target = "thumbv7m-none-eabi"
diff --git a/.gdbinit b/.gdbinit
new file mode 100644
index 0000000000000000000000000000000000000000..7c72d4fb1f4064ffbe5275f665caa65846bf90da
--- /dev/null
+++ b/.gdbinit
@@ -0,0 +1,6 @@
+target remote :3333
+
+monitor arm semihosting enable
+
+load
+step
diff --git a/.gitignore b/.gitignore
index 6dc3db1ac0e732ed9e171f6cfb0a88469439cf30..8bc31d43a2d39b57699e85de873a64b479ab7556 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,5 @@
 **/*.rs.bk
+*.org
+.gdb_history
 Cargo.lock
 target/
diff --git a/.travis.yml b/.travis.yml
index c14b79df5b2b96d77008e3fa0e34e011c5bdbb82..568e7ab43fe405d7a431629db1144fc727728300 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -2,6 +2,8 @@ language: rust
 
 matrix:
   include:
+    - env: TARGET=x86_64-unknown-linux-gnu
+      rust: nightly
     - env: TARGET=thumbv7m-none-eabi
       rust: nightly
       addons:
diff --git a/Xargo.toml b/Xargo.toml
new file mode 100644
index 0000000000000000000000000000000000000000..89ad4cdcaeb6cce198c64fb0e03f570429243b42
--- /dev/null
+++ b/Xargo.toml
@@ -0,0 +1,6 @@
+[dependencies.core]
+stage = 0
+
+[dependencies.compiler_builtins]
+features = ["mem"]
+stage = 1
\ No newline at end of file
diff --git a/ci/script.sh b/ci/script.sh
index 08323b2557138fd26216012a83bfe8c8ef6b5923..0c48f8d1820d0a400ae85bf57f2f5daf1fdd0974 100644
--- a/ci/script.sh
+++ b/ci/script.sh
@@ -1,52 +1,13 @@
 set -euxo pipefail
 
 main() {
-    local src=$(pwd)
-    local td=$(mktemp -d)
-    local version=0.1.8
-    local url=https://github.com/japaric/cortex-m-quickstart/archive/v$version.tar.gz
+    if [ $TARGET = x86_64-unknown-linux-gnu ]; then
+        cargo build --target $TARGET
+        return
+    fi
 
-    pushd $td
-
-    curl -L $url | tar --strip-components 1 -xz
-
-    rm -rf build.rs examples memory.x src
-    ln -s $src/examples .
-
-    cat >>Cargo.toml <<EOF
-[dependencies.blue-pill]
-path = "$src"
-
-[dependencies.embedded-hal]
-git = "https://github.com/japaric/embedded-hal"
-rev = "5295697669f5b48a900aa325b8ebb4d4e8d4b236"
-
-[dependencies.cortex-m-rtfm]
-version = "0.1.1"
-
-[dependencies.futures]
-default-features = false
-version = "0.1.14"
-
-[dependencies.nb]
-git = "https://github.com/japaric/nb"
-EOF
-
-    for path in $(ls examples/*); do
-        local ex=$(basename $path)
-        ex=${ex%.*}
-
-        case $ex in
-            *-await)
-                continue
-                ;;
-        esac
-
-        xargo check --example $ex --target $TARGET
-    done
-
-    popd
-    rm -rf $td
+    xargo build --target $TARGET
+    xargo test --target $TARGET --examples
 }
 
 main
diff --git a/examples/blinky-await.rs b/examples/blinky-await.rs
deleted file mode 100644
index 5ce6fbfa03da2a7f48bdfebea572f98caa8b934a..0000000000000000000000000000000000000000
--- a/examples/blinky-await.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-//! Blinky using `await!`
-
-#![allow(unreachable_code)] // for the `await!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    led::init(gpioc, rcc);
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    // Tasks
-    let mut blinky = (|| {
-        let mut state = false;
-        loop {
-            await!(timer.wait()).unwrap(); // NOTE E = !
-
-            state != state;
-
-            if state {
-                Green.on();
-            } else {
-                Green.off();
-            }
-        }
-    })();
-
-    // Event loop
-    timer.resume();
-    loop {
-        blinky.resume();
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/blinky-blocking.rs b/examples/blinky-blocking.rs
index d0045e6a207b4b7e5d4590059a18aaa5ed9cb4d4..50dd31205438eb1c94127b72c7d4c359629175f7 100644
--- a/examples/blinky-blocking.rs
+++ b/examples/blinky-blocking.rs
@@ -17,7 +17,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -37,7 +37,7 @@ fn init(p: init::Peripherals) {
     timer.init(FREQUENCY.invert(), p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM3);
 
     timer.resume();
diff --git a/examples/blinky-futures.rs b/examples/blinky-futures.rs
deleted file mode 100644
index 3d9e2353e8b60e5894481755e6c5bb4e860afc68..0000000000000000000000000000000000000000
--- a/examples/blinky-futures.rs
+++ /dev/null
@@ -1,90 +0,0 @@
-//! Blinky using futures
-
-#![allow(unreachable_code)] // for the `try_nb!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    led::init(gpioc, rcc);
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-
-    // Tasks
-    let mut blinky = future::loop_fn::<_, (), _, _>(true, |state| {
-        future::poll_fn(move || Ok(Async::Ready(try_nb!(timer.wait()))))
-            .map(move |_| {
-                if state {
-                    Green.on();
-                } else {
-                    Green.off();
-                }
-
-                Loop::Continue(!state)
-            })
-    });
-
-    // Event loop
-    timer.resume();
-    loop {
-        blinky.poll().unwrap(); // NOTE(unwrap) E = !
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/blinky.rs b/examples/blinky.rs
index ad3e749f02bea220152fe2e70b4f6f28a6eba26f..4020fae4597487c4ec2021ca3f7ee60b91d3a80d 100644
--- a/examples/blinky.rs
+++ b/examples/blinky.rs
@@ -1,14 +1,11 @@
 //! Blinks the user LED
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::led::{self, Green};
@@ -18,15 +15,19 @@ use rtfm::{app, Threshold};
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static ON: bool = false;
+    },
+
     tasks: {
         SYS_TICK: {
-            priority: 1,
+            path: toggle,
+            resources: [ON],
         },
     },
 }
 
-// INITIALIZATION PHASE
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     led::init(p.GPIOC, p.RCC);
 
     p.SYST.set_clock_source(SystClkSource::Core);
@@ -35,7 +36,6 @@ fn init(p: init::Peripherals) {
     p.SYST.enable_counter();
 }
 
-// IDLE LOOP
 fn idle() -> ! {
     // Sleep
     loop {
@@ -44,14 +44,10 @@ fn idle() -> ! {
 }
 
 // TASKS
-task!(SYS_TICK, blink, Locals {
-    static STATE: bool = false;
-});
-
-fn blink(_t: &mut Threshold, l: &mut Locals, _r: SYS_TICK::Resources) {
-    *l.STATE = !*l.STATE;
+fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) {
+    **r.ON = !**r.ON;
 
-    if *l.STATE {
+    if **r.ON {
         Green.on();
     } else {
         Green.off();
diff --git a/examples/capture1.rs b/examples/capture1.rs
index f07ee8a92c6990d40bc6ebe53eee2daf5a106bc5..a413904c883c606b3f5ec9b24394939676aa39c5 100644
--- a/examples/capture1.rs
+++ b/examples/capture1.rs
@@ -1,5 +1,4 @@
 //! Input capture using TIM1
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
@@ -14,7 +13,7 @@ extern crate nb;
 use blue_pill::prelude::*;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 // CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
@@ -33,7 +32,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 4] =
         [Channel::_1, Channel::_2, Channel::_3, Channel::_4];
 
diff --git a/examples/capture2.rs b/examples/capture2.rs
index 70b89ef0f1b0cf9a1cfac67102a98bb670ca6699..bb08c5055c2642cfb1d0bced65dc13e64e9844dc 100644
--- a/examples/capture2.rs
+++ b/examples/capture2.rs
@@ -14,9 +14,8 @@ extern crate nb;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
 
 app! {
@@ -33,7 +32,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 4] =
         [Channel::_1, Channel::_2, Channel::_3, Channel::_4];
 
diff --git a/examples/capture3.rs b/examples/capture3.rs
index f3bc006cc83c04ce7385616639bbf15711e5de0d..fd46304f9dc557cec9b025a9944eef15d6bcd6e2 100644
--- a/examples/capture3.rs
+++ b/examples/capture3.rs
@@ -14,9 +14,8 @@ extern crate nb;
 use blue_pill::prelude::*;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
-use rtfm::app;
+use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
 
 app! {
@@ -33,7 +32,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 2] = [Channel::_1, Channel::_2];
 
     let capture = Capture(&*r.TIM3);
diff --git a/examples/capture4.rs b/examples/capture4.rs
index 3ea4494c3ee043dfb7e65c26785f3b13c1040573..2073106828f401598cf4e3dccb5f2d135f644fd8 100644
--- a/examples/capture4.rs
+++ b/examples/capture4.rs
@@ -1,5 +1,4 @@
 //! Input capture using TIM4
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
@@ -14,9 +13,8 @@ extern crate nb;
 use blue_pill::time::Milliseconds;
 use blue_pill::{Capture, Channel};
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const RESOLUTION: Milliseconds = Milliseconds(1);
 
 app! {
@@ -33,7 +31,7 @@ fn init(p: init::Peripherals) {
     capture.init(RESOLUTION, p.AFIO, p.GPIOB, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     const CHANNELS: [Channel; 4] =
         [Channel::_1, Channel::_2, Channel::_3, Channel::_4];
 
diff --git a/examples/claim.rs b/examples/claim.rs
new file mode 100644
index 0000000000000000000000000000000000000000..82aeaaabdfe7083d8c79abbfe93ff86cbd7d9284
--- /dev/null
+++ b/examples/claim.rs
@@ -0,0 +1,76 @@
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use blue_pill::stm32f103xx::Interrupt;
+use rtfm::{app, Resource, Threshold};
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static R1: bool = false;
+    },
+
+    tasks: {
+        EXTI0: {
+            path: exti0,
+            priority: 1,
+            resources: [R1],
+        },
+
+        EXTI1: {
+            path: exti1,
+            priority: 2,
+            resources: [R1],
+        },
+
+        EXTI2: {
+            path: exti2,
+            priority: 3,
+        },
+    },
+}
+
+fn init(_p: init::Peripherals, _r: init::Resources) {}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn exti0(t: &mut Threshold, r: EXTI0::Resources) {
+    // Threshold == 1
+
+    rtfm::set_pending(Interrupt::EXTI1); // ~> exti1
+
+    r.R1.claim(t, |_r1, _t| {
+        // Threshold = 2
+        rtfm::set_pending(Interrupt::EXTI1);
+
+        rtfm::set_pending(Interrupt::EXTI2); // ~> exti2
+    }); // Threshold = 1
+
+    // ~> exti1
+
+    rtfm::atomic(t, |t| {
+        // Threshold = MAX
+        let _r1 = r.R1.borrow(t);
+
+        rtfm::set_pending(Interrupt::EXTI1);
+
+        rtfm::set_pending(Interrupt::EXTI2);
+    }); // Threshold = 1
+
+    // ~> exti2, exti1
+}
+
+fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {
+    // .. modify R1 ..
+}
+
+fn exti2() {}
diff --git a/examples/concurrent-await.rs b/examples/concurrent-await.rs
deleted file mode 100644
index 1bed02101deec040bbc838a0c7bdeddf5a6cdf30..0000000000000000000000000000000000000000
--- a/examples/concurrent-await.rs
+++ /dev/null
@@ -1,120 +0,0 @@
-//! Two concurrent tasks using `await!`
-
-#![allow(unreachable_code)] // for the `await!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Serial, Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const BAUD_RATE: Hertz = Hertz(115_200);
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    AFIO: Peripheral {
-        ceiling: C0,
-    },
-    GPIOA: Peripheral {
-        ceiling: C0,
-    },
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-    USART1: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let afio = &AFIO.access(prio, thr);
-    let gpioa = &GPIOA.access(prio, thr);
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    led::init(gpioc, rcc);
-
-    serial.init(BAUD_RATE.invert(), afio, None, gpioa, rcc);
-
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-#[inline(never)]
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    // Tasks
-    let mut blinky = (|| {
-        let mut state = false;
-        loop {
-            await!(timer.wait()).unwrap(); // NOTE(unwrap) E = !
-
-            state != state;
-
-            if state {
-                Green.on();
-            } else {
-                Green.off();
-            }
-        }
-    })();
-
-    let mut loopback = (|| loop {
-                            let byte = await!(serial.read()).unwrap();
-                            await!(serial.write()).unwrap();
-                        })();
-
-    // Resume the timer count
-    timer.resume();
-
-    // Event loop
-    loop {
-        blinky.resume();
-        loopback.resume();
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/concurrent-futures.rs b/examples/concurrent-futures.rs
deleted file mode 100644
index f95960804e32fe31324974ee6367ec74e86ec944..0000000000000000000000000000000000000000
--- a/examples/concurrent-futures.rs
+++ /dev/null
@@ -1,121 +0,0 @@
-//! Two concurrent tasks using futures
-
-#![allow(unreachable_code)] // for the `try_nb!` macro
-#![deny(unsafe_code)]
-#![deny(warnings)]
-#![feature(const_fn)]
-#![feature(used)]
-#![no_std]
-
-extern crate blue_pill;
-
-extern crate embedded_hal as hal;
-
-// version = "0.2.3"
-extern crate cortex_m_rt;
-
-// version = "0.1.0"
-#[macro_use]
-extern crate cortex_m_rtfm as rtfm;
-
-extern crate futures;
-
-#[macro_use]
-extern crate nb;
-
-use blue_pill::led::{self, Green};
-use blue_pill::time::Hertz;
-use blue_pill::{Serial, Timer, stm32f103xx};
-use futures::future::{self, Loop};
-use futures::{Async, Future};
-use hal::prelude::*;
-use rtfm::{P0, T0, TMax};
-
-// CONFIGURATION
-const BAUD_RATE: Hertz = Hertz(115_200);
-const FREQUENCY: Hertz = Hertz(1);
-
-// RESOURCES
-peripherals!(stm32f103xx, {
-    AFIO: Peripheral {
-        ceiling: C0,
-    },
-    GPIOA: Peripheral {
-        ceiling: C0,
-    },
-    GPIOC: Peripheral {
-        ceiling: C0,
-    },
-    RCC: Peripheral {
-        ceiling: C0,
-    },
-    TIM3: Peripheral {
-        ceiling: C0,
-    },
-    USART1: Peripheral {
-        ceiling: C0,
-    },
-});
-
-// INITIALIZATION PHASE
-fn init(ref prio: P0, thr: &TMax) {
-    let afio = &AFIO.access(prio, thr);
-    let gpioa = &GPIOA.access(prio, thr);
-    let gpioc = &GPIOC.access(prio, thr);
-    let rcc = &RCC.access(prio, thr);
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    led::init(gpioc, rcc);
-
-    serial.init(BAUD_RATE.invert(), afio, None, gpioa, rcc);
-
-    timer.init(FREQUENCY.invert(), rcc);
-}
-
-// IDLE LOOP
-#[inline(never)]
-fn idle(ref prio: P0, ref thr: T0) -> ! {
-    let tim3 = TIM3.access(prio, thr);
-    let usart1 = USART1.access(prio, thr);
-
-    let timer = Timer(&*tim3);
-    let serial = Serial(&*usart1);
-
-    // Tasks
-    let mut blinky = future::loop_fn::<_, (), _, _>(true, |state| {
-        future::poll_fn(move || Ok(Async::Ready(try_nb!(timer.wait()))))
-            .map(move |_| {
-                if state {
-                    Green.on();
-                } else {
-                    Green.off();
-                }
-
-                Loop::Continue(!state)
-            })
-    });
-
-    let mut loopback = future::loop_fn::<_, (), _, _>((), |_| {
-        future::poll_fn(move || Ok(Async::Ready(try_nb!(serial.read()))))
-            .and_then(|byte| {
-                future::poll_fn(
-                    move || Ok(Async::Ready(try_nb!(serial.write(byte)))),
-                )
-            })
-            .map(|_| Loop::Continue(()))
-    });
-
-    // Event loop
-    timer.resume();
-    loop {
-        loopback.poll().unwrap(); // NOTE(unwrap) E = !
-        blinky.poll().unwrap();
-    }
-}
-
-// TASKS
-tasks!(stm32f103xx, {});
diff --git a/examples/concurrent.rs b/examples/concurrent.rs
index 28dffaebe026054700e61c33a3762f27aebd8de2..10abc90c7e224b3a53a397854a5d2abc86b3affa 100644
--- a/examples/concurrent.rs
+++ b/examples/concurrent.rs
@@ -1,91 +1,76 @@
-//! Serial loopback
-
+//! Running two tasks concurrently
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-
-#[macro_use]
+extern crate cortex_m;
 extern crate cortex_m_rtfm as rtfm;
 
+use blue_pill::Serial;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::serial::Event;
 use blue_pill::time::Hertz;
-use blue_pill::{Serial, Timer, stm32f103xx};
+use cortex_m::peripheral::SystClkSource;
 use rtfm::{app, Threshold};
 
+const BAUD_RATE: Hertz = Hertz(115_200);
+
 app! {
-    device: stm32f103xx,
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static ON: bool = false;
+    },
 
     tasks: {
-        TIM2: {
-            priority: 1,
-            enabled: true,
-            resources: [TIM2],
+        SYS_TICK: {
+            path: toggle,
+            resources: [ON],
         },
 
         USART1: {
-            priority: 1,
-            enabled: true,
+            path: loopback,
             resources: [USART1],
         },
     },
 }
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
-pub const FREQUENCY: Hertz = Hertz(1);
-
-// INITIALIZATION PHASE
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let serial = Serial(p.USART1);
-    let timer = Timer(p.TIM2);
 
     led::init(p.GPIOC, p.RCC);
 
     serial.init(BAUD_RATE.invert(), p.AFIO, None, p.GPIOA, p.RCC);
     serial.listen(Event::Rxne);
 
-    timer.init(FREQUENCY.invert(), p.RCC);
-    timer.resume();
+    p.SYST.set_clock_source(SystClkSource::Core);
+    p.SYST.set_reload(8_000_000); // 1s
+    p.SYST.enable_interrupt();
+    p.SYST.enable_counter();
 }
 
-// IDLE LOOP
 fn idle() -> ! {
-    // Sleep
     loop {
         rtfm::wfi();
     }
 }
 
-// TASKS
-task!(TIM2, blinky, Local {
-    static STATE: bool = false;
-});
-
-fn blinky(_t: &mut Threshold, l: &mut Local, r: TIM2::Resources) {
-    let timer = Timer(&**r.TIM2);
+fn loopback(_t: &mut Threshold, r: USART1::Resources) {
+    let serial = Serial(&**r.USART1);
 
-    timer.wait().unwrap();
+    let byte = serial.read().unwrap();
+    serial.write(byte).unwrap();
+}
 
-    *l.STATE = !*l.STATE;
+fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) {
+    **r.ON = !**r.ON;
 
-    if *l.STATE {
+    if **r.ON {
         Green.on();
     } else {
         Green.off();
     }
 }
-
-task!(USART1, loopback);
-
-fn loopback(_t: &mut Threshold, r: USART1::Resources) {
-    let serial = Serial(&**r.USART1);
-
-    let byte = serial.read().unwrap();
-    serial.write(byte).unwrap();
-}
diff --git a/examples/cpu.rs b/examples/cpu.rs
index b81ef4ed6aa0b409b3404e9a5db1057239230ebc..d5bab7c4522840fe42cec306e0d114f713598ea5 100644
--- a/examples/cpu.rs
+++ b/examples/cpu.rs
@@ -1,27 +1,21 @@
 //! CPU usage monitor
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-
-#[macro_use]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Timer;
-use blue_pill::stm32f103xx;
 use blue_pill::time::Hertz;
 use blue_pill::prelude::*;
 use rtfm::{app, Resource, Threshold};
 
 app! {
-    device: stm32f103xx,
+    device: blue_pill::stm32f103xx,
 
     resources: {
         static SLEEP_TIME: u32 = 0;
@@ -33,17 +27,14 @@ app! {
 
     tasks: {
         TIM2: {
-            priority: 1,
-            enabled: true,
+            path: periodic,
             resources: [ITM, SLEEP_TIME, TIM2],
         },
     },
 }
 
-// CONFIGURATION
 const FREQUENCY: Hertz = Hertz(1);
 
-// INITIALIZATION PHASE
 fn init(p: init::Peripherals, _r: init::Resources) {
     let timer = Timer(p.TIM2);
 
@@ -53,13 +44,12 @@ fn init(p: init::Peripherals, _r: init::Resources) {
     timer.resume();
 }
 
-// IDLE LOOP
-fn idle(_t: &mut Threshold, mut r: idle::Resources) -> ! {
+fn idle(t: &mut Threshold, mut r: idle::Resources) -> ! {
     loop {
         // For the span of this critical section the processor will not service
         // interrupts (tasks)
-        rtfm::atomic(|cs| {
-            let sleep_time = r.SLEEP_TIME.borrow_mut(cs);
+        rtfm::atomic(t, |t| {
+            let sleep_time = r.SLEEP_TIME.borrow_mut(t);
 
             // Sleep
             let before = r.DWT.cyccnt.read();
@@ -76,8 +66,6 @@ fn idle(_t: &mut Threshold, mut r: idle::Resources) -> ! {
     }
 }
 
-task!(TIM2, periodic);
-
 fn periodic(_t: &mut Threshold, r: TIM2::Resources) {
     let timer = Timer(&**r.TIM2);
 
diff --git a/examples/gpio.rs b/examples/gpio.rs
index 0b5a5b31d20190a4d78f9aba26132f95b40adc0a..192656bf40c35c92faf0048381b66ae957eb687e 100644
--- a/examples/gpio.rs
+++ b/examples/gpio.rs
@@ -1,5 +1,4 @@
 //! Sets PB12 high
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
diff --git a/examples/hello-world.rs b/examples/hello-world.rs
index e053bdb796d156a1a77e06619414bdd99b9f0725..1d22e08920ee980aca5ab011b241832c0e3b8143 100644
--- a/examples/hello-world.rs
+++ b/examples/hello-world.rs
@@ -1,8 +1,6 @@
 //! Prints "Hello" and then "World" in the OpenOCD console
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
@@ -12,7 +10,7 @@ extern crate cortex_m_semihosting as semihosting;
 
 use core::fmt::Write;
 
-use rtfm::app;
+use rtfm::{app, Threshold};
 use semihosting::hio::{self, HStdout};
 
 app! {
@@ -35,7 +33,7 @@ fn init(_p: init::Peripherals, r: init::Resources) {
     **r.HSTDOUT = Some(hstdout);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     writeln!(r.HSTDOUT.as_mut().unwrap(), "World").unwrap();
 
     loop {
diff --git a/examples/hello.rs b/examples/hello.rs
index 63833fc7e524eeebb6e67eee84ca362277e14fc8..85afeb372b52bcb07da3836c392b8456453ef5e4 100644
--- a/examples/hello.rs
+++ b/examples/hello.rs
@@ -1,5 +1,4 @@
 //! Prints "Hello, World" in the OpenOCD console
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
diff --git a/examples/itm.rs b/examples/itm.rs
index 9c31f71e6636f54242942b38d1777b9c24203d7f..ab913ecf9c0650108474963bd9cfb71ddeaf59a3 100644
--- a/examples/itm.rs
+++ b/examples/itm.rs
@@ -18,7 +18,6 @@
 //! Hello
 //! World
 //! ```
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
@@ -29,7 +28,7 @@ extern crate blue_pill;
 extern crate cortex_m;
 extern crate cortex_m_rtfm as rtfm;
 
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -43,7 +42,7 @@ fn init(p: init::Peripherals) {
     iprintln!(&p.ITM.stim[0], "Hello");
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     iprintln!(&r.ITM.stim[0], "World");
 
     // Sleep
diff --git a/examples/loopback.rs b/examples/loopback.rs
index 6e19cf2c180dce5ceba6811a451c846b7663dea8..cb91fa50ef0c69153bee4a8a16091401fa4c2c06 100644
--- a/examples/loopback.rs
+++ b/examples/loopback.rs
@@ -1,12 +1,10 @@
 //! Serial loopback via USART1
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Serial;
@@ -15,16 +13,14 @@ use blue_pill::serial::Event;
 use blue_pill::time::Hertz;
 use rtfm::{app, Threshold};
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
 
     tasks: {
         USART1: {
-            enabled: true,
-            priority: 1,
+            path: loopback,
             resources: [USART1],
         },
     },
@@ -43,8 +39,6 @@ fn idle() -> ! {
     }
 }
 
-task!(USART1, loopback);
-
 fn loopback(_t: &mut Threshold, r: USART1::Resources) {
     let serial = Serial(&**r.USART1);
 
diff --git a/examples/preemption.rs b/examples/preemption.rs
new file mode 100644
index 0000000000000000000000000000000000000000..4423ecddfc6b7b0bcd1d09435973670426a61731
--- /dev/null
+++ b/examples/preemption.rs
@@ -0,0 +1,86 @@
+//! Running two tasks that share data concurrently
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use blue_pill::Serial;
+use blue_pill::led::{self, Green};
+use blue_pill::prelude::*;
+use blue_pill::serial::Event;
+use blue_pill::time::Hertz;
+use cortex_m::peripheral::SystClkSource;
+use rtfm::{app, Resource, Threshold};
+
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static CONTEXT_SWITCHES: u32 = 0;
+        static ON: bool = false;
+    },
+
+    tasks: {
+        SYS_TICK: {
+            path: toggle,
+            priority: 1,
+            resources: [CONTEXT_SWITCHES, ON],
+        },
+
+        USART1: {
+            path: loopback,
+            priority: 2,
+            resources: [CONTEXT_SWITCHES, USART1],
+        },
+    },
+}
+
+fn init(p: init::Peripherals, _r: init::Resources) {
+    let serial = Serial(p.USART1);
+
+    led::init(p.GPIOC, p.RCC);
+
+    serial.init(BAUD_RATE.invert(), p.AFIO, None, p.GPIOA, p.RCC);
+    serial.listen(Event::Rxne);
+
+    p.SYST.set_clock_source(SystClkSource::Core);
+    p.SYST.set_reload(8_000_000); // 1s
+    p.SYST.enable_interrupt();
+    p.SYST.enable_counter();
+}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn loopback(_t: &mut Threshold, r: USART1::Resources) {
+    **r.CONTEXT_SWITCHES += 1;
+
+    let serial = Serial(&**r.USART1);
+
+    let byte = serial.read().unwrap();
+    serial.write(byte).unwrap();
+}
+
+fn toggle(t: &mut Threshold, mut r: SYS_TICK::Resources) {
+    r.CONTEXT_SWITCHES.claim_mut(t, |context_switches, _t| {
+        // inside a critical section
+        **context_switches += 1;
+    });
+
+    **r.ON = !**r.ON;
+
+    if **r.ON {
+        Green.on();
+    } else {
+        Green.off();
+    }
+}
diff --git a/examples/pwm-control.rs b/examples/pwm-control.rs
index 70ba754a92fdb6aed33236976adeaf53f80a44f2..a72977f0b4fb201ed976b851ea015d52f61d7827 100644
--- a/examples/pwm-control.rs
+++ b/examples/pwm-control.rs
@@ -4,14 +4,12 @@
 //! - '+' increase duty by 1
 //! - '-' decrease duty by 1
 //! - '/' decrease duty by a factor of 2
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use core::u16;
@@ -29,8 +27,7 @@ app! {
 
     tasks: {
         USART1: {
-            enabled: true,
-            priority: 1,
+            path: rx,
             resources: [TIM2, USART1],
         },
     },
@@ -54,8 +51,6 @@ fn idle() -> ! {
     }
 }
 
-task!(USART1, rx);
-
 fn rx(_t: &mut Threshold, r: USART1::Resources) {
     let pwm = Pwm(&**r.TIM2);
     let serial = Serial(&**r.USART1);
diff --git a/examples/qei1.rs b/examples/qei1.rs
index ba49f09d320458f62b02a492628adbc861d6b697..0760b68f0f30cb97ed9e2951a69dffbd1cf6fbc3 100644
--- a/examples/qei1.rs
+++ b/examples/qei1.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM1
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::prelude::*;
@@ -19,22 +16,24 @@ use blue_pill::time::Hertz;
 use blue_pill::{Qei, Timer};
 use rtfm::{app, Threshold};
 
-// CONFIGURATION
 const FREQUENCY: Hertz = Hertz(1);
 
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM4: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM1, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM1, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM1);
     let timer = Timer(p.TIM4);
 
@@ -50,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM4, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM4::Resources) {
     let qei = Qei(&**r.TIM1);
     let timer = Timer(&**r.TIM4);
 
@@ -63,11 +58,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/qei2.rs b/examples/qei2.rs
index edba974778b0ac3741c70af67580111bbe52856e..32b1febcd0cba3424794be0762afe91261ef223a 100644
--- a/examples/qei2.rs
+++ b/examples/qei2.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM2
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::prelude::*;
@@ -24,16 +21,19 @@ const FREQUENCY: Hertz = Hertz(1);
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM4: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM2, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM2, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM2);
     let timer = Timer(p.TIM4);
 
@@ -49,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM4, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM4::Resources) {
     let qei = Qei(&**r.TIM2);
     let timer = Timer(&**r.TIM4);
 
@@ -63,11 +59,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/qei3.rs b/examples/qei3.rs
index e0ed7dec48435f0179598972c2a17dba86e5c0ae..7342affc35bb0cac8545a01773a0c11ca2bf0a68 100644
--- a/examples/qei3.rs
+++ b/examples/qei3.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM3
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::time::Hertz;
@@ -24,16 +21,19 @@ const FREQUENCY: Hertz = Hertz(1);
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM4: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM3, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM3, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM3);
     let timer = Timer(p.TIM4);
 
@@ -49,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM4, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM4::Resources) {
     let qei = Qei(&**r.TIM3);
     let timer = Timer(&**r.TIM4);
 
@@ -62,11 +58,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM4::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/qei4.rs b/examples/qei4.rs
index b04c7eadb90a1fb422bc89c938ef7e9fc343310b..b62a3b6ff586230eb6bbc96e45f92660a03919bc 100644
--- a/examples/qei4.rs
+++ b/examples/qei4.rs
@@ -1,17 +1,14 @@
 //! Quadrature Encoder Interface using TIM4
 //!
 //! Periodically reports the readings of the QEI
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
-#![feature(const_fn)]
 #![feature(proc_macro)]
 #![no_std]
 
 extern crate blue_pill;
 #[macro_use(iprint, iprintln)]
 extern crate cortex_m;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::time::Hertz;
@@ -24,16 +21,19 @@ const FREQUENCY: Hertz = Hertz(1);
 app! {
     device: blue_pill::stm32f103xx,
 
+    resources: {
+        static PREVIOUS: Option<u16> = None;
+    },
+
     tasks: {
         TIM1_UP_TIM10: {
-            enabled: true,
-            priority: 1,
-            resources: [ITM, TIM1, TIM4],
+            path: periodic,
+            resources: [ITM, PREVIOUS, TIM1, TIM4],
         },
     },
 }
 
-fn init(p: init::Peripherals) {
+fn init(p: init::Peripherals, _r: init::Resources) {
     let qei = Qei(p.TIM4);
     let timer = Timer(p.TIM1);
 
@@ -49,11 +49,7 @@ fn idle() -> ! {
     }
 }
 
-task!(TIM1_UP_TIM10, periodic, Locals {
-    static PREVIOUS: Option<u16> = None;
-});
-
-fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM1_UP_TIM10::Resources) {
+fn periodic(_t: &mut Threshold, r: TIM1_UP_TIM10::Resources) {
     let qei = Qei(&**r.TIM4);
     let timer = Timer(&**r.TIM1);
 
@@ -62,11 +58,11 @@ fn periodic(_t: &mut Threshold, l: &mut Locals, r: TIM1_UP_TIM10::Resources) {
     let curr = qei.count();
     let dir = qei.direction();
 
-    if let Some(prev) = l.PREVIOUS.take() {
+    if let Some(prev) = r.PREVIOUS.take() {
         let speed = (curr as i16).wrapping_sub(prev as i16);
 
         iprintln!(&r.ITM.stim[0], "{} - {} - {:?}", curr, speed, dir);
     }
 
-    *l.PREVIOUS = Some(curr);
+    **r.PREVIOUS = Some(curr);
 }
diff --git a/examples/raise.rs b/examples/raise.rs
new file mode 100644
index 0000000000000000000000000000000000000000..351eaf1fd9614faf7317619e1b337f312cdfa514
--- /dev/null
+++ b/examples/raise.rs
@@ -0,0 +1,62 @@
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use cortex_m::asm;
+use rtfm::{app, Resource, Threshold};
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static R1: bool = false;
+        static R2: bool = false;
+    },
+
+    tasks: {
+        EXTI0: {
+            path: exti0,
+            priority: 1,
+            resources: [R1, R2],
+        },
+
+        EXTI1: {
+            path: exti1,
+            priority: 2,
+            resources: [R1],
+        },
+
+        EXTI2: {
+            path: exti2,
+            priority: 3,
+            resources: [R2],
+        },
+    },
+}
+
+fn init(_p: init::Peripherals, _r: init::Resources) {}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn exti0(t: &mut Threshold, r: EXTI0::Resources) {
+    r.R1.claim(t, |_r1, t| {
+        asm::nop();
+
+        r.R2.claim(t, |_r2, _t| {
+            asm::nop();
+        });
+
+        asm::nop();
+    });
+}
+
+fn exti1(_t: &mut Threshold, _r: EXTI1::Resources) {}
+
+fn exti2(_t: &mut Threshold, _r: EXTI2::Resources) {}
diff --git a/examples/sharing.rs b/examples/sharing.rs
new file mode 100644
index 0000000000000000000000000000000000000000..d499c5791347a20f81c9dae22810b2e4bd0a777a
--- /dev/null
+++ b/examples/sharing.rs
@@ -0,0 +1,81 @@
+//! Running two tasks, that share data, concurrently
+#![deny(unsafe_code)]
+#![deny(warnings)]
+#![feature(proc_macro)]
+#![no_std]
+
+extern crate blue_pill;
+extern crate cortex_m;
+extern crate cortex_m_rtfm as rtfm;
+
+use blue_pill::Serial;
+use blue_pill::led::{self, Green};
+use blue_pill::prelude::*;
+use blue_pill::serial::Event;
+use blue_pill::time::Hertz;
+use cortex_m::peripheral::SystClkSource;
+use rtfm::{app, Threshold};
+
+const BAUD_RATE: Hertz = Hertz(115_200);
+
+app! {
+    device: blue_pill::stm32f103xx,
+
+    resources: {
+        static CONTEXT_SWITCHES: u32 = 0;
+        static ON: bool = false;
+    },
+
+    tasks: {
+        SYS_TICK: {
+            path: toggle,
+            resources: [CONTEXT_SWITCHES, ON],
+        },
+
+        USART1: {
+            path: loopback,
+            resources: [CONTEXT_SWITCHES, USART1],
+        },
+    },
+}
+
+fn init(p: init::Peripherals, _r: init::Resources) {
+    let serial = Serial(p.USART1);
+
+    led::init(p.GPIOC, p.RCC);
+
+    serial.init(BAUD_RATE.invert(), p.AFIO, None, p.GPIOA, p.RCC);
+    serial.listen(Event::Rxne);
+
+    p.SYST.set_clock_source(SystClkSource::Core);
+    p.SYST.set_reload(8_000_000); // 1s
+    p.SYST.enable_interrupt();
+    p.SYST.enable_counter();
+}
+
+fn idle() -> ! {
+    loop {
+        rtfm::wfi();
+    }
+}
+
+fn loopback(_t: &mut Threshold, r: USART1::Resources) {
+    **r.CONTEXT_SWITCHES += 1;
+
+    let serial = Serial(&**r.USART1);
+
+    let byte = serial.read().unwrap();
+    serial.write(byte).unwrap();
+}
+
+fn toggle(_t: &mut Threshold, r: SYS_TICK::Resources) {
+    **r.CONTEXT_SWITCHES += 1;
+
+    **r.ON = !**r.ON;
+
+    if **r.ON {
+        Green.on();
+    } else {
+        Green.off();
+    }
+}
diff --git a/examples/spi1.rs b/examples/spi1.rs
index cbcd2318aa659b81e5a8b4f97c35060f5b7d977c..f0ccf03f0da46995a3f14adb60633fa29450ec1e 100644
--- a/examples/spi1.rs
+++ b/examples/spi1.rs
@@ -12,7 +12,7 @@ extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Spi;
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -28,7 +28,7 @@ fn init(p: init::Peripherals) {
     spi.init(p.AFIO, p.GPIOA, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     // Register to read
     const WHO_AM_I: u8 = 117;
 
@@ -39,7 +39,7 @@ fn idle(r: idle::Resources) -> ! {
     const ANS: u8 = 0x73;
 
     // Read mode
-    pub const R: u8 = 1 << 7;
+    const R: u8 = 1 << 7;
 
     let spi = Spi(&*r.SPI1);
 
diff --git a/examples/spi2.rs b/examples/spi2.rs
index 7436e244abc788faf4c428eb60c7c4ff04933c1d..caac90ec079f00335a0f4b07b878c1822fb406ce 100644
--- a/examples/spi2.rs
+++ b/examples/spi2.rs
@@ -12,7 +12,7 @@ extern crate cortex_m_rtfm as rtfm;
 
 use blue_pill::Spi;
 use blue_pill::prelude::*;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -28,7 +28,7 @@ fn init(p: init::Peripherals) {
     spi.init(p.AFIO, p.GPIOB, p.RCC);
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     // Register to read
     const WHO_AM_I: u8 = 117;
 
@@ -39,7 +39,7 @@ fn idle(r: idle::Resources) -> ! {
     const ANS: u8 = 0x73;
 
     // Read mode
-    pub const R: u8 = 1 << 7;
+    const R: u8 = 1 << 7;
 
     let spi = Spi(&*r.SPI2);
 
diff --git a/examples/usart1-rx-dma.rs b/examples/usart1-rx-dma.rs
index 7f3c0b3cd88767376b0e8669ceb93057b62ff17d..dee5fea87bc1d438382a1620922b5078e64dac1c 100644
--- a/examples/usart1-rx-dma.rs
+++ b/examples/usart1-rx-dma.rs
@@ -1,5 +1,4 @@
 //! Test receiving serial data using the DMA
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(const_fn)]
@@ -7,7 +6,6 @@
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 extern crate nb;
 
@@ -16,7 +14,7 @@ use blue_pill::dma::{Buffer, Dma1Channel5};
 use blue_pill::time::Hertz;
 use rtfm::{app, Threshold};
 
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -27,8 +25,7 @@ app! {
 
     tasks: {
         DMA1_CHANNEL5: {
-            enabled: true,
-            priority: 1,
+            path: transfer_done,
             resources: [BUFFER, DMA1],
         },
     },
@@ -48,8 +45,6 @@ fn idle() -> ! {
     }
 }
 
-task!(DMA1_CHANNEL5, transfer_done);
-
 fn transfer_done(_t: &mut Threshold, r: DMA1_CHANNEL5::Resources) {
     r.BUFFER.release(r.DMA1).unwrap();
 
diff --git a/examples/usart1-tx-dma.rs b/examples/usart1-tx-dma.rs
index 06f209e6b5d73395b04b06598a548846c7213781..c68985108970fe544511a6171d2a1c35736c8e1e 100644
--- a/examples/usart1-tx-dma.rs
+++ b/examples/usart1-tx-dma.rs
@@ -1,5 +1,4 @@
 //! Test sending serial data using the DMA
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(const_fn)]
@@ -7,7 +6,6 @@
 #![no_std]
 
 extern crate blue_pill;
-#[macro_use(task)]
 extern crate cortex_m_rtfm as rtfm;
 extern crate nb;
 
@@ -16,7 +14,7 @@ use blue_pill::dma::{Buffer, Dma1Channel4};
 use blue_pill::time::Hertz;
 use rtfm::{app, Threshold};
 
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
@@ -27,8 +25,7 @@ app! {
 
     tasks: {
         DMA1_CHANNEL4: {
-            enabled: true,
-            priority: 1,
+            path: transfer_done,
             resources: [BUFFER, DMA1],
         },
     },
@@ -49,8 +46,6 @@ fn idle() -> ! {
     }
 }
 
-task!(DMA1_CHANNEL4, transfer_done);
-
 fn transfer_done(_t: &mut Threshold, r: DMA1_CHANNEL4::Resources) {
     r.BUFFER.release(r.DMA1).unwrap();
 
diff --git a/examples/usart1.rs b/examples/usart1.rs
index 9abd07de932e81215039213f6cbbb611b60e70dc..ca0d23bd65dbd8f3b4bdaa512a0bf290f99dcba6 100644
--- a/examples/usart1.rs
+++ b/examples/usart1.rs
@@ -16,8 +16,7 @@ use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
 use rtfm::app;
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
diff --git a/examples/usart2.rs b/examples/usart2.rs
index 2af3b2e40c89f3aa0d5a352fdc102fef351f1f0e..0eb55a1acc3103fd46419b615a954ee198f39524 100644
--- a/examples/usart2.rs
+++ b/examples/usart2.rs
@@ -17,8 +17,7 @@ use blue_pill::prelude::*;
 use nb::Error;
 use rtfm::app;
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
diff --git a/examples/usart3.rs b/examples/usart3.rs
index 5d5815fe55dff265064c470def7a79e3a9ba172f..6dd8e9635520f1731025616ecaa42a9ac9aa3512 100644
--- a/examples/usart3.rs
+++ b/examples/usart3.rs
@@ -17,8 +17,7 @@ use blue_pill::time::Hertz;
 use nb::Error;
 use rtfm::app;
 
-// CONFIGURATION
-pub const BAUD_RATE: Hertz = Hertz(115_200);
+const BAUD_RATE: Hertz = Hertz(115_200);
 
 app! {
     device: blue_pill::stm32f103xx,
diff --git a/examples/wait1.rs b/examples/wait1.rs
index bfe353cafdaf4c01bddc4c80a35867d18771c05c..21f51c98fbdc5fae72bfbce5e5790f70371abfe5 100644
--- a/examples/wait1.rs
+++ b/examples/wait1.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -33,7 +33,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM1);
 
     let mut state = false;
diff --git a/examples/wait2.rs b/examples/wait2.rs
index daad69e34212ef0f281868e9f89762257df40148..3b23c27c87f844f5ce40b8e1b7c7668f314e433b 100644
--- a/examples/wait2.rs
+++ b/examples/wait2.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -32,7 +32,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM2);
 
     let mut state = false;
diff --git a/examples/wait3.rs b/examples/wait3.rs
index 6023c5de8ddf85485be382e8bc373c9a7f55e255..b5d5c3e006d9d8f295c58ec47cd274de22185920 100644
--- a/examples/wait3.rs
+++ b/examples/wait3.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -33,7 +33,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM3);
 
     let mut state = false;
diff --git a/examples/wait4.rs b/examples/wait4.rs
index fe14a34de746e301a565342cd108b54aa26ccd29..393f454e021197f9de9ccff6c394a68a9061a961 100644
--- a/examples/wait4.rs
+++ b/examples/wait4.rs
@@ -12,7 +12,7 @@ use blue_pill::Timer;
 use blue_pill::led::{self, Green};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
-use rtfm::app;
+use rtfm::{app, Threshold};
 
 const FREQUENCY: Hertz = Hertz(1);
 
@@ -33,7 +33,7 @@ fn init(p: init::Peripherals) {
     timer.resume();
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let timer = Timer(&*r.TIM4);
 
     let mut state = false;
diff --git a/examples/ws2812.rs b/examples/ws2812.rs
index 5f61faa7b1cdf5b1a77241bb1da8c8d22d504fcd..da623f8e896c22a20b61b9f6f4dfbfdbe3962801 100644
--- a/examples/ws2812.rs
+++ b/examples/ws2812.rs
@@ -1,7 +1,6 @@
 //! Drive a ring of 24 WS2812 LEDs
 //!
 //! To test this demo connect the data-in pin of the LED ring to pin PA0
-
 #![deny(unsafe_code)]
 #![deny(warnings)]
 #![feature(const_fn)]
@@ -17,7 +16,7 @@ use blue_pill::dma::{Buffer, Dma1Channel2};
 use blue_pill::prelude::*;
 use blue_pill::time::Hertz;
 use blue_pill::{Channel, Pwm};
-use rtfm::{app, Static};
+use rtfm::{app, Static, Threshold};
 
 // CONFIGURATION
 const FREQUENCY: Hertz = Hertz(200_000);
@@ -51,7 +50,7 @@ fn init(p: init::Peripherals, r: init::Resources) {
     }
 }
 
-fn idle(r: idle::Resources) -> ! {
+fn idle(_t: &mut Threshold, r: idle::Resources) -> ! {
     let pwm = Pwm(&*r.TIM2);
     let buffer = Static::wrap_mut(r.BUFFER);
 
diff --git a/src/dma.rs b/src/dma.rs
index 0019657023759a68ca0948ac57b36685c1c7cf7c..fd581fe7797cc74fe86450dfbc28e2f1e0146c70 100644
--- a/src/dma.rs
+++ b/src/dma.rs
@@ -43,10 +43,10 @@ pub struct Dma1Channel5 {
 // NOTE(packed) workaround for rust-lang/rust#41315
 #[repr(packed)]
 pub struct Buffer<T, CHANNEL> {
-    _marker: PhantomData<CHANNEL>,
     data: UnsafeCell<T>,
     flag: Cell<BorrowFlag>,
     state: Cell<State>,
+    _marker: PhantomData<CHANNEL>,
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
diff --git a/src/lib.rs b/src/lib.rs
index 3e15a7fef9c0f95ea5e1054affc29843c3295abb..515bbcbfd7d8e3558d6f830717895d0c05fca144 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -22,7 +22,6 @@ extern crate cast;
 extern crate embedded_hal as hal;
 extern crate nb;
 extern crate static_ref;
-extern crate volatile_register;
 
 pub extern crate stm32f103xx;