![]() | ![]() | ![]() | Event handling flow of control | ![]() |
Events are read out in response to a trigger. The trigger is represented as a function object derived from CTrigger. The object's operator() returns a true value when a trigger has been received.
Triggers are polled for in a separate trigger thread. This design allows the system to be responsive to commands while keeping the average trigger latency very low (measured at about 3µsec). The trigger thread polls for the trigger in an inner loop while an outer loop checks periodically to see if it has been asked to exit.
The trigger loop thread object contains a pointer to the experiment object. The main trigger loop is shown below:
while(!m_Exiting) { struct timeval mutexstart; struct timeval mutexend; struct timezone tz; // Unused but required for gettimeofday(2). int dwell; // // Lock the mutex and process triggers for the // dwell time. The trigger is checked several times // to amortize gettimeofday(). // gettimeofday(&mutexstart, &tz); CApplicationSerializer::getInstance()->Lock(); do { for(int i = 0; i < 500; i++) { int triggers=0; if((*m_pTrigger)()) { // Read an event... m_pExperiment->ReadEvent(); if((triggers++) >= m_nTriggerdwell) break; // Check elapsed time. } } // If we've held the mutex for longer than m_msHoldTime, // release the mutex so that other threads get a chance to run. // gettimeofday(&mutexend, &tz); int secdif = mutexend.tv_sec - mutexstart.tv_sec; mutexend.tv_usec += SECOND*secdif; dwell = (mutexend.tv_usec - mutexstart.tv_usec)/MILISECOND; } while(dwell < m_msHoldTime); CApplicationSerializer::getInstance()->UnLock(); }
Several points to note:
Event readout, once initiated executes within the context of the trigger thread with the global synchronization mutex already acquired.
![]() | ![]() | ![]() | Event handling flow of control | ![]() |