Created
December 24, 2016 18:52
-
-
Save tonsky/62a7ec6d539fc013186bee2df0812cf6 to your computer and use it in GitHub Desktop.
This file contains hidden or 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
(defn race | |
"Runs two fns in tight loops in two parallel threads for 1 second" | |
[publish-fn check-fn] | |
(println "---") | |
(let [*run? (volatile! true) | |
*failures (volatile! 0) | |
thread! #(future | |
(loop [i 0] | |
(% i) | |
(if @*run? (recur (inc i)) i))) | |
*t1 (thread! publish-fn) | |
*t2 (thread! #(when-not (check-fn %) | |
(vswap! *failures inc) | |
(println "failure at step" %)))] | |
(Thread/sleep 1000) | |
(vreset! *run? false) | |
{ :runs @*t1 | |
:checks @*t2 | |
:failures @*failures })) | |
(defn race-set | |
"Checks set implementation: are insertions made by one thread visible from another?" | |
[ctor conj contains?] | |
(let [*value (volatile! (rand)) | |
*set (volatile! (ctor [@*value])) | |
publish (fn [_] ;; publish gurantees that value is ALWAYS in a set | |
(let [next-value (rand)] | |
;; it first puts value into a set | |
(vswap! *set conj next-value) | |
;; only then it updates value ref | |
;; fact: when we observe value it means it was already put in a set | |
(vreset! *value next-value))) | |
check (fn [_] ;; checks if value is visible in a set | |
(let [value @*value | |
set @*set] | |
;; fact: if we observe some value it was already put in a set | |
(contains? set value)))] | |
(race publish check))) | |
;; transient sets fails race-set | |
;; presumably because it uses mutable Object[] in ArrayNode/BitmapIndexedNode | |
;; (your results may vary. Better to run `race-set` multiple times) | |
;; --- | |
;; failure at step 3287 | |
;; failure at step 229042 | |
;; failure at step 2717018 | |
(race-set #(transient (set %)) | |
conj! | |
#(.contains ^clojure.lang.ITransientSet %1 %2)) | |
;; persistent set is ok | |
(race-set set conj contains?) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment