diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,12 @@
+## 0.2 [2018.07.01]
+* `thread-local-storage` now checks that threads calling
+  `Data.TLS.PThread.getTLS` are bound threads, and throws a runtime error if
+  this is not the case.
+
+  For this reason, if you call `getTLS` in a thread spawned by `forkOn`, it
+  will break with this release, so you are encouraged to switch uses of
+  `forkOn` to `forkOS`.
+
 ## 0.1.2 [2017.06.23]
 * Fix the benchmark suite with `criterion-1.2`
 
diff --git a/Data/TLS/PThread/Internal.hs b/Data/TLS/PThread/Internal.hs
--- a/Data/TLS/PThread/Internal.hs
+++ b/Data/TLS/PThread/Internal.hs
@@ -10,6 +10,7 @@
 -- with caution.
 module Data.TLS.PThread.Internal where
 
+import Control.Concurrent (isCurrentThreadBound, rtsSupportsBoundThreads)
 import Control.Monad
 import Control.Exception
 import Data.IORef
@@ -82,8 +83,14 @@
   allC <- newIORef []
   return $! TLS key new allC
 
+-- | Fetches the copy of the TLS variable of the running OS thread.
+--
+-- The returned value is reliable only if the current thread is bound.
+-- For this reason, this function calls 'error' if the current thread is
+-- unbound.
 getTLS TLS{key,mknew,allCopies} = do
   p <- pthread_getspecific key
+  checkBoundness
   if castStablePtrToPtr p == nullPtr then do
     a <- mknew
     sp <- newStablePtr a
@@ -92,6 +99,11 @@
     return a
    else
     deRefStablePtr p
+ where
+  checkBoundness = when rtsSupportsBoundThreads $ do
+    b <- isCurrentThreadBound
+    when (not b) $
+      fail "thread-local-storage: PThread.getTLS used from an unbound thread."
 
 allTLS TLS{allCopies} = do
     ls <- readIORef allCopies
diff --git a/bench/Main.hs b/bench/Main.hs
--- a/bench/Main.hs
+++ b/bench/Main.hs
@@ -14,6 +14,7 @@
 import Data.Atomics.Counter
 
 import Control.Monad
+import Control.Concurrent (forkOS)
 import Control.Concurrent.MVar
 import Data.IORef
 import GHC.Conc
@@ -86,10 +87,10 @@
   -- numCapabilities.
   let totalIters = (fromIntegral iters) * (max numCap numT)
       perThread  = totalIters `quot` numT
-  mvs <- forM [0..numT-1] $ \ n -> do
+  mvs <- replicateM numT $ do
     v <- newEmptyMVar
-    _ <- forkOn n $ do rep perThread (fn x)
-                       putMVar v ()
+    _ <- forkOS $ do rep perThread (fn x)
+                     putMVar v ()
     return v
   forM_ mvs takeMVar
   -- Shut down only when all threads are finished with it:
@@ -101,10 +102,10 @@
 --   This version uses MVar synchronization.
 benchPar1 :: Int -> IO () -> Benchmarkable
 benchPar1 num act = toBenchmarkable $ \ iters -> do
-  mvs <- forM [0..num-1] $ \ n -> do
+  mvs <- replicateM num $ do
     v <- newEmptyMVar
-    _ <- forkOn n $ do rep (fromIntegral iters) act
-                       putMVar v ()
+    _ <- forkOS $ do rep (fromIntegral iters) act
+                     putMVar v ()
     return v
   forM_ mvs takeMVar
 {-# INLINE benchPar1 #-}
@@ -118,7 +119,7 @@
       go = do rep (fromIntegral iters) act
               incrCounter_ 1 done
               waitCounter
-  forM_ [1..num-1] $ \ n -> forkOn n go
+  replicateM_ (num-1) $ forkOS go
   go
 
 {-# INLINE benchPar2 #-}
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -7,6 +7,7 @@
 import Data.IORef
 -- import Foreign.Ptr
 import GHC.Conc
+import Control.Concurrent (forkOS)
 import Control.Concurrent.MVar
 import Control.Monad
 -- import Control.Exception
@@ -33,7 +34,7 @@
   tls <- mkTLS (do putStrLn "  New() called.."
                    newIORef (-1 :: Int))
   mvs <- sequence $ replicate numCap newEmptyMVar
-  forM_ (zip [0..] mvs) $ \(ix,mv) -> forkOn ix $ do
+  forM_ (zip [0..] mvs) $ \(ix,mv) -> forkOS $ do
     r   <- getTLS tls
     n   <- readIORef r
     tid <- myThreadId
diff --git a/thread-local-storage.cabal b/thread-local-storage.cabal
--- a/thread-local-storage.cabal
+++ b/thread-local-storage.cabal
@@ -1,5 +1,5 @@
 name:                thread-local-storage
-version:             0.1.2
+version:             0.2
 synopsis:            Several options for thread-local-storage (TLS) in Haskell.
 description:
    .
@@ -26,6 +26,13 @@
 category:            System
 build-type:          Simple
 cabal-version:       >=1.10
+tested-with:         GHC == 7.6.3
+                   , GHC == 7.8.4
+                   , GHC == 7.10.3
+                   , GHC == 8.0.2
+                   , GHC == 8.2.2
+                   , GHC == 8.4.3
+                   , GHC == 8.6.1
 
 extra-source-files:  CHANGELOG.md, README.md, Data/TLS/TLS_Sig.hs
 
