CPU usage

Hi,

I think the issue that should be on top of True BASIC´s to-do list should be fixing the high CPU usage issue.

The reason for this issue is quite clear. TB is constantly looking for Windows events, as John Arscott said here previously as well. This message pump loop should have been programmed to wait for events and handle the incoming ones instead of polling ("peeking") for events all the time. Of course, I don't know if this part of the source code is or is not available to the current owners of True BASIC and if anyone can compile the code.

As is described in this topic http://www.truebasic.com/node/832 , doing a short pause helps. True BASIC's pause statement most probably converts the specified value to milliseconds and calls the Sleep Win32 API (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298(v=vs.85).aspx). As documented in the specified URL, this function causes a thread to relinquish the remainder of its time slice. So basically other threads are given time to run.

Specifying 0ms does not help (I tested it, even by creating a DLL in a different language to make sure that it actually runs). The trouble with sleep(0) is that this function immediately returns and put simply (probably not 100% technically correct) it does not give Windows/CPU time to "breathe", as it will still run the loop if no other thread is waiting (so still using 100% of a CPU core). For those interested, I found more information here: http://stackoverflow.com/questions/3727420/significance-of-sleep0

I wish I could come up with a good solution, but after studying the Win32 API I fear it will only be possible by changing the original source code.

The next best thing should be to call sleep(1) every now and again, as was suggested in the TB forum posting that I linked to. Instead of every loop iteration I'd suggest to do it in a counter. Some stupid code that I used to test the DEMTXED editor example with:

Somewhere in the beginning:
LET I=0
...DO....

....
LET I = I + 1
IF I > 1024 THEN
PAUSE 0.01
LET I = 0
END IF

...LOOP...

The result on my laptop (Win 7) was quite good. Very low CPU usage and to me the application was quite responsive (I am a quick typist). Of course above´s snippet should be improved.

Did anyone try something like this in a real-world TB application and can share their experience?

BTW: I *don't* want to suggest that the original developers of this part of TB did a lousy or bad job. There's most probably a lot going on "under the hood" of TB's message loop. Talking about changing it is probably much easier than actually doing it.

Best regards from The Netherlands,
Vincent

Comments

CTX list of current objects

Hi,

Here is a list of the objects and controls currently available in the CTX library:

! 1=static text (real text and images of text)
! 2=check box
! 3=radio group
! 4=radio button
! 5=edit field
! 6=push button
! 7=data table
! 8=list box
! 9=list button
! 10=list edit
! 11=right click menu
! 12=sub menu
! 13=spare
! 14=elevator buttons
! 15=barscale (adjustable bar chart)
! 16=barscale text field
! 17=HSbar
! 18=VSbar
! 19=up/down or left/right Sbar buttons
! 20=Sbar thumb button
! 21=image
! 22=spare
! 23=Window (uses TrueCtrl)
! 24=Menu (uses TrueCtrl)
! 25=Txed control (as used in the editor)
! 26=Hoverbox
! 27=array group (array of objects within a box)

All TrueCtrl statements work with CTX as long as the leading TC_ is changed to CT_

Regards

CPU usage

Hi,

I agree that 100% CPU usage is an annoying feature of TB programs. Basically it all boils down to the use of the routine TC_event, which itself calls the built-in subroutine SYS_EVENT. As you correctly observed, if these sub-routines are placed in a DO...LOOP then the loop will continuously cycle - hence the 100% CPU usage, regardless of whether any "events" are actually happening.

As you also correctly observed, one possible solution might be to PAUSE the continuous cycle, but there is a problem with this method, i.e. how often, and for how long?

There are basically two types of event; mouse and keyboard. It is possible to write your own routine to mimic the SYS_EVENT routine, by using IF KEY INPUT (followed by GET KEY) and GET MOUSE. The advantage with SYS_EVENT is that the events form a queue - at least this is what the manual says. Looping through SYS_EVENT allows us to inspect the queue until it is exhausted. In some programs, such as the TBeditor, it is necessary to empty or flush out the queue.

