|
25 | 25 | *
|
26 | 26 | * private var _x: AnyRef = null
|
27 | 27 | * def x: A =
|
28 |
| - * while !_x.isInstanceOf[A] do |
29 |
| - * _x match |
30 |
| - * case null => |
31 |
| - * if CAS(_x, null, Evaluating) then |
32 |
| - * var result = rhs |
33 |
| - * // if result == null then result == NULL |
34 |
| - * if !CAS(x, Evaluating, result) then |
35 |
| - * val lock = _x.asInstanceOf[Waiting] |
36 |
| - * _x = result |
37 |
| - * lock.release(result) |
38 |
| - * // case NULL => |
39 |
| - * // return null |
40 |
| - * case current: Waiting => |
41 |
| - * _x = current.awaitRelease() |
42 |
| - * case _ => |
43 |
| - * CAS(x, Evaluating, new Waiting) |
44 |
| - * // end while |
45 |
| - * current.asInstanceOf[A] |
46 |
| - * |
47 |
| - * def x: A = |
48 | 28 | * _x match
|
49 | 29 | * case current: A =>
|
50 | 30 | * current
|
|
95 | 75 | * whether cache has updated
|
96 | 76 | * - no synchronization operations on reads after the first one
|
97 | 77 | * - If there is contention, we see in addition
|
98 |
| - * - for the initializing thread: a volatile write and a synchronized notifyAll |
| 78 | + * - for the initializing thread: a synchronized notifyAll |
99 | 79 | * - for a reading thread: 0 or 1 CAS and a synchronized wait
|
100 | 80 | *
|
101 | 81 | * Code sizes for getter:
|
102 | 82 | *
|
103 |
| - * this scheme, if nulls are excluded in type: 72 bytes |
| 83 | + * this scheme, if nulls are excluded in type: 72 bytes |
104 | 84 | * current Dotty scheme: 131 bytes
|
105 | 85 | * Scala 2 scheme: 39 bytes + 1 exception handler
|
106 | 86 | *
|
|
111 | 91 | * and normal code
|
112 | 92 | * - no deadlocks (other than those inherent in user code)
|
113 | 93 | * - synchronized code is executed only if there is contention
|
114 |
| - * - simpler that current Dotty scheme |
| 94 | + * - simpler than current Dotty scheme |
115 | 95 | *
|
116 | 96 | * Disadvantages:
|
117 | 97 | *
|
|
0 commit comments