Last active
December 29, 2020 21:54
-
-
Save vietnt/84c7532d70e83dee2545df7507158856 to your computer and use it in GitHub Desktop.
unsafe in f#
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[<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 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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