never executed always true always false
    1 {-# LANGUAGE CPP #-}
    2 
    3 {-# OPTIONS_GHC -fno-cse #-}
    4 -- -fno-cse is needed for GLOBAL_VAR's to behave properly
    5 
    6 -- | Do not use global variables!
    7 --
    8 -- Global variables are a hack. Do not use them if you can help it.
    9 module GHC.Utils.GlobalVars
   10    ( v_unsafeHasPprDebug
   11    , v_unsafeHasNoDebugOutput
   12    , v_unsafeHasNoStateHack
   13    , unsafeHasPprDebug
   14    , unsafeHasNoDebugOutput
   15    , unsafeHasNoStateHack
   16 
   17    , global
   18    , consIORef
   19    , globalM
   20    , sharedGlobal
   21    , sharedGlobalM
   22    )
   23 where
   24 
   25 -- For GHC_STAGE
   26 #include "ghcplatform.h"
   27 
   28 import GHC.Prelude
   29 
   30 import GHC.Conc.Sync ( sharedCAF )
   31 
   32 import System.IO.Unsafe
   33 import Data.IORef
   34 import Foreign (Ptr)
   35 
   36 #define GLOBAL_VAR(name,value,ty)  \
   37 {-# NOINLINE name #-};             \
   38 name :: IORef (ty);                \
   39 name = global (value);
   40 
   41 #define GLOBAL_VAR_M(name,value,ty) \
   42 {-# NOINLINE name #-};              \
   43 name :: IORef (ty);                 \
   44 name = globalM (value);
   45 
   46 
   47 #define SHARED_GLOBAL_VAR(name,accessor,saccessor,value,ty) \
   48 {-# NOINLINE name #-};                                      \
   49 name :: IORef (ty);                                         \
   50 name = sharedGlobal (value) (accessor);                     \
   51 foreign import ccall unsafe saccessor                       \
   52   accessor :: Ptr (IORef a) -> IO (Ptr (IORef a));
   53 
   54 #define SHARED_GLOBAL_VAR_M(name,accessor,saccessor,value,ty)  \
   55 {-# NOINLINE name #-};                                         \
   56 name :: IORef (ty);                                            \
   57 name = sharedGlobalM (value) (accessor);                       \
   58 foreign import ccall unsafe saccessor                          \
   59   accessor :: Ptr (IORef a) -> IO (Ptr (IORef a));
   60 
   61 
   62 
   63 #if GHC_STAGE < 2
   64 
   65 GLOBAL_VAR(v_unsafeHasPprDebug,      False, Bool)
   66 GLOBAL_VAR(v_unsafeHasNoDebugOutput, False, Bool)
   67 GLOBAL_VAR(v_unsafeHasNoStateHack,   False, Bool)
   68 
   69 #else
   70 SHARED_GLOBAL_VAR( v_unsafeHasPprDebug
   71                  , getOrSetLibHSghcGlobalHasPprDebug
   72                  , "getOrSetLibHSghcGlobalHasPprDebug"
   73                  , False
   74                  , Bool )
   75 SHARED_GLOBAL_VAR( v_unsafeHasNoDebugOutput
   76                  , getOrSetLibHSghcGlobalHasNoDebugOutput
   77                  , "getOrSetLibHSghcGlobalHasNoDebugOutput"
   78                  , False
   79                  , Bool )
   80 SHARED_GLOBAL_VAR( v_unsafeHasNoStateHack
   81                  , getOrSetLibHSghcGlobalHasNoStateHack
   82                  , "getOrSetLibHSghcGlobalHasNoStateHack"
   83                  , False
   84                  , Bool )
   85 #endif
   86 
   87 unsafeHasPprDebug :: Bool
   88 unsafeHasPprDebug = unsafePerformIO $ readIORef v_unsafeHasPprDebug
   89 
   90 unsafeHasNoDebugOutput :: Bool
   91 unsafeHasNoDebugOutput = unsafePerformIO $ readIORef v_unsafeHasNoDebugOutput
   92 
   93 unsafeHasNoStateHack :: Bool
   94 unsafeHasNoStateHack = unsafePerformIO $ readIORef v_unsafeHasNoStateHack
   95 
   96 {-
   97 ************************************************************************
   98 *                                                                      *
   99                         Globals and the RTS
  100 *                                                                      *
  101 ************************************************************************
  102 
  103 When a plugin is loaded, it currently gets linked against a *newly
  104 loaded* copy of the GHC package. This would not be a problem, except
  105 that the new copy has its own mutable state that is not shared with
  106 that state that has already been initialized by the original GHC
  107 package.
  108 
  109 (Note that if the GHC executable was dynamically linked this
  110 wouldn't be a problem, because we could share the GHC library it
  111 links to; this is only a problem if DYNAMIC_GHC_PROGRAMS=NO.)
  112 
  113 The solution is to make use of @sharedCAF@ through @sharedGlobal@
  114 for globals that are shared between multiple copies of ghc packages.
  115 -}
  116 
  117 -- Global variables:
  118 
  119 global :: a -> IORef a
  120 global a = unsafePerformIO (newIORef a)
  121 
  122 consIORef :: IORef [a] -> a -> IO ()
  123 consIORef var x =
  124   atomicModifyIORef' var (\xs -> (x:xs,()))
  125 
  126 globalM :: IO a -> IORef a
  127 globalM ma = unsafePerformIO (ma >>= newIORef)
  128 
  129 -- Shared global variables:
  130 
  131 sharedGlobal :: a -> (Ptr (IORef a) -> IO (Ptr (IORef a))) -> IORef a
  132 sharedGlobal a get_or_set = unsafePerformIO $
  133   newIORef a >>= flip sharedCAF get_or_set
  134 
  135 sharedGlobalM :: IO a -> (Ptr (IORef a) -> IO (Ptr (IORef a))) -> IORef a
  136 sharedGlobalM ma get_or_set = unsafePerformIO $
  137   ma >>= newIORef >>= flip sharedCAF get_or_set