Skip to content

Instantly share code, notes, and snippets.

@hvr
Last active August 29, 2015 14:06
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hvr/d9c08fe0e87075228e41 to your computer and use it in GitHub Desktop.
Save hvr/d9c08fe0e87075228e41 to your computer and use it in GitHub Desktop.
CounterArray based on `fetchAddIntArray#`
{-# LANGUAGE MagicHash #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE UnboxedTuples #-}
{-# LANGUAGE BangPatterns #-}
module RingCounter
( CounterArray
, newCounterArray
, sizeofCounterArray
, readCounterArray
, writeCounterArray
, fetchAddCounterArray
) where
import GHC.Exts
import GHC.Types
#include "MachDeps.h"
data CounterArray = CA !(MutableByteArray# RealWorld)
newCounterArray :: Word -> IO CounterArray
newCounterArray n = IO $ \s -> case newByteArray# sz# s of
(# s', mba# #) -> case setByteArray# mba# 0# sz# 0# s' of
!s'' -> (# s'', CA mba# #)
where
!(I# sz#) = SIZEOF_HSWORD * (fromIntegral n)
sizeofCounterArray :: CounterArray -> Word
sizeofCounterArray (CA mba#) = W# (int2Word# (sizeofMutableByteArray# mba#)) `quot` SIZEOF_HSWORD
readCounterArray :: CounterArray -> Word -> IO Int
readCounterArray (CA mba#) ix = IO $ \s -> case readIntArray# mba# ix# s of
(# s', i# #) -> (# s', I# i# #)
where
!(I# ix#) = fromIntegral $ ix `rem` sizeofCounterArray (CA mba#)
writeCounterArray :: CounterArray -> Word -> Int -> IO ()
writeCounterArray (CA mba#) ix (I# i#) = IO $ \s -> case writeIntArray# mba# ix# i# s of
!s' -> (# s', () #)
where
!(I# ix#) = fromIntegral $ ix `rem` sizeofCounterArray (CA mba#)
fetchAddCounterArray :: CounterArray -> Word -> Int -> IO Int
fetchAddCounterArray (CA mba#) ix (I# i#) = IO $ \s -> case fetchAddIntArray# mba# ix# i# s of
(# !s', i'# #) -> (# s', I# i'# #)
where
!(I# ix#) = fromIntegral $ ix `rem` sizeofCounterArray (CA mba#)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment