@@ -22,6 +22,7 @@ object LazyVals {
2222 val processors = java.lang.Runtime .getRuntime.nn.availableProcessors()
2323 8 * processors * processors
2424 }
25+
2526 private [this ] val monitors : Array [Object ] =
2627 Array .tabulate(base)(_ => new Object )
2728
@@ -37,6 +38,41 @@ object LazyVals {
3738
3839 /* ------------- Start of public API ------------- */
3940
41+ /**
42+ * Used to indicate the state of a lazy val that is being
43+ * evaluated and of which other threads await the result.
44+ */
45+ final class Waiting :
46+ private var done = false
47+
48+ /**
49+ * Wakes up waiting threads. Called on completion of the evaluation
50+ * of lazy val's right-hand side.
51+ */
52+ def release (): Unit = synchronized {
53+ done = true
54+ notifyAll()
55+ }
56+
57+ /**
58+ * Awaits the completion of the evaluation of lazy val's right-hand side.
59+ */
60+ def awaitRelease (): Unit = synchronized {
61+ while ! done do wait()
62+ }
63+
64+ /**
65+ * Used to indicate the state of a lazy val that is currently being
66+ * evaluated with no other thread awaiting its result.
67+ */
68+ object Evaluating
69+
70+ /**
71+ * Used to indicate the state of a lazy val that has been evaluated to
72+ * `null`.
73+ */
74+ object NULL
75+
4076 final val BITS_PER_LAZY_VAL = 2L
4177
4278 def STATE (cur : Long , ord : Int ): Long = {
@@ -54,6 +90,12 @@ object LazyVals {
5490 unsafe.compareAndSwapLong(t, offset, e, n)
5591 }
5692
93+ def objCAS (t : Object , offset : Long , exp : Object , n : Object ): Boolean = {
94+ if (debug)
95+ println(s " objCAS( $t, $exp, $n) " )
96+ unsafe.compareAndSwapObject(t, offset, exp, n)
97+ }
98+
5799 def setFlag (t : Object , offset : Long , v : Int , ord : Int ): Unit = {
58100 if (debug)
59101 println(s " setFlag( $t, $offset, $v, $ord) " )
@@ -106,6 +148,13 @@ object LazyVals {
106148 r
107149 }
108150
151+ def getStaticOffset (clz : Class [_], name : String ): Long = {
152+ val r = unsafe.staticFieldOffset(clz.getDeclaredField(name))
153+ if (debug)
154+ println(s " getStaticOffset( $clz, $name) = $r" )
155+ r
156+ }
157+
109158 def getOffsetStatic (field : java.lang.reflect.Field ) =
110159 val r = unsafe.objectFieldOffset(field)
111160 if (debug)
@@ -114,11 +163,18 @@ object LazyVals {
114163
115164
116165 object Names {
166+ final val waiting = " Waiting"
167+ final val evaluating = " Evaluating"
168+ final val nullValued = " NULL"
169+ final val waitingAwaitRelease = " awaitRelease"
170+ final val waitingRelease = " release"
117171 final val state = " STATE"
118172 final val cas = " CAS"
173+ final val objCas = " objCAS"
119174 final val setFlag = " setFlag"
120175 final val wait4Notification = " wait4Notification"
121176 final val get = " get"
122177 final val getOffset = " getOffset"
178+ final val getStaticOffset = " getStaticOffset"
123179 }
124180}
0 commit comments