aboutsummaryrefslogtreecommitdiff
path: root/kamon-core/src/main/scala/kamon/context/Storage.scala
diff options
context:
space:
mode:
Diffstat (limited to 'kamon-core/src/main/scala/kamon/context/Storage.scala')
-rw-r--r--kamon-core/src/main/scala/kamon/context/Storage.scala33
1 files changed, 26 insertions, 7 deletions
diff --git a/kamon-core/src/main/scala/kamon/context/Storage.scala b/kamon-core/src/main/scala/kamon/context/Storage.scala
index 4f4e6cbb..f116142d 100644
--- a/kamon-core/src/main/scala/kamon/context/Storage.scala
+++ b/kamon-core/src/main/scala/kamon/context/Storage.scala
@@ -15,6 +15,8 @@
package kamon.context
+import kamon.context.Storage.ThreadLocal.ContextHolder
+
trait Storage {
def current(): Context
def store(context: Context): Storage.Scope
@@ -27,28 +29,45 @@ object Storage {
def close(): Unit
}
-
+ /**
+ * Wrapper that implements optimized {@link ThreadLocal} access pattern ideal for heavily used
+ * ThreadLocals.
+ *
+ * It is faster to use a mutable holder object and always perform ThreadLocal.get() and never use
+ * ThreadLocal.set(), because the value is more likely to be found in the ThreadLocalMap direct hash
+ * slot and avoid the slow path ThreadLocalMap.getEntryAfterMiss().
+ *
+ * Important: this thread local will live in ThreadLocalMap forever, so use with care.
+ */
class ThreadLocal extends Storage {
- private val tls = new java.lang.ThreadLocal[Context]() {
- override def initialValue(): Context = Context.Empty
+ private val tls = new java.lang.ThreadLocal[ContextHolder]() {
+ override def initialValue() = new ContextHolder(Context.Empty)
}
override def current(): Context =
- tls.get()
+ get()
override def store(context: Context): Scope = {
val newContext = context
- val previousContext = tls.get()
- tls.set(newContext)
+ val previousContext = get()
+ set(newContext)
new Scope {
override def context: Context = newContext
- override def close(): Unit = tls.set(previousContext)
+ override def close(): Unit = set(previousContext)
}
}
+
+ private def get():Context =
+ tls.get().value
+
+ private def set(value:Context) : Unit =
+ tls.get().value = value
}
object ThreadLocal {
def apply(): ThreadLocal = new ThreadLocal()
+
+ final class ContextHolder(var value:Context)
}
} \ No newline at end of file