Commit c82064f8 authored by Giuseppe Carboni's avatar Giuseppe Carboni Committed by GitHub
Browse files

Fix #431, dropped the use of the SecureArea in the AntennaBoss WatchingThread (#432)

* Fix #431, dropped the use of the SecureArea in the AntennaBoss WatchingThread

The AntennaBoss WatchingThread is now free to run without being blocked by a SecureArea. This allows both the WatchingThread and the WorkingThread to be executed in parallel. This was tested using the SRT ACU simulator. The test has been running for more than one hour without issues. Further testing with the SRT will be performed soon (2019/07/25). This SHOULD NOT break the MedicinaMount, but it was not tested, so I'm not 100% sure.

P.S.: I also tried a setup with both threads not protected by a SecureArea, but after a while the tracking behaved unexpectedly, sending to the ACU a set of coordinates with an elevation of more than 2000 degrees. This behavior was most likely caused by the WorkingThread not protected by the SecureArea.

* Fix #431, improved synchronization between AntennaBoss threads

The load/unloadMount, load/unloadRefraction load/unloadPointingModel methods are now thread safe in order to minimize (unfortunately not avoid completely) concurrency errors between the AntennaBoss WatchingThread and WorkingThread
The TimeTaggedCircularArray object is now thread safe.
parent 4ba390ee
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
/* Andrea Orlati(aorlati@ira.inaf.it) 31/01/2008      changed the algorithm of selectPoint()                                          */
/* Andrea Orlati(aorlati@ira.inaf.it) 31/01/2008      fixed a bug in selectPoint() that causes  problem when longitude crosses the 360  */
/* Andrea Orlati(aorlati@ira.inaf.it) 08/09/2010      added the averagePoint method */
/* G. Carboni(giuseppe.carboni@inaf.it) 26/07/2019    the class is now thread safe                      */

#include <acstimeEpochHelper.h>
#include "Definitions.h"
@@ -161,6 +162,7 @@ protected:
private:
	CTimeTaggedCircularArray(const CTimeTaggedCircularArray&);
	const CTimeTaggedCircularArray& operator =(const CTimeTaggedCircularArray& src);
	mutable BACIMutex m_mutex;
};
	
}
+13 −2
Original line number Diff line number Diff line
@@ -25,11 +25,13 @@ CTimeTaggedCircularArray::~CTimeTaggedCircularArray()

void CTimeTaggedCircularArray::empty()
{
	baci::ThreadSyncGuard guard(&m_mutex);
	m_head=m_free=0;	
}

bool CTimeTaggedCircularArray::addPoint(const double& azimuth,const double& elevation,const TIMEVALUE& time)
{
	baci::ThreadSyncGuard guard(&m_mutex);
	TIMEVALUE *tmp;
	if (isEmpty()) {
	}
@@ -47,6 +49,7 @@ bool CTimeTaggedCircularArray::addPoint(const double& azimuth,const double& elev

bool CTimeTaggedCircularArray::getPoint(unsigned pos,double& azimuth,double& elevation,TIMEVALUE& time) const
{
	baci::ThreadSyncGuard guard(&m_mutex);
	unsigned ss,pp;
	if (isEmpty()) return false;
	ss=elements();
@@ -60,21 +63,25 @@ bool CTimeTaggedCircularArray::getPoint(unsigned pos,double& azimuth,double& ele

const double& CTimeTaggedCircularArray::getLastAzimuth() const
{
	baci::ThreadSyncGuard guard(&m_mutex);
	return m_lastAzimuth;
}

const double& CTimeTaggedCircularArray::getLastElevation() const
{
	baci::ThreadSyncGuard guard(&m_mutex);
	return m_lastElevation;
}

const TIMEVALUE& CTimeTaggedCircularArray::getLastTime() const
{
	baci::ThreadSyncGuard guard(&m_mutex);
	return m_lastTime;
}

unsigned CTimeTaggedCircularArray::elements() const
{
	baci::ThreadSyncGuard guard(&m_mutex);
	if (isEmpty()) return 0;
	if (m_head>m_free) return (m_size-m_head)+m_free;
	else return m_free-m_head;
@@ -82,6 +89,7 @@ unsigned CTimeTaggedCircularArray::elements() const

void CTimeTaggedCircularArray::purge(const TIMEVALUE& time)
{
	baci::ThreadSyncGuard guard(&m_mutex);
	unsigned ss=elements();
	unsigned pp=0;
	for (unsigned i=0;i<ss;i++) {
@@ -93,6 +101,7 @@ void CTimeTaggedCircularArray::purge(const TIMEVALUE& time)

void CTimeTaggedCircularArray::addOffsets(const double& azOff,const double& elOff,const TIMEVALUE& time)
{
	baci::ThreadSyncGuard guard(&m_mutex);
	unsigned ss=elements();
	unsigned pp=0;
	for (unsigned i=0;i<ss;i++) {
@@ -103,6 +112,7 @@ void CTimeTaggedCircularArray::addOffsets(const double& azOff,const double& elOf

void CTimeTaggedCircularArray::selectPoint(const TIMEVALUE& time,double& azimuth,double& elevation) const
{
	baci::ThreadSyncGuard guard(&m_mutex);
	unsigned ss=elements();
	unsigned pp=0;
	TArrayRecord m1,m2;
@@ -185,6 +195,7 @@ void CTimeTaggedCircularArray::selectPoint(const TIMEVALUE& time,double& azimuth

void CTimeTaggedCircularArray::averagePoint(const TIMEVALUE& startTime,const TIMEVALUE& stopTime,double& azimuth,double& elevation) const
{
	baci::ThreadSyncGuard guard(&m_mutex);
	unsigned scroller;
	unsigned elem=elements();
	double avgAz=0.0,avgEl=0.0;
+4 −0
Original line number Diff line number Diff line
@@ -639,6 +639,10 @@ private:
	 * This is the reference to the refraction component
	 */
	Antenna::Refraction_var m_refraction;
	/**
	 * Mutexes in order to synchronize loadMount, unloadMount, loadRefraction, unloadRefraction, loadPointingModel, unloadPointingModel
	*/
	mutable BACIMutex m_mountMutex, m_pmMutex, m_refractionMutex;
	/**
	 * if this flag is false no action is taken by the component
	*/ 
+2 −2
Original line number Diff line number Diff line
@@ -27,7 +27,7 @@ public:
     * @param responseTime thread's heartbeat response time in 100ns unit. Default value is 1s.
     * @param sleepTime thread's sleep time in 100ns unit. Default value is 100ms.
    */
	CWatchingThread(const ACE_CString& name,IRA::CSecureArea<CBossCore>  *param, 
	CWatchingThread(const ACE_CString& name,CBossCore *param,
			const ACS::TimeInterval& responseTime=ThreadBase::defaultResponseTime,const ACS::TimeInterval& sleepTime=ThreadBase::defaultSleepTime);

	/**
@@ -51,7 +51,7 @@ public:
     */
     virtual void runLoop();
private:
	IRA::CSecureArea<CBossCore> *m_core;
	CBossCore *boss;
};

#endif /*WATCHINGTHREAD_H_*/
+2 −2
Original line number Diff line number Diff line
@@ -151,8 +151,8 @@ void AntennaBossImpl::initialize() throw (ACSErr::ACSbaseExImpl)
	}
	boss->initialize(); //could throw (ComponentErrors::UnexpectedExImpl)
	try {
		m_watchingThread=getContainerServices()->getThreadManager()->create<CWatchingThread,CSecureArea<CBossCore> *>
		  ("BOSSWATCHER",m_core);
		m_watchingThread=getContainerServices()->getThreadManager()->create<CWatchingThread,CBossCore*>
		  ("BOSSWATCHER",boss);
		m_workingThread=getContainerServices()->getThreadManager()->create<CWorkingThread,CSecureArea<CBossCore> *>
		  ("BOSSWORKER",m_core);
	}
Loading