Commit 16149668 authored by Pavel Vainerman's avatar Pavel Vainerman

(IONotifyController): оптимизация: попытка уменьшить количество вызовов

chrono::clock::now(), а также попытка убрать лишние "создания объектов"
parent 646bf7b9
...@@ -67,7 +67,7 @@ namespace UniSetTypes ...@@ -67,7 +67,7 @@ namespace UniSetTypes
// для оптимизации, делаем конструктор который не будет инициализировать свойства класса // для оптимизации, делаем конструктор который не будет инициализировать свойства класса
// это необходимо для VoidMessage, который конструируется при помощи memcpy // это необходимо для VoidMessage, который конструируется при помощи memcpy
Message( int dummy_init ) {} explicit Message( int dummy_init ) {}
template<class In> template<class In>
static const TransportMessage transport(const In& msg) static const TransportMessage transport(const In& msg)
...@@ -123,19 +123,19 @@ namespace UniSetTypes ...@@ -123,19 +123,19 @@ namespace UniSetTypes
{ {
public: public:
ObjectId id; ObjectId id = { UniSetTypes::DefaultObjectId };
long value; long value = { 0 };
bool undefined; bool undefined = { false };
// время изменения состояния датчика // время изменения состояния датчика
struct timespec sm_tv; struct timespec sm_tv = { 0, 0 };
UniversalIO::IOType sensor_type; UniversalIO::IOType sensor_type = { UniversalIO::DI };
IOController_i::CalibrateInfo ci; IOController_i::CalibrateInfo ci;
// для пороговых датчиков // для пороговых датчиков
bool threshold; /*!< TRUE - сработал порог, FALSE - порог отключился */ bool threshold = { false }; /*!< TRUE - сработал порог, FALSE - порог отключился */
UniSetTypes::ThresholdId tid; UniSetTypes::ThresholdId tid = { UniSetTypes::DefaultThresholdId };
SensorMessage( SensorMessage&& m) = default; SensorMessage( SensorMessage&& m) = default;
SensorMessage& operator=(SensorMessage&& m) = default; SensorMessage& operator=(SensorMessage&& m) = default;
...@@ -148,6 +148,12 @@ namespace UniSetTypes ...@@ -148,6 +148,12 @@ namespace UniSetTypes
UniversalIO::IOType st = UniversalIO::AI, UniversalIO::IOType st = UniversalIO::AI,
ObjectId consumer = UniSetTypes::DefaultObjectId); ObjectId consumer = UniSetTypes::DefaultObjectId);
// специальный конструктор, для оптимизации
// он не инициализирует поля по умолчанию
// и за инициализацию значений отвечает "пользователь"
// например см. IONotifyController::localSetValue()
explicit SensorMessage( int dummy );
SensorMessage(const VoidMessage* msg); SensorMessage(const VoidMessage* msg);
inline TransportMessage transport_msg() const inline TransportMessage transport_msg() const
{ {
......
...@@ -288,9 +288,12 @@ void IOController::localSetValue( std::shared_ptr<USensorInfo>& usi, ...@@ -288,9 +288,12 @@ void IOController::localSetValue( std::shared_ptr<USensorInfo>& usi,
usi->supplier = sup_id; // запоминаем того кто изменил usi->supplier = sup_id; // запоминаем того кто изменил
bool blocked = ( usi->blocked || usi->undefined ); bool blocked = ( usi->blocked || usi->undefined );
changed = ( usi->value != value ); changed = ( usi->real_value != value );
if( changed || blocked ) // если поменялось состояние блокировки
bool blockChanged = ( blocked != (usi->value == usi->d_off_value ) );
if( changed || blockChanged )
{ {
ulog4 << myname << ": save sensor value (" << usi->si.id << ")" ulog4 << myname << ": save sensor value (" << usi->si.id << ")"
<< " name: " << uniset_conf()->oind->getNameById(usi->si.id) << " name: " << uniset_conf()->oind->getNameById(usi->si.id)
......
...@@ -384,28 +384,48 @@ void IONotifyController::localSetValue( std::shared_ptr<IOController::USensorInf ...@@ -384,28 +384,48 @@ void IONotifyController::localSetValue( std::shared_ptr<IOController::USensorInf
IOController::localSetValue(usi, value, sup_id); IOController::localSetValue(usi, value, sup_id);
// сравниваем именно с usi->value // Копируем "под замком" только значимые части зависящие от value
// т.к. фактическое сохранённое значение может быть изменено // т.к. всё остальное не меняется в процессе работы программы и по сути readonly
// фильтрами или блокировками.. CORBA::Long realValue = prevValue;
SensorMessage sm(usi->si.id, usi->value); CORBA::ULong tv_sec = 0;
{ CORBA::ULong tv_nsec = 0;
CORBA::Boolean undefined = false;
IOController_i::CalibrateInfo ci;
// lock // lock
{
uniset_rwmutex_rlock lock(usi->val_lock); uniset_rwmutex_rlock lock(usi->val_lock);
realValue = usi->value;
tv_sec = usi->tv_sec;
tv_nsec = usi->tv_nsec;
undefined = usi->undefined;
ci = usi->ci;
} // unlock value
if( prevValue == usi->value )
return;
// Рассылаем уведомления только в слуае изменения значения // Рассылаем уведомления только в слуае изменения значения
// --------
// сравниваем именно с realValue
// т.к. фактическое сохранённое значение может быть изменено
// фильтрами или блокировками..
if( prevValue == realValue )
return;
SensorMessage sm(1); // <-- вызываем dummy конструктор т.к. потом все поля всё-равно сами инициализируем
{
// lock
// uniset_rwmutex_rlock lock(usi->val_lock);
sm.id = usi->si.id; sm.id = usi->si.id;
sm.node = uniset_conf()->getLocalNode(); sm.node = uniset_conf()->getLocalNode();
sm.value = usi->value; sm.value = realValue;
sm.undefined = usi->undefined; sm.undefined = undefined;
sm.priority = (Message::Priority)usi->priority; sm.priority = (Message::Priority)usi->priority;
sm.supplier = sup_id; // owner_id sm.supplier = sup_id; // owner_id
sm.sensor_type = usi->type; sm.sensor_type = usi->type;
sm.sm_tv.tv_sec = usi->tv_sec; sm.sm_tv.tv_sec = tv_sec;
sm.sm_tv.tv_nsec = usi->tv_nsec; sm.sm_tv.tv_nsec = tv_nsec;
sm.ci = usi->ci; sm.tm = { (long)tv_sec, (long)tv_nsec };
sm.ci = ci;
} // unlock } // unlock
try try
......
...@@ -110,6 +110,12 @@ namespace UniSetTypes ...@@ -110,6 +110,12 @@ namespace UniSetTypes
sm_tv = tm; sm_tv = tm;
} }
SensorMessage::SensorMessage( int dummy ):
Message(1) // вызываем dummy-конструктор, который не инициализирует данные (оптимизация)
{
type = Message::SensorInfo;
}
SensorMessage::SensorMessage(const VoidMessage* msg): SensorMessage::SensorMessage(const VoidMessage* msg):
Message(1) // вызываем dummy-конструктор, который не инициализирует данные (оптимизация) Message(1) // вызываем dummy-конструктор, который не инициализирует данные (оптимизация)
{ {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment