Use ThreadId for spawn_local
diff --git a/.travis.yml b/.travis.yml
index bd66105..fb309a2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -23,3 +23,4 @@
   - cargo fmt --all -- --check
   - cargo check --benches --bins --examples --tests
   - cargo test -- --test-threads=1
+  - cargo check --no-default-features
diff --git a/Cargo.toml b/Cargo.toml
index 4fa912e..f957ba0 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -12,11 +12,9 @@
 categories = ["asynchronous", "concurrency", "no-std"]
 readme = "README.md"
 
-[target.'cfg(unix)'.dependencies]
-libc = "0.2.68"
-
-[target.'cfg(windows)'.dependencies]
-winapi = { version = "0.3.8", features = ["processthreadsapi"] }
+[features]
+default = ["std"]
+std = []
 
 [dev-dependencies]
 crossbeam = "0.7.3"
diff --git a/src/lib.rs b/src/lib.rs
index c4dea41..f5b96ad 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -135,5 +135,5 @@
 pub use crate::task::{spawn, Task};
 pub use crate::waker_fn::waker_fn;
 
-#[cfg(any(unix, windows))]
+#[cfg(feature = "std")]
 pub use crate::task::spawn_local;
diff --git a/src/task.rs b/src/task.rs
index 0c57a85..4d60f07 100644
--- a/src/task.rs
+++ b/src/task.rs
@@ -1,11 +1,10 @@
 use core::fmt;
 use core::future::Future;
 use core::marker::PhantomData;
-use core::mem::{self, ManuallyDrop};
-use core::pin::Pin;
+use core::mem;
 use core::ptr::NonNull;
 use core::sync::atomic::Ordering;
-use core::task::{Context, Poll, Waker};
+use core::task::Waker;
 
 use crate::header::Header;
 use crate::raw::RawTask;
@@ -88,6 +87,9 @@
 /// Unlike [`spawn`], this function does not require the future to implement [`Send`]. If the
 /// [`Task`] reference is run or dropped on a thread it was not created on, a panic will occur.
 ///
+/// **NOTE:** This function is only available when the `std` feature for this crate is enabled (it
+/// is by default).
+///
 /// [`Task`]: struct.Task.html
 /// [`JoinHandle`]: struct.JoinHandle.html
 /// [`spawn`]: fn.spawn.html
@@ -110,7 +112,7 @@
 /// // Create a task with the future and the schedule function.
 /// let (task, handle) = async_task::spawn_local(future, schedule, ());
 /// ```
-#[cfg(any(unix, windows))]
+#[cfg(feature = "std")]
 pub fn spawn_local<F, R, S, T>(future: F, schedule: S, tag: T) -> (Task<T>, JoinHandle<R, T>)
 where
     F: Future<Output = R> + 'static,
@@ -118,20 +120,25 @@
     S: Fn(Task<T>) + Send + Sync + 'static,
     T: Send + Sync + 'static,
 {
-    #[cfg(unix)]
-    #[inline]
-    fn thread_id() -> usize {
-        unsafe { libc::pthread_self() as usize }
-    }
+    extern crate std;
 
-    #[cfg(windows)]
+    use std::mem::ManuallyDrop;
+    use std::pin::Pin;
+    use std::task::{Context, Poll};
+    use std::thread::{self, ThreadId};
+    use std::thread_local;
+
     #[inline]
-    fn thread_id() -> usize {
-        unsafe { winapi::um::processthreadsapi::GetCurrentThreadId() as usize }
+    fn thread_id() -> ThreadId {
+        thread_local! {
+            static ID: ThreadId = thread::current().id();
+        }
+        ID.try_with(|id| *id)
+            .unwrap_or_else(|_| thread::current().id())
     }
 
     struct Checked<F> {
-        id: usize,
+        id: ThreadId,
         inner: ManuallyDrop<F>,
     }