[SYSTEMML-2073] Fix lost update on lock-free statistics maintenance The recently introduced lock-free statistics maintenance (which significantly reduced contention for high frequency updates), had a problem of lost update in case multiple threads try to insert a missing opcode. This patch hardens the lock-free update for such cases without affecting the common case of existing opcodes.
Project: http://git-wip-us.apache.org/repos/asf/systemml/repo Commit: http://git-wip-us.apache.org/repos/asf/systemml/commit/151f658c Tree: http://git-wip-us.apache.org/repos/asf/systemml/tree/151f658c Diff: http://git-wip-us.apache.org/repos/asf/systemml/diff/151f658c Branch: refs/heads/master Commit: 151f658cd071aea06987eef08596ec179e4eb9c0 Parents: 185ab0e Author: Matthias Boehm <[email protected]> Authored: Mon Jan 15 20:27:02 2018 -0800 Committer: Matthias Boehm <[email protected]> Committed: Mon Jan 15 20:27:02 2018 -0800 ---------------------------------------------------------------------- src/main/java/org/apache/sysml/utils/Statistics.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/systemml/blob/151f658c/src/main/java/org/apache/sysml/utils/Statistics.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/sysml/utils/Statistics.java b/src/main/java/org/apache/sysml/utils/Statistics.java index 414f0e7..c003f30 100644 --- a/src/main/java/org/apache/sysml/utils/Statistics.java +++ b/src/main/java/org/apache/sysml/utils/Statistics.java @@ -533,11 +533,12 @@ public class Statistics * @param timeNanos time in nano seconds */ public static void maintainCPHeavyHitters( String instName, long timeNanos ) { - //maintain instruction entry + //maintain instruction entry (w/ robustness for concurrent updates) InstStats tmp = _instStats.get(instName); if( tmp == null ) { - tmp = new InstStats(); - _instStats.put(instName, tmp); + InstStats tmp0 = new InstStats(); + InstStats tmp1 = _instStats.putIfAbsent(instName, tmp0); + tmp = (tmp1 != null) ? tmp1 : tmp0; } //thread-local maintenance of instruction stats
