From 11e0e6d6cde876fb4810596c2c5cb116601c0f42 Mon Sep 17 00:00:00 2001
From: Philippe Canal <pcanal@fnal.gov>
Date: Thu, 18 Feb 2021 11:26:19 -0600
Subject: [PATCH] TIsAProxy switch fClass to non-atomic.

Since fClass is modified only 'once' at init time of the IsAProxy object, it is actual more efficient
to protect the initialization by a lock rather than having fClass being atomic.
---
 core/meta/inc/TIsAProxy.h   |  2 +-
 core/meta/src/TIsAProxy.cxx | 15 +++++++--------
 2 files changed, 8 insertions(+), 9 deletions(-)

diff --git a/core/meta/inc/TIsAProxy.h b/core/meta/inc/TIsAProxy.h
index 2680824b4c1..5b43db54e9a 100644
--- a/core/meta/inc/TIsAProxy.h
+++ b/core/meta/inc/TIsAProxy.h
@@ -36,7 +36,7 @@ private:
    static constexpr UInt_t fgMaxLastSlot = 8;
 
    const std::type_info     *fType;        //Actual typeid of the proxy
-   Atomic_t<TClass*>         fClass;       //Actual TClass
+   TClass                   *fClass;       //Actual TClass
    Char_t                    fSubTypes[72];//map of known sub-types
    mutable Atomic_t<UInt_t>  fSubTypesReaders; //number of readers of fSubTypes
    Atomic_t<Bool_t>          fSubTypesWriteLockTaken; //True if there is a writer
diff --git a/core/meta/src/TIsAProxy.cxx b/core/meta/src/TIsAProxy.cxx
index 5039c659945..22e197ce53b 100644
--- a/core/meta/src/TIsAProxy.cxx
+++ b/core/meta/src/TIsAProxy.cxx
@@ -85,30 +85,29 @@ void TIsAProxy::SetClass(TClass *cl)
 TClass* TIsAProxy::operator()(const void *obj)
 {
    if ( !fInit )  {
-      if ( !fClass.load() && fType ) {
-         auto cls = TClass::GetClass(*fType);
-         TClass* expected = nullptr;
-         fClass.compare_exchange_strong(expected,cls);
+      R__WRITE_LOCKGUARD(ROOT::gCoreMutex);
+      if ( !fClass && fType ) {
+         fClass = TClass::GetClass(*fType);
       }
-      if ( !fClass.load() ) return nullptr;
+      if ( !fClass ) return nullptr;
       fVirtual = (*fClass).ClassProperty() & kClassHasVirtual;
       fInit = kTRUE;
    }
    if ( !obj || !fVirtual )  {
-      return fClass.load();
+      return fClass;
    }
    // Avoid the case that the first word is a virtual_base_offset_table instead of
    // a virtual_function_table
    Long_t offset = **(Long_t**)obj;
    if ( offset == 0 ) {
-      return fClass.load();
+      return fClass;
    }
 
    DynamicType* ptr = (DynamicType*)obj;
    const std::type_info* typ = &typeid(*ptr);
 
    if ( typ == fType )  {
-     return fClass.load();
+     return fClass;
    }
    for(auto& slot : fLasts) {
       auto last = ToPair(slot);
-- 
GitLab