If we decide to introduce a PAUSE in the loop, we have to make sure we don't miss any "events". Take for example a double mouse click. The manual doesn't say what the time interval is between the two clicks, but in practice if you are too slow you get two "SINGLE" events instead of a "DOUBLE". Likewise, if hold a key down, then you will get multiple instances of "KEYPRESS" events. The number will depend on how your keyboard has been set up. Obviously a pause inside the event loop might cause us to miss some mouse clicks or keypresses, although we could add some logic that says a pause cannot occur if an event is already in the queue and that a pause can only occur when the queue is empty.

Unfortunately the manual is not very explicit about the way the event queue works. What I don't know is whether this queue accumulates events even if we are not currently cycling through the loop. If it does queue events regardless, then the duration of the PAUSE largely depends on whether the user will notice a slight delay. Maybe somebody can experiment and find out how long the PAUSE can be before someone will notice.

If we can devise a workable pause system, then I will be quite happy to include an alternative low CPU version of TC_event in the True Ctrl library module, and to modify the TBeditor accordingly.

Regards
BigJohn

Timer parameter of TC_Event

Hi,

Thanks both for your replies.

I just noticed the "timer" parameter of TC_Event.

CALL TC_Event (timer, event$, window, x1, x2)

The docs promise that TC_Event will still return immediately if there are events to process and otherwise wait for them. This sounds better than using the Pause statement.

I tried some examples. If I used the 0.5 value (IIRC) I had good results, anything lower and the CPU was back to 100%. I found the scrollbar performance acceptable myself. I assume using timer is incompatible with the event list emptying technique John mentioned, though. For my first TB app I'm going to experiment with this parameter.

On an unrelated note, does anybody know an URL to download a reasonable sized TB app, so I can do easier testing with the CPU?
Of course, I *should* be writing those apps myself.... :-)

Best regards,
Vincent

Pause and scroll bars

Hi

The only issue I see with putting in a pause directly or in a loop like you have done is that the scroll bars do not respond correctly. I am still hoping that someone at TB can come up with a fix for the offending library.

Dave

Hi Dave, Yes, I saw some

Hi Dave,

Yes, I saw some graphical issues as well, I believe in the menu bar.
However, on my laptop I seem to have some issues (flickering mouse cursor) when I'm running the standard TB code without modifications as well.

I also truly hope that the existing TB code can be fixed. This would be a win-win situation for everyone.

If not, there's one other solution that I can think of and that is rewriting the "OBJECT" routine in a DLL. Or at least the most important portions of it, to form a new alternative GUI library. Would be a massive undertaking though.

For fun I'm gonna to toy with this idea, but don't expect any meaningful code from me anytime soon.
Just like to play with this idea, to see if it is possible at all and see where the complications are.

Regards,
Vincent

Re-writing the OBJECT code.

Hi Vincent,

There are many reasons for re-writing the OBJECT code. For example, to give greater control over colors, text formats and the like. Some years ago I did this and produced a library module called CTX which re-created all the existing objects, including menus, push buttons, text boxes, image boxes, lists etc., plus a whole lot more including dialog boxes. This was all done from scatch using TB graphics only and no Windows APIs. The only things I did borrow from the TrueCtrl library was TC_win_create and TC event. This was indeed a MASSIVE undertaking.

In the CTX library ALL objects are clickable with the mouse and all return "SINGLE" as the event. CTX_event also returns the type of object, e.g. push button, list, image etc. All other events are passed on as is, e.g. typed character numbers. In this way CTX and TrueCTRL can co-exist in the same program. The Version 6 editor works this way.

It is relatively easy to use PAUSE or the TC_event (timer) parameter within either CTX or TrueCtrl to reduce CPU usage provided we all agree on the value of the time pause. We can even introduce a routine called Reduced_CPU(value) which will allow users to set a global variable for the pause time. We can even automatically add some code to users programs that will set this pause time. We also need to define a way of measuring the reduction in CPU usage so that users can witness the improvement. Any ideas?

Regards
Big John

CTX Updates

Hi John,

Sorry but a bit of a sidetrack from the original question but have there been any updates to the CTX library recently. You said a while back that you were going to implement additional controls and I was just wondering how that was coming along.

Best regards
Dave

Extensions to the CTX library

Hi,

Recently I have modified the Stext and Pushbutton control objects so that they will accept images as well as text. This is important for languages such as Chinese, Japanese and Korean, and for any Unicode fonts. As you know, TB only recognizes ANSI fonts which are limited to 255 characters.

Regards
Big John