1
1
package scala .runtime
2
2
3
+ import java .lang .reflect .Modifier
3
4
import scala .annotation .since
4
5
5
6
/**
@@ -24,6 +25,7 @@ object LazyVals {
24
25
val processors = java.lang.Runtime .getRuntime.nn.availableProcessors()
25
26
8 * processors * processors
26
27
}
28
+
27
29
private [this ] val monitors : Array [Object ] =
28
30
Array .tabulate(base)(_ => new Object )
29
31
@@ -39,6 +41,41 @@ object LazyVals {
39
41
40
42
/* ------------- Start of public API ------------- */
41
43
44
+ /**
45
+ * Used to indicate the state of a lazy val that is being
46
+ * evaluated and of which other threads await the result.
47
+ */
48
+ final class Waiting :
49
+ private var done = false
50
+
51
+ /**
52
+ * Wakes up waiting threads. Called on completion of the evaluation
53
+ * of lazy val's right-hand side.
54
+ */
55
+ def release (): Unit = synchronized {
56
+ done = true
57
+ notifyAll()
58
+ }
59
+
60
+ /**
61
+ * Awaits the completion of the evaluation of lazy val's right-hand side.
62
+ */
63
+ def awaitRelease (): Unit = synchronized {
64
+ while ! done do wait()
65
+ }
66
+
67
+ /**
68
+ * Used to indicate the state of a lazy val that is currently being
69
+ * evaluated with no other thread awaiting its result.
70
+ */
71
+ object Evaluating
72
+
73
+ /**
74
+ * Used to indicate the state of a lazy val that has been evaluated to
75
+ * `null`.
76
+ */
77
+ object NULL
78
+
42
79
final val BITS_PER_LAZY_VAL = 2L
43
80
44
81
def STATE (cur : Long , ord : Int ): Long = {
@@ -56,6 +93,12 @@ object LazyVals {
56
93
unsafe.compareAndSwapLong(t, offset, e, n)
57
94
}
58
95
96
+ def objCAS (t : Object , offset : Long , exp : Object , n : Object ): Boolean = {
97
+ if (debug)
98
+ println(s " objCAS( $t, $exp, $n) " )
99
+ unsafe.compareAndSwapObject(t, offset, exp, n)
100
+ }
101
+
59
102
def setFlag (t : Object , offset : Long , v : Int , ord : Int ): Unit = {
60
103
if (debug)
61
104
println(s " setFlag( $t, $offset, $v, $ord) " )
@@ -108,6 +151,13 @@ object LazyVals {
108
151
r
109
152
}
110
153
154
+ def getStaticOffset (clz : Class [_], name : String ): Long = {
155
+ val r = unsafe.staticFieldOffset(clz.getDeclaredField(name))
156
+ if (debug)
157
+ println(s " getStaticOffset( $clz, $name) = $r" )
158
+ r
159
+ }
160
+
111
161
@ since(" 3.2" )
112
162
def getOffsetStatic (field : java.lang.reflect.Field ) =
113
163
val r = unsafe.objectFieldOffset(field)
@@ -117,11 +167,18 @@ object LazyVals {
117
167
118
168
119
169
object Names {
170
+ final val waiting = " Waiting"
171
+ final val evaluating = " Evaluating"
172
+ final val nullValued = " NULL"
173
+ final val waitingAwaitRelease = " awaitRelease"
174
+ final val waitingRelease = " release"
120
175
final val state = " STATE"
121
176
final val cas = " CAS"
177
+ final val objCas = " objCAS"
122
178
final val setFlag = " setFlag"
123
179
final val wait4Notification = " wait4Notification"
124
180
final val get = " get"
125
181
final val getOffset = " getOffset"
182
+ final val getStaticOffset = " getStaticOffset"
126
183
}
127
184
}
0 commit comments