00001 // Copyright CERN 2012 - Developed in collaboration with GSI 00002 00003 #include <fesa-core/DataStore/DataStore.h> 00004 00005 #include <fesa-core/DataStore/AbstractField.h> 00006 #include <fesa-core/Core/AbstractEquipment.h> 00007 #include <fesa-core/Synchronization/MultiplexingContext.h> 00008 #include <fesa-core/Synchronization/AbstractMultiplexingManager.h> 00009 #include <fesa-core/Utilities/Mutex.h> 00010 #include <fesa-core/Utilities/SharedMutex.h> 00011 #include <fesa-core/Utilities/Lock.h> 00012 #include <fesa-core/Utilities/ParserElements.h> 00013 00014 #include <cmw-log/Logger.h> 00015 00016 #include <iostream> 00017 00018 namespace 00019 { 00020 00021 CMW::Log::Logger& logger = CMW::Log::LoggerFactory::getLogger("FESA.FWK.fesa-core.DataStore.DataStore"); 00022 00023 } 00024 00025 namespace fesa 00026 { 00027 00028 DataStore::DataStore() : 00029 numberOfSettingFields_(0) 00030 { 00031 00032 } 00033 00034 DataStore::~DataStore() 00035 { 00036 00037 } 00038 00039 void DataStore::registerField(AbstractField* pField) 00040 { 00041 if (pField->getType() == Setting) 00042 { 00043 numberOfSettingFields_++; 00044 pFieldCol_.insert(pFieldCol_.begin(), pField); 00045 } 00046 else 00047 { 00048 pFieldCol_.push_back(pField); 00049 } 00050 00051 if (pField->isPersistent()) 00052 { 00053 persistentCol_.push_back(pField); 00054 } 00055 } 00056 00057 AbstractField* DataStore::getField(const std::string& name) 00058 { 00059 for (uint32_t i = 0; i < pFieldCol_.size(); i++) 00060 { 00061 if (pFieldCol_[i]->getName() == name) 00062 { 00063 return pFieldCol_[i]; 00064 } 00065 } 00066 return 0; 00067 } 00068 00069 void DataStore::createMutex(char* pAddrMemory) 00070 { 00071 if (AbstractEquipment::getInstance()->getProcessType() == unsplit) 00072 { 00073 pMutex_ = new Mutex(pAddrMemory); 00074 } 00075 else 00076 { 00077 pMutex_ = new SharedMutex(pAddrMemory); 00078 } 00079 } 00080 00081 void DataStore::synchronizeSettingFields(MultiplexingContext& context) 00082 { 00083 Lock pMutexLock(*pMutex_); 00084 for (uint32_t i = 0; i < numberOfSettingFields_; i++) 00085 { 00086 // do not commit fields that are multiplexed and the context is not multiplexed 00087 // because they cannot be used in the real time action 00088 // it will be the responsibility of another real time action to commit them. 00089 if (context.getType() == MultiplexingContext::NoneCtxt && (pFieldCol_[i]->isMultiplexed())) 00090 { 00091 // This context is not meant to commit a multiplexed field, so just skip it 00092 continue; 00093 } 00094 int32_t idx = 0; 00095 if (pFieldCol_[i]->getMultiplexingManager() != NULL) 00096 { 00097 idx = pFieldCol_[i]->getMultiplexingManager()->getSlot(context); 00098 } 00099 pFieldCol_[i]->commit(idx); 00100 } 00101 } 00102 00103 void DataStore::synchronizeSettingFields() 00104 { 00105 Lock pMutexLock(*pMutex_); 00106 for (uint32_t i = 0; i < numberOfSettingFields_; i++) 00107 { 00108 uint32_t muxDepth = 1; // non mux field has a depth of one slot 00109 if (pFieldCol_[i]->getMultiplexingManager() != NULL) 00110 { 00111 muxDepth = pFieldCol_[i]->getMultiplexingManager()->getDepth(); 00112 } 00113 for (uint32_t idx= 0; idx < muxDepth; ++idx) 00114 { 00115 pFieldCol_[i]->commit(idx); 00116 } 00117 } 00118 } 00119 00120 void DataStore::initializeFromElement(DataStoreElement& element) 00121 { 00122 initialize(); 00123 for (uint32_t fieldIdx = 0; fieldIdx < pFieldCol_.size(); fieldIdx++) 00124 { 00125 FieldElement* fieldElement = element.getFieldElement(pFieldCol_[fieldIdx]->getName()); 00126 if (fieldElement != NULL) 00127 { 00128 pFieldCol_[fieldIdx]->initialize(*fieldElement); 00129 pFieldCol_[fieldIdx]->restore(*fieldElement); 00130 } 00131 } 00132 } 00133 00134 void DataStore::restoreFromElement(DataStoreElement& element) 00135 { 00136 for (uint32_t fieldIdx = 0; fieldIdx < persistentCol_.size(); fieldIdx++) 00137 { 00138 FieldElement* fieldElement = element.getFieldElement(persistentCol_[fieldIdx]->getName()); 00139 if (fieldElement != NULL) 00140 { 00141 persistentCol_[fieldIdx]->restore(*fieldElement); 00142 } 00143 else 00144 { 00145 continue; // either is a new field or the field changed the name, in any case was not found in the persistent file 00146 } 00147 } 00148 } 00149 00150 int32_t DataStore::getMemorySizeToAllocate() 00151 { 00152 int32_t size = 0; 00153 for (uint32_t i = 0; i < pFieldCol_.size(); i++) 00154 { 00155 size += (pFieldCol_[i]->getFieldValueSize() * pFieldCol_[i]->getMuxDepth()); 00156 } 00157 size += getSizeOfAdditionalFields(); 00158 if (AbstractEquipment::getInstance()->getProcessType() == unsplit) 00159 { 00160 size += Mutex::getSize(); 00161 } 00162 else 00163 { 00164 size += SharedMutex::getSize(); 00165 } 00166 return size; 00167 } 00168 00169 void DataStore::mapMemory(char* p, bool initializeFields) 00170 { 00171 { 00172 std::ostringstream msg; 00173 msg << "Mapping " << (void*)p << " end" << std::endl; 00174 LOG_TRACE_IF(logger, msg.str()); 00175 } 00176 00177 for (uint32_t i = 0; i < pFieldCol_.size(); i++) 00178 { 00179 pFieldCol_[i]->setFieldValueAddress(p, initializeFields); 00180 p += pFieldCol_[i]->getFieldValueSize() * pFieldCol_[i]->getMuxDepth(); 00181 } 00182 mapAdditionalFields(p); 00183 p += getSizeOfAdditionalFields(); 00184 createMutex(p); 00185 } 00186 00187 int32_t DataStore::getSizeOfAdditionalFields() 00188 { 00189 return sizeof(bool); // isLoggable and synchronize_ 00190 } 00191 00192 void DataStore::mapAdditionalFields(char* p) 00193 { 00194 } 00195 00196 void DataStore::initialize() 00197 { 00198 } 00199 00200 } // fesa