@@ -25,6 +25,7 @@ object LazyVals {
2525 val processors = java.lang.Runtime .getRuntime.nn.availableProcessors()
2626 8 * processors * processors
2727 }
28+
2829 private [this ] val monitors : Array [Object ] =
2930 Array .tabulate(base)(_ => new Object )
3031
@@ -40,6 +41,41 @@ object LazyVals {
4041
4142 /* ------------- Start of public API ------------- */
4243
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+
4379 final val BITS_PER_LAZY_VAL = 2L
4480
4581 def STATE (cur : Long , ord : Int ): Long = {
@@ -57,6 +93,12 @@ object LazyVals {
5793 unsafe.compareAndSwapLong(t, offset, e, n)
5894 }
5995
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+
60102 def setFlag (t : Object , offset : Long , v : Int , ord : Int ): Unit = {
61103 if (debug)
62104 println(s " setFlag( $t, $offset, $v, $ord) " )
@@ -110,6 +152,13 @@ object LazyVals {
110152 r
111153 }
112154
155+ def getStaticOffset (clz : Class [_], name : String ): Long = {
156+ val r = unsafe.staticFieldOffset(clz.getDeclaredField(name))
157+ if (debug)
158+ println(s " getStaticOffset( $clz, $name) = $r" )
159+ r
160+ }
161+
113162 def getOffsetStatic (field : java.lang.reflect.Field ) =
114163 @ nowarn
115164 val r = unsafe.objectFieldOffset(field)
@@ -119,11 +168,18 @@ object LazyVals {
119168
120169
121170 object Names {
171+ final val waiting = " Waiting"
172+ final val evaluating = " Evaluating"
173+ final val nullValue = " NULL"
174+ final val waitingAwaitRelease = " awaitRelease"
175+ final val waitingRelease = " release"
122176 final val state = " STATE"
123177 final val cas = " CAS"
178+ final val objCas = " objCAS"
124179 final val setFlag = " setFlag"
125180 final val wait4Notification = " wait4Notification"
126181 final val get = " get"
127182 final val getOffset = " getOffset"
183+ final val getStaticOffset = " getStaticOffset"
128184 }
129185}
0 commit comments