Skip to content

Instantly share code, notes, and snippets.

@vietnt
Last active December 29, 2020 21:54
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save vietnt/84c7532d70e83dee2545df7507158856 to your computer and use it in GitHub Desktop.
Save vietnt/84c7532d70e83dee2545df7507158856 to your computer and use it in GitHub Desktop.
unsafe in f#
[<Struct;StructLayout(LayoutKind.Explicit, Pack=1,Size=32)>]
type Bucket =
struct
[<FieldOffset(0)>]val mutable Free : int64
[<FieldOffset(8)>]val mutable FreeCount: int
[<FieldOffset(12)>]val mutable Used: int
[<FieldOffset(16)>]val mutable Size: int
[<FieldOffset(20)>]val mutable Full: bool
end
static member NewSlice (addr: int64) =
let bucket = Native.cast<Bucket>(addr)
let used = bucket.Used
let res = addr + int64(used)
let size = bucket.Size + SliceHeaderSize
bucket.Full <- used + 2*size > FullBucketSize
bucket.Used <- bucket.Used + size
bucket.Allocated <- bucket.Allocated + 1
res
#nowarn "9"
#nowarn "42"
module Native =
open System
open System.Runtime.InteropServices
[<NoDynamicInvocation>]
let inline cast<'T>(p : int64): byref<'T> = (# "" p : byref<'T> #)
[<NoDynamicInvocation>]
let inline getAddress(p: 'T): int64 = (# "" p: int64 #)
[<NoDynamicInvocation>]
let inline pinArray(p : Array): int64 =
let handle = GCHandle.Alloc (p,GCHandleType.Pinned)
handle.AddrOfPinnedObject() |>
getAddress
let inline allocateAligned align size =
let buf = align + size |> Array.zeroCreate<byte>
let ptr = pinArray buf
let off = (int64 align) - (ptr% (int64 align))
buf, ptr + off, int off
let inline compare source dest size =
let mutable f = source
let mutable t = dest
let mutable d = false
let mutable i = 0
let mutable r = 0
while i < size/8 && not d do
let a = cast<int64> f
let b = cast<int64> t
if a <> b then
d <- true
r <- int (a - b)
f <- f + 8L
t <- t + 8L
i <- i + 1
if d then r
else
let max = size &&&7
i <- 0
while i < max && not d do
let a = cast<byte> (f + int64 i)
let b = cast<byte> (t + int64 i)
if a <> b then
d <- true
r <- int (a - b)
i <- i + 1
r
let inline memoryCopy source dest size =
let mutable f = source
let mutable t = dest
for i = 1 to size/8 do
let x = cast<int64> f
let y = cast<int64> t
y <- x
f <- f + 8L
t <- t + 8L
for i = 1 to (size &&&15)/4 do
let x = cast<int> f
let y = cast<int> t
y <- x
f <- f + 4L
t <- t + 4L
for i = 0 to (size&&&3) do
let x = cast<byte> (f + int64 i)
let y = cast<byte> (t + int64 i)
y <- x
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment