Post by FaisalPost by FaisalPost by Igor TandetnikPost by GoranPost by FaisalIf volatile does the synchronization, why we need the InterLockedXXX
functions?
Volatile does not do any synchronization, you are mistaken.
Actually, as of VC8, the compiler generates memory barrier instructions (on those architectures that need them) when accessing volatile variables. See
http://msdn.microsoft.com/en-us/library/12a04hfd.aspx
the part that talks about acquire and release semantics. This is MS-specific and non-portable.
Post by Goran1. hardware that has no CPU cache and code relies on some peripheral
equipment to change main memory contents
2. concurrent access on a multi-CPU systems with no per-CPU cache
3. concurrent access on a single-CPU system
4. Multi-CPU system that features strong cache coherence - as is the case with all x86 CPUs. Systems with weak cache coherence (the kind where one CPU can write a value to memory but another can observe a stale old value from the cache indefinitely, the kind that provides and requires memory barrier instructions) are actually not all that widespread.
--
With best wishes,
Igor Tandetnik
With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Igor,
Does this would work.
void OnStart()
{
InterlockedExchange( (volatile long*)&m_bStopped, FALSE );
InterlockedExchange( (volatile long*)&m_bRunning, TRUE );
}
****
void OnStart()
{
m_bStopped = FALSE;
m_bRunning = TRUE;
}
works because the thread is not stopped and the thread is running. And in the case of
scripting, script state HAS to be thread-local and therefore requires no synchronization!
Otherwise, you cannot have two threads executing the same script, which must be
asynchronous in each thread.
****>void OnStop()
Post by Faisal{
InterlockedExchange( (volatile long*)&m_bRunning, FALSE );
}
*****
Since the script state has to be per-thread, this member variable has to be a member of
the CWinThread object, and therefore requires no synchronization because there is no
concurrent access.
You always have to examine the complete context; naive solutions that either (a) ignore
synchronization or (b) overuse synchronization when it is not necessary are both wrong.
You have to ask "Who has access to this variable?" "Is it monotonically mutable?" "Is it
thread-local?"
Note that the InterlockedExchange does NOTHING that the assignment statement will not do,
because you don't look at the old value of the variable!
*****
Post by Faisalvoid Execute()
{
if( InterlockedCompareExchange ((volatile long*)&m_bRunning,
TRUE, TRUE) )
****
I don't understand why this matters. Either a script is running or not, which is
thread-local state. It would make no sense to make it, say, a global variable; I don't
understand why you are using a global function here, since this is running in the context
of a thread.
*****> {
Post by Faisal //Do some tasks
}
else
{
if( InterlockedCompareExchange ((volatile long*)&m_bStopped, TRUE,
FALSE) )
{
//Do some tasks
}
}
****
We have found in general that people trying to implement synchronzation "from scratch"
usually get it wrong. Since I cannot understand why you think it has to be atomic, since
it is set only by the thread, I don't see any synchronization requirement at all.
I notice that you are using names like m_bStopped but have not told us what class this is
declared in, but you certainly cannot access a class variable from a global function
called "Execute". Please provide ALL necessary information required to formulate an
answer.
joe
****
Joseph M. Newcomer [MVP]
Web:http://www.flounder.com
MVP Tips:http://www.flounder.com/mvp_tips.htm
Hi Joe,
More details below
//from SignalProcessor,h
class CSignalProcessor
{
public:
void OnScriptingStart();
void OnScriptingStop();
void Execute( long* plData, unisgned int unDataSize );
private:
BOOL m_bScriptStopped;
BOOL m_bScriptRunning;
}
This is called by UI thread when user clicks a menu item
void CSignalProcessor::OnScriptingStart()
{
InterlockedExchange( (volatile long*)&m_bScriptStopped, FALSE );
InterlockedExchange( (volatile long*)&m_bScriptRunning, TRUE );
}
This is called by UI thread when user clicks a menu item
void CSignalProcessor::OnScriptingStop()
{
InterlockedExchange( (volatile long*)&m_bScriptRunning, FALSE );
}
This function is called by the data dispatcher thread. This data
dispatcher thread maintains a queue and sempahore. When the data
acquistion thread reads a data( say frame ) from hardware it is pushed
into the queue and the semaphore is released. Data dispatcher thread
WFMO to signal this semaphore. When this thread is woke-up it dequeues
a frame from queue and the function Excute() of CSignalProcessor is
called.
void CSignalProcessor::Execute( long* plData, unsigned int
unDataSize )
{
//Post a message to mainwindow so that the data will be plotted in a
graph window
m_pMainWnd->PostMessage( UWM_LINEDATAUPDATE, (WPARAM)plData, (LPARAM)
unDataSize );
if( InterlockedCompareExchange ((volatile long*)
&m_bScriptRunning, TRUE, TRUE) )
{
//Scripting is enabled.
//Do some processing on the data and keep it
}
else
{
if( InterlockedCompareExchange ((volatile long*)
&m_bScriptStopped, TRUE,FALSE) )
{
//Scripting stopped
//Combine the data and save in to a file
}
}
}
In this context, do i need the InterlockedXXX operations?