Skip to content

[ concurrency ] mutable containers are not thread safe, even though they claim to be #63

@stefan-hoeck

Description

@stefan-hoeck

Run the following on the default Chez backend:

module Concurrent

import Data.BoundedQueue.Unsized.Internal
import Data.BoundedQueue1.Unsized.Internal
import Data.BoundedQueue1.Unsized
import Data.Linear.Ref1
import Data.Vect as V
import System
import System.Concurrency

%default total

ITER : Nat
ITER = 10_000

DELAY : Nat
DELAY = 100_000

inc : BoundedQueue1 s Nat -> Nat -> F1' s
inc q 0     = enqueue q 0
inc q (S k) = inc q k

prog : BoundedQueue1 World Nat -> IO ()
prog q = runIO (forN ITER $ inc q DELAY)

runProg : Nat -> IO (List Nat)
runProg n = do
  q  <- runIO (Unsized.empty 1_000_000_000_000)
  ts <- sequence $ V.replicate n (fork $ prog q)
  traverse_ (\t => threadWait t) ts
  runIO (toList q)

main : IO ()
main = do
  us <- runProg 4
  printLn (length us)

We expect the length of the list extracted from the queue to be exactly 40'000 as we enqueue 10'000 numbers in four threads in parallel. However, the actual number is dramatically smaller: Some of the enqueued values were lost. You might have to tinker with the DELAY value on your system to make sure the four threads actually get a chance of a proper race condition.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions