11package scala .runtime
22
3+ import java .lang .reflect .Modifier
34import scala .annotation .since
45
56/**
@@ -24,6 +25,7 @@ object LazyVals {
2425 val processors = java.lang.Runtime .getRuntime.nn.availableProcessors()
2526 8 * processors * processors
2627 }
28+
2729 private [this ] val monitors : Array [Object ] =
2830 Array .tabulate(base)(_ => new Object )
2931
@@ -39,6 +41,41 @@ object LazyVals {
3941
4042 /* ------------- Start of public API ------------- */
4143
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+
4279 final val BITS_PER_LAZY_VAL = 2L
4380
4481 def STATE (cur : Long , ord : Int ): Long = {
@@ -56,6 +93,12 @@ object LazyVals {
5693 unsafe.compareAndSwapLong(t, offset, e, n)
5794 }
5895
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+
59102 def setFlag (t : Object , offset : Long , v : Int , ord : Int ): Unit = {
60103 if (debug)
61104 println(s " setFlag( $t, $offset, $v, $ord) " )
@@ -108,6 +151,13 @@ object LazyVals {
108151 r
109152 }
110153
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+
111161 @ since(" 3.2" )
112162 def getOffsetStatic (field : java.lang.reflect.Field ) =
113163 val r = unsafe.objectFieldOffset(field)
@@ -117,11 +167,18 @@ object LazyVals {
117167
118168
119169 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"
120175 final val state = " STATE"
121176 final val cas = " CAS"
177+ final val objCas = " objCAS"
122178 final val setFlag = " setFlag"
123179 final val wait4Notification = " wait4Notification"
124180 final val get = " get"
125181 final val getOffset = " getOffset"
182+ final val getStaticOffset = " getStaticOffset"
126183 }
127184}
0 commit comments