Changes between Version 9 and Version 10 of Building/CrossCompiling/iOS


Ignore:
Timestamp:
Mar 25, 2013 10:12:01 PM (2 years ago)
Author:
StephenBlackheath
Comment:

Remove adjustor pools documentation because adjustor pools are no more

Legend:

Unmodified
Added
Removed
Modified
  • Building/CrossCompiling/iOS

    v9 v10  
    169169Each time you modify your Haskell code you'll need to re-compile from the command line before re-building in Xcode. It is possible to automate this in Xcode if you wish.
    170170
    171 == Adjustor pools ==
    172 
    173 A declaration for a "wrapper" callback looks like this:
    174 
    175 {{{
    176 foreign import ccall safe "wrapper"
    177         mkDelegate :: IO () -> IO (FunPtr (IO ()))
    178 }}}
    179 
    180 To implement these, GHC normally generates a small piece of executable code at runtime, called an "adjustor".  The purpose of these "wrapper" declarations is to generate a C-callable function pointer that executes Haskell code.
    181 
    182 Due to Apple's requirements for code-signing, the iOS kernel enforces a ban on self-modifying code.
    183 
    184 We solve this conundrum by pre-compiling a pool of functions, and allocating from it.  Because the pool size for each wrapper is fixed, this creates the problem that the pool can run out.  If this happens, the application will die with this message:
    185 
    186 {{{
    187 HaskellDraw: internal error: createPooledAdjustor - adjustor pool 'Main_d1tU' is empty (capacity 32)
    188 }}}
    189 
    190 (The name of the module where the "wrapper" was declared appears before the underscore character.)
    191 
    192 Each "wrapper" declaration has its own pool, whose size defaults to 32.  This means that at any one time, there can exist no more than 32 adjustors created by the defined wrapper constructor function (in this example, mkDelegate).  '''Foreign.Ptr.freeHaskellFunPtr''' is the IO action to free an adjustor, and in this implementation this returns it to the pool.
    193 
    194 If the pool is too small for a given application, you can increase it by using a {-# POOLSIZE x #-} pragma, which must appear after the "wrapper" token.  e.g.
    195 
    196 {{{
    197 foreign import ccall safe "wrapper" {-# POOLSIZE 100 #-}
    198         mkDelegate :: IO () -> IO (FunPtr (IO ()))
    199 }}}
    200 
    201 Because pool sizes are limited, it should be considered unsafe to call freeHaskellFunPtr in a finalizer, because garbage collection is not predictable.
    202 
    203 The {{{POOLSIZE}}} pragma generates a compiler warning only on GHC versions where it isn't supported, so in practice it's portable.
    204 
    205171== Loose ends ==
    206172