LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Thread Execution and Sleep Policy

Hi,
 
I thought I'd posted this but something must have gone wrong. Can someone answer this for me please.
 
I have an app which calls RunUserInterface() in the main thread. There are two secondary threads, one of which does some software timing and must execute as fast as possible. This thread does not wait on anything so I would expect it to occupy the CPU for most of the time, certainly keeping the System Idle thread off the CPU, but this does not happen, the System Idle thread runs most of the time and my apps process only takes <5%.
 
If I change the sleep policy of the main thread then my CVI app's process does take all available CPU time, but shouldn't changing the sleep policy just affect how long the main thread sleeps between RunUserInterface() processing events? Shouldn't my secondary thread run at full speed. Changing the sleep policy of the main thread to 'sleep none' seems to improve the performance of my secondary thread, so is there some inter-dependency here?
 
Any help would be appreciated.
 
Thanks
 
Jamie Fraser
0 Kudos
Message 1 of 8
(4,884 Views)
What are you doing in your secondary thread which is supposed to be heavy user of CPU. If it has nothing much to do, the system idle thread will be running most of the time.
0 Kudos
Message 2 of 8
(4,860 Views)

Hi and thanks for taking the time to reply. In CPU terms there's no such thing as "not much to do", a thread is either 'waiting' for something, in which case it is treated as 'not ready', or it is 'doing' something, in which case it will be treated as 'ready' and scheduled to execute by the Windows Scheduler. If it's not 'waiting' then it's 'doing' and therefore should not allow the System Idle thread any time on the CPU. It's the same reason why a CVI app will take ~100% of the CPU if the sleep policy of RunUserInterace() is set to 'never sleep' - it hasn't got much to do in a useful sense if there are few events to process, but it is 'doing' something in the sense that it continually checks for events without 'waiting' in between. I therefore don't think your reply answers my question and I throw it open to others.

Thanks

Jamie Fraser

0 Kudos
Message 3 of 8
(4,840 Views)
Well, doesn't this only lead us to the conclusion that your thread is WAITING for the most of the time? (In a Sleep(), Delay() or some library function produced  WAIT state) Then of course if this is a Timer or AsyncTimer you are talking about, it just executes for a few milliseconds and dissappears before the next interval when the Timer is invoked again for a few milliseconds.



0 Kudos
Message 4 of 8
(4,832 Views)
Hi,
 
The thread is not called by an asynchronous timer so it's not that, I don't call Sleep() - that really would be a school boy error - but you are right in that it must be waiting, but what for?
 
What I do call in a loop is DAQmxReadCounterScalarU32 () that returns the counter value used to count the number of pulses coming from a signal generator. This function could be waiting for something, but I'd like to know what it's waiting for. The hardware device is a DAQPad-6015 which is a USB device.
 
I'm trying to use the DAQPad to measure pulse intervals (time periods) but this can't be done in hardware because the very small hardware FIFO overflows at very low frequencies because USB polling / latency is not very good. So, I am trying to do the timing in software (I can afford to wait a few seconds and look at the difference in pulse count and divide by the time difference) which means I have to time stamp the returned counter value with as high an accuracy as possible. Maybe the function call is waiting for NI-DAQmx to release a mutex or something like that, but I'd like to know exactly what is happening. Maybe NI-DAQ blocks repeat requests for the counter value before the next USB poll returns - this might well explain what I am seeing.
 
Any more help from anyone?
 
Jamie Fraser
0 Kudos
Message 5 of 8
(4,825 Views)

Hi Jamie

If you look at the help for the function you are calling DAQmxReadCounterScalarU32, then you'll see that the 'timeout' parameter specifies how the function performs. If you set this to -1 (its default) then the function will wait until the specified number of samples are available before returning a result. This could be causing your delays.

**************************************************************************************************************************************************************************************************

DAQmxReadCounterScalarU32

int32 DAQmxReadCounterScalarU32 (TaskHandle taskHandle, float64 timeout, uInt32 *value, bool32 *reserved);

Purpose

Reads a 32-bit integer sample from a counter task. Use this function when the counter sample is returned unscaled, such as for edge counting.

Parameters

Input
Name Type Description
taskHandle TaskHandle The task to read the sample from.
timeout float64 The amount of time, in seconds, to wait for the function to read the sample(s). The default value is 10.0 seconds. To specify an infinite wait, pass -1 (DAQmx_Val_WaitInfinitely). This function returns an error if the timeout elapses.

A value of 0 indicates to try once to read the requested samples. If all the requested samples are read, the function is successful. Otherwise, the function returns a timeout error and returns the samples that were actually read.
reserved bool32 * Reserved for future use. Pass NULL to this parameter.
Output
Name Type Description
value uInt32 * The sample read from the task.

Return Value

Name Type Description
status int32 The error code returned by the function in the event of an error or warning. A value of 0 indicates success. A positive value indicates a warning. A negative value indicates an error.

**********************************************************************************************************************************************************************************************

Make sure you check how you have programmed this part of your application, like JPL6 said, it could be something in a library call.

Regards

Hannah
NIUK & Ireland

0 Kudos
Message 6 of 8
(4,812 Views)

Hi Hannah,

Thanks for your response. I did try changing the time out value from 10.0 to 0 but it didn't make any difference to what I am seeing in terms of CPU loading.

I think now that perhaps it is the USB latency that is the limiting factor but would like confirmation from someone with detailed knowledge of the CVI ADE and DAQmx (perhaps one of the CVI ADE programmers?). Does my call to DAQmxReadCounterScalarU32 () block if NI-DAQmx has initiated a USB poll and is waiting for a response? This could well explain what I am seeing. My laptop only has USB 1.1 and I know that USB 2.0 is better as far as latency is concerned, but I would like to know if this is indeed the reason for what I am seeing before trying to get hold of a laptop that has USB 2.0

All help much appreciated.

Jamie Fraser

0 Kudos
Message 7 of 8
(4,801 Views)

The behavior you are seeing has more to do with DAQmx than CVI. I wrote a small app where the secondary thread was just an empty while loop and I used process explorer to verify that that looping thread was the one taking all of the CPU time.

I'm just throwing this out since I didnt test this with a USB DAQ device, but this KB might explain what you are seeing. If it is important for you to give your secondary thread as much of the CPU time as possible, you can change the read wait mode using the following function

DAQmxSetReadAttribute (taskHandle, DAQmx_Read_WaitMode, DAQmx_Val_Yield);

Hope this helps
Bilal Durrani
NI
Message 8 of 8
(4,770 Views)