Add waker_fn (#18)

* Add waker_fn

* Add a waker_fn test

* Double sleep times

* More benches

* Prohibit recursive block_on calls

* Reformat code
diff --git a/src/waker_fn.rs b/src/waker_fn.rs
new file mode 100644
index 0000000..37105f1
--- /dev/null
+++ b/src/waker_fn.rs
@@ -0,0 +1,43 @@
+use alloc::sync::Arc;
+use core::mem::{self, ManuallyDrop};
+use core::task::{RawWaker, RawWakerVTable, Waker};
+
+/// Creates a waker from a wake function.
+///
+/// The function gets called every time the waker is woken.
+pub fn waker_fn<F: Fn() + Send + Sync + 'static>(f: F) -> Waker {
+    let raw = Arc::into_raw(Arc::new(f)) as *const ();
+    let vtable = &Helper::<F>::VTABLE;
+    unsafe { Waker::from_raw(RawWaker::new(raw, vtable)) }
+}
+
+struct Helper<F>(F);
+
+impl<F: Fn() + Send + Sync + 'static> Helper<F> {
+    const VTABLE: RawWakerVTable = RawWakerVTable::new(
+        Self::clone_waker,
+        Self::wake,
+        Self::wake_by_ref,
+        Self::drop_waker,
+    );
+
+    unsafe fn clone_waker(ptr: *const ()) -> RawWaker {
+        let arc = ManuallyDrop::new(Arc::from_raw(ptr as *const F));
+        mem::forget(arc.clone());
+        RawWaker::new(ptr, &Self::VTABLE)
+    }
+
+    unsafe fn wake(ptr: *const ()) {
+        let arc = Arc::from_raw(ptr as *const F);
+        (arc)();
+    }
+
+    unsafe fn wake_by_ref(ptr: *const ()) {
+        let arc = ManuallyDrop::new(Arc::from_raw(ptr as *const F));
+        (arc)();
+    }
+
+    unsafe fn drop_waker(ptr: *const ()) {
+        drop(Arc::from_raw(ptr as *const F));
+    }
+}