The Computer Language
Benchmarks Game

thread-ring F# .NET Core #2 program

source code

(*  The Computer Language Benchmarks Game
    http://benchmarksgame.alioth.debian.org/

    Contributed by Dmitry Lomov & Jomo Fisher

    Uses F# asyncs (lightweight threads) with customized auto reset cell 
    as semaphore.
*)

let ringLength = 503

type AutoResetCell() =
    let mutable value = -1
    let mutable run = None
    
    member this.RegisterResult res =
        let grabbed = 
            lock this (fun () ->
                match run with
                | None -> value <- res; None
                | grabbed -> run <- None; grabbed)
        match grabbed with
        | None -> ()
        | Some run -> run res

    member this.AsyncResult = 
        Async.FromContinuations(fun (success,_,_) -> 
            let runNow = 
                lock this (fun () ->
                    if value = -1 then
                        run <- Some success
                        false                        
                    else true)                        
            if runNow then 
                let r = value
                value <- -1 // Autoreset
                success r) 

let createCell _ = AutoResetCell()

let createThread (cells:AutoResetCell array) i =
    let next = if i = ringLength-1 then 0 else i + 1
    async {
            let more = ref true
            while !more do
                let! msg = cells.[i].AsyncResult 
                cells.[next].RegisterResult(msg-1)           
                more := msg>0
                if msg = 0 then                    
                    printfn "%d" (i+1) }

[<EntryPoint>]
let main args = 
    let count = if args.Length>0 then int args.[0] else 50000000
    
    let cells = Array.init ringLength createCell

    let threads = Array.init ringLength (createThread cells)

    cells.[0].RegisterResult(count) 

    threads
        |> Async.Parallel // Run all the asyncs at once
        |> Async.Ignore // Ignore the results
        |> Async.RunSynchronously // Block the main thread until work is done
    
    0
    

notes, command-line, and program output

NOTES:
64-bit Ubuntu quad core
2.0.2 a04b4bf512
"System.GC.Server": true


Thu, 09 Nov 2017 01:04:55 GMT

MAKE:
cp threadring.fsharpcore-2.fsharpcore Program.fs
cp Include/fsharpcore/tmp.fsproj .
cp Include/fsharpcore/runtimeconfig.template.json .
mkdir obj
cp Include/fsharpcore/project.assets.json ./obj
cp Include/fsharpcore/tmp.fsproj.nuget.g.props ./obj
cp Include/fsharpcore/tmp.fsproj.nuget.g.targets ./obj
/usr/bin/dotnet build -c Release --no-restore
Microsoft (R) Build Engine version 15.4.8.50001 for .NET Core
Copyright (C) Microsoft Corporation. All rights reserved.

  tmp -> /home/dunham/benchmarksgame_quadcore/threadring/tmp/bin/Release/netcoreapp2.0/tmp.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:09.56

10.08s to complete and log all make actions

COMMAND LINE:
/usr/bin/dotnet ./bin/Release/netcoreapp2.0/tmp.dll 50000000

PROGRAM OUTPUT:
292