LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Need to stop CVI without ProcessSystemEvents

I have a loop that reads a file the user created and it sends and receives RS-232 data at high speed. My program takes < 20 msec per line if I allow the user to select the file and run it without using GetUserEvent() or ProcessSystemEvent(). I wanted to add an "ABORT" button to allow the user to stop the file pre-maturely but when I add the ProcessSystemEvents() or GetUserEvent() call to check if the user hit the ABORT button, it slows my program down to 30-50 msec per line...this is WAY TOO SLOW. Is there a FASTER way to see if the user hit a button? Can I use some other thing on my panel that I can POLL? Is there some FAST function that checks if the user wants to abort the program (e.g. EscKeyHit() or CntlBreakHit() or somehting like that) I need to call this in a loop and it must execute in < 1 ms to be acceptable.
0 Kudos
Message 1 of 9
(5,047 Views)

There are only a few things you can do to try solving your problem. First of all, in case you are reading the file inside the loop I will evaluate if it's possible to read it in memory before the loop in order to reduce disk access which can slow down your process: the time saved in this operation could be used to poll GetUserEvents or ProcessSystemEvents.

If this is not possible or is not as fast as you need, you should consider moving the rs232 loop in a separate thread: Im not sure if this way you can reach the efficiency you want but I see no other solution.

Of course before you do all this you must carefully revise your code to stop or eliminate all processes that can be executed by the call to ProcessSystemEvents ( ) like timers or other events pending in the system.



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 2 of 9
(5,041 Views)

It is a good idea to incorporate ProcessSystemEvents() inside your loop, but of course you don't have to call it every time your code loops. I use Timer() to determine when (about) 250ms has elapsed within a tight loop and then call ProcessSystemEvents() just the once, as a quick check on any GUI input that may need servicing. This still gives good user responsiveness without wasting CPU time by polling events or buttons way faster than someone can hit them.

 

JR

Message 3 of 9
(5,033 Views)
I don't think ProcessSystemEvents is the solution, it is WAY TO SLOW! I need the loop to run AS FAST AS POSSIBLE as I am sending a lot of data over an RS-232 port. The 20-30 ms that ProcessSystemEvents takes seems ridiculous! Isn’t there some other way to QUICKLY allow the user to terminate a “CPU intensive” CVI process without slowing the process down incredibly?
0 Kudos
Message 4 of 9
(5,016 Views)

 

Hello Matthew,

 

Try calling the SetSleepPolicy function with VAL_SLEEP_NONE before the loop. That should cause your loop with ProcessSystemEvents to go noticeably faster.

 

Luis

Message Edited by LuisG on 10-01-2008 11:31 AM
Message 5 of 9
(5,007 Views)
Thanks LuisG, that did it... It is VERY INTERESTING that this is not the default, the default is VAL_SLEEP_MORE. Apparently NI coded the ProcessSystemEvents (and GetUserEvent) to really aggrevate users as shown below. void ProcessSystemEvents(void) { // If user did not call SetSleepPolicy(VAL_SLEEP_NONE) then waste SOME or by default MORE time if (sleepPolicy == VAL_SLEEP_SOME) { Do (ABSOLUTELY NOTHING) for 5-10 milliseconds } else if (sleepPolicy == VAL_SLEEP_MORE) // Really wast time for the unknowing user { Do (ABSOLUTELY NOTHING) for 10-50 milliseconds } Process Events return; }
0 Kudos
Message 6 of 9
(4,985 Views)

The sleep policy of a program is a general setting the programmer must be aware of in order to correctly design its application. According to the on-line help,

 

CVI environment sleep policy—Each time LabWindows/CVI checks an event from the operating system, it can put itself in the background, in sleep mode, for a specified period of time. While LabWindows/CVI is in sleep mode, other applications have more processor time. However, LabWindows/CVI might run slower. You can specify how much LabWindows/CVI sleeps.

 

This attribute can be set in Options >> Environment panel as a general rule, but can be superseded arond some portion of code with SetSleepPolicy ( ) function; note that thedefault sleep policy is SLEEP_SOME and that this option is thread specific (so for example you may want to SLEEP_SOME in the user interface thread and SLEEP_NONE in critical threads).

 



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 7 of 9
(4,969 Views)

did you try to see what is so slow in your implementation ?

 

you tell us you can read a line in 20ms, but i'd like to know more: what is the typical size of a line ? reading a line from a file in 20ms is really slow ! sending it through a COM port should not consume much time since the communication should be buffered by default: when the buffer is not full, sending through a COM port is as fast as calling memcpy.

you also said you need the software to send the data fast. can you define fast ? a COM port at 115000bps will not send more than about 20KB per second: that is not fast by today's standards. what is critical to you: speed or throughput ? at last, the OS is not really fast at reacting to user events (especially when the CPU is overloaded). a 10ms reaction time is typical, but it seems to be problematic for you. can you tell us why ?

 

so, here are some hints:

- do you really need to send the file line by line ? can't  you read a bigger block of data (like 1KB or more) and send it at once ?

- are you sure that your current implementation is optimal ? can't you improve it ? for example: using static buffers instead of dynamic buffer allocation, removing unused or dead code, moving part of the code out of the loop

- are you sure about your software design ? can't you improve the design ? by using threads, or Windows facilities (overlapped I/O or such)

Message Edited by dummy_decoy on 10-06-2008 11:13 AM
0 Kudos
Message 8 of 9
(4,912 Views)
There is no need to continue this discussion thread. The SOLUTION is as LuisG suggested to use the "SetSleepPolicy(VAL_SLEEP_NONE);" call prior to using the ProcessSystemEvents() call. Is the code as efficent as it could be...probably not...but I know all about effiecent code having written code for embedded systems for over 25 years. Making my code more efficient WOULD NOT fix the fact that ProcessSystemEvents takes 30-50 ms by default and takes <1 ms when you use "SetSleepPolicy(VAL_SLEEP_NONE);".

This should probably be better documented in the LabWindows CVI HELP for ProcessSystemEvents and GetUserEvent like adding:
"NOTE: The call to this function will put the PC to sleep per the Sleep Policy of the running thread, see SetSleepPolicy()."
Had this note been in the HELP, I would not have had to ask this question in the first place.
Message 9 of 9
(4,905 Views)