LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

TSQ callback timing issue

I have setup a simple TSQ similar to the 20-page "Multithreading in LabWindows/CVI" document, p.12, with some small modifications. That is,

int queue;
int panelHandle;
int g_counter = 0;
int main (int argc, char *argv[])
{
if (InitCVIRTE... )
return -1;
if ((panelHandle = LoadPanel(0, ...)
return -1;
// create queue that holds 1000 doubles and grows if needed
CmtNewTSQ(1000, sizeof(double), OPT_TSQ_DYNAMIC_SIZE, &queue);
CmtInstallTSQCallback (queue, EVENT_TSQ_ITEMS_IN_QUEUE, 1,
QueueReadCallback, 0, CmtGetCurrentThreadID(), NULL);
CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, DataAcqThreadFunc,
NULL, NULL);
DisplaPanel (panelHandle);
RunUserInterface();
return 0;
}
void CVICALLBACK QueueReadCallback (int queuehandle,
unsigned int event, int value, void *callbackData)
{
int nItemsInQ = 0;
int i = 0;
int nItemsFlushed = 0;
double MyData[500];

CmtGetTSQAttribute(queue, ATTR_TSQ_ITEMS_IN_QUEUE, &nItemsInQ);
CmtReadTSQData (queue, MyData, nItemsInQ, TSQ_INFINITE_TIMEOUT);

for (i=0; i {
PlotData (panelHandle, PANEL_GRAPH, g_counter, MyData[i]);
g_counter++;
}
// flush out the items just read.
CmtFlushTSQ (queue, nItemsInQ, &nItemsFlushed);
}

int CVICALLBACK QueueReadCallback (int queueHandle,
unsigned int event, int value, coid *callbackData)
{
int nComPort = 1;
int counter = 0;
char szScanBuffer[5];
double dIntensity = 0.0;

while (!quit)
{
counter = 0;
// just asked device to send 300 data points
// So read the 300 points
do
{
ComRd (nComPort, szScanBuffer, 4); //Read the 4-byte int
ConvertIntToIntensity(szScanBuffer, &dIntensity); // Convert the int to an intensity
// write the double intensity to the queue
CmtWriteTSQData (queue, &dIntensity, 1,
TSQ_INFINITE_TIMEOUT, NULL);
counter++;
} while (counter < 300);
}
return 0;
}

In this small app, I am attempting to read each data point as it comes in and put it in the queue so that it can be plotted right away. I do not want to wait for all 300 bytes to come in before plotting (or even 20). This works pretty well but... when it gets near the end of the 300 point read, there are a few bytes left in the queue that do not get plotted. It seems that the last few bytes are read in during the plotting for loop. Then the TSQFlush function gets rid of those that were read in. But since there have been additional items put in the queue, the queue size does not fall below the threshold of 1, so that callback event is not generated for those last few items, and they get stuck.

Is there a way, other than a for or while loop in the QueueReadCallback() to make sure that I get all of those items? For instance, can I force an event to be generated just after exiting the while loop in the QueueDataAcq thread, to make sure that the QueueReadCallback gets a chance to get those last few items?

Thanks.
0 Kudos
Message 1 of 2
(2,911 Views)
Craig,

Check out the sample that ships with CVI called buffnodataloss.prj (under \samples\utility\threading\threadsafequeue\buffnodataloss). The example shows how to use a thread safe queue (very similar to what you are doing) but it ensures that those last items are not thrown away or lost at the end.

Regards,
Azucena
NI
0 Kudos
Message 2 of 2
(2,911 Views)