Commit 16149668 authored by Pavel Vainerman's avatar Pavel Vainerman

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

chrono::clock::now(), а также попытка убрать лишние "создания объектов"
parent 646bf7b9
......@@ -67,7 +67,7 @@ namespace UniSetTypes
// для оптимизации, делаем конструктор который не будет инициализировать свойства класса
// это необходимо для VoidMessage, который конструируется при помощи memcpy
Message( int dummy_init ) {}
explicit Message( int dummy_init ) {}
template<class In>
static const TransportMessage transport(const In& msg)
......@@ -123,19 +123,19 @@ namespace UniSetTypes
{
public:
ObjectId id;
long value;
bool undefined;
ObjectId id = { UniSetTypes::DefaultObjectId };
long value = { 0 };
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;
// для пороговых датчиков
bool threshold; /*!< TRUE - сработал порог, FALSE - порог отключился */
UniSetTypes::ThresholdId tid;
bool threshold = { false }; /*!< TRUE - сработал порог, FALSE - порог отключился */
UniSetTypes::ThresholdId tid = { UniSetTypes::DefaultThresholdId };
SensorMessage( SensorMessage&& m) = default;
SensorMessage& operator=(SensorMessage&& m) = default;
......@@ -148,6 +148,12 @@ namespace UniSetTypes
UniversalIO::IOType st = UniversalIO::AI,
ObjectId consumer = UniSetTypes::DefaultObjectId);
// специальный конструктор, для оптимизации
// он не инициализирует поля по умолчанию
// и за инициализацию значений отвечает "пользователь"
// например см. IONotifyController::localSetValue()
explicit SensorMessage( int dummy );
SensorMessage(const VoidMessage* msg);
inline TransportMessage transport_msg() const
{
......
......@@ -288,9 +288,12 @@ void IOController::localSetValue( std::shared_ptr<USensorInfo>& usi,
usi->supplier = sup_id; // запоминаем того кто изменил
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 << ")"
<< " name: " << uniset_conf()->oind->getNameById(usi->si.id)
......
......@@ -384,28 +384,48 @@ void IONotifyController::localSetValue( std::shared_ptr<IOController::USensorInf
IOController::localSetValue(usi, value, sup_id);
// сравниваем именно с usi->value
// т.к. фактическое сохранённое значение может быть изменено
// фильтрами или блокировками..
SensorMessage sm(usi->si.id, usi->value);
{
// Копируем "под замком" только значимые части зависящие от value
// т.к. всё остальное не меняется в процессе работы программы и по сути readonly
CORBA::Long realValue = prevValue;
CORBA::ULong tv_sec = 0;
CORBA::ULong tv_nsec = 0;
CORBA::Boolean undefined = false;
IOController_i::CalibrateInfo ci;
// 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.node = uniset_conf()->getLocalNode();
sm.value = usi->value;
sm.undefined = usi->undefined;
sm.value = realValue;
sm.undefined = undefined;
sm.priority = (Message::Priority)usi->priority;
sm.supplier = sup_id; // owner_id
sm.sensor_type = usi->type;
sm.sm_tv.tv_sec = usi->tv_sec;
sm.sm_tv.tv_nsec = usi->tv_nsec;
sm.ci = usi->ci;
sm.sm_tv.tv_sec = tv_sec;
sm.sm_tv.tv_nsec = tv_nsec;
sm.tm = { (long)tv_sec, (long)tv_nsec };
sm.ci = ci;
} // unlock
try
......
......@@ -110,6 +110,12 @@ namespace UniSetTypes
sm_tv = tm;
}
SensorMessage::SensorMessage( int dummy ):
Message(1) // вызываем dummy-конструктор, который не инициализирует данные (оптимизация)
{
type = Message::SensorInfo;
}
SensorMessage::SensorMessage(const VoidMessage* msg):
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