What's new

Timer issues

Doomulation

?????????????????????????
Umm, I was wondering something. Of course, I know how to install and use timers. However, the probles lies not in there. I wish to use an infinite loop that would run about a second. Due to the diffrent speeds of computers, I can't make it count the loops and stop after a chosen amount.
Therefore, I've tried timers. However, the thing is that the OS seems to busy to send either a message nor call a callback function. Is there any way to solve this one little problem?
 

blight

New member
change your OS ;P
maybe you could describe the problem a little close cuz altough i do not natively code for windows i know that i.e. W32API's FileDialog can block the whole event loop of your app (including timers)... what do you mean by "the os seems to busy to send the message"? does it never send it or is it like 10 ms to late? or a few seconds to late?
 

Cyberman

Moderator
Moderator
Doomulation said:
Umm, I was wondering something. Of course, I know how to install and use timers. However, the probles lies not in there. I wish to use an infinite loop that would run about a second. Due to the diffrent speeds of computers, I can't make it count the loops and stop after a chosen amount.
Therefore, I've tried timers. However, the thing is that the OS seems to busy to send either a message nor call a callback function. Is there any way to solve this one little problem?

You are putting an infinate loop into an event?
All that will succeed in doing is causing the execution thread to have a siezure and stop.

I believe you can tweak windows into sending a message to your application at a regular rate and it's programable based on 1ms (which if you didn't know the PC actually has a 1MS interrupt on it from the real time clock that is independant of the processor).

Your job would be to catch the message do whatever you need to do and end your execution thread at that point.

Cyb
 

Moose Jr.

Raging Moose
What language are you using? I had a similar problem in VB.NET when I found a helpful article about an API call for medium-resolution (1 ms) timing that isn't system dependent. It even allows you to deal with the function call overhead.
 

ingonab

New member
Code:
DWORD endTick = GetTickCount() + 1000;

while (1)
{
    if (GetTickCount() >= endTick)
        break;

    // do stuff here
}

Anything wrong with just doing this? (Apart from the obvious cheap programming technique that isn't fit for anyone with proper experience.)
 
OP
Doomulation

Doomulation

?????????????????????????
Obviosuly, like this:

Code:
bool bExit = false;

int main()
{
SetTimer(...,TimerProc) // Set timer
int i=0;
while(true) { i++; if (bExit) break; }
return 0;
}

TimerProc(...)
{
bExit=true;
}

I don't care if it's an api or not; just to get it working. Why don't I do like you say? Because that involves a function call at every turn; which is not what I want. The reason for the infinite loop like this is to test your computer's speed. How many instuctions per second? Later also including function calls.

What I mean by "to busy to send," is as you see, the TimerProc will never get called. Until I break the loop.
 

ingonab

New member
Doomulation said:
I don't care if it's an api or not; just to get it working. Why don't I do like you say? Because that involves a function call at every turn; which is not what I want.
I don't know how "accurate" you want this thing to be but the function call each cycle won't make much different to what you're already doing, in the grand scale of things.

But lets suppose you do it your way:
Code:
for (i = 0; !bExit; i++) ;
The reason for the infinite loop like this is to test your computer's speed. How many instuctions per second?
You realize the result you get won't be "instructions per second". Only a number proportional to that. --Though I assume you know this.

What I mean by "to busy to send," is as you see, the TimerProc will never get called. Until I break the loop.
Your assumption is only partially correct. The OS is not "too busy to send". Your application is, in essence, too busy to send, but only because you've dead-locked it in a not-very-functional loop.

More accurately, the reason why TimerProc is not getting called is because your application is never calling GetMessage() or the likes during the time it expects the message. The events/messages you expect from SetTimer(hWnd, ...) are generated in the calls to GetMessage() of the thread hWnd specifies. If hWnd is not specified, the thread is that which called SetTimer(...) --most often the main application thread. This is true for both when you use choose to use WM_TIMER and specify an ID or a callback procedure (which you've done).

If you want to verify this, just stick a message loop in your "infinite loop" and it'll probably work the way you were hoping. If you do this however, you'll introduce many more functions in your loop than just the calls to GetTickCount() from the way I suggested above.

Now, for a "more proper" way one could do this:
Code:
{
    DWORD dwCounter = 0;

    HANDLE hCounterThread = CreateThread(NULL, 0,
        CounterThread, (LPVOID)&dwCounter CREATE_SUSPENDED, 0);

    ResumeThread(hCounterThread);
    Sleep(1000);
    TerminateThread(hCounterThread, 0);
    CloseHandle(hCounterThread);
}

DWORD WINAPI CounterThread(LPVOID lpParameter)
{
    while (1)
        (*(DWORD *)lpParameter)++;
}

dwCounter will, afterwards, hold the number of times the loop in CounterThread went around for.

It is generally considered dangerous or bad to use TerminateThread(...) to stop a thread. --You should take note of this (if you didn't already know it) if you ever go about creating your own threads. It's okay in this case because there isn't anything in CounterThread(...) that would be of harm to anything when killed.
 
Last edited:

tooie

New member
ingonab is correct .. you program is dead locking, the OS would be adding the message to your message que .. when DispatchMessage is executed on this message .. that callback function will be called .. so you need to do this in a secondary thread .. having the main thread process messages .. or get it to process messages in that loop.

this is a function I have for polling the message que and processing any messages in it .. if no messages are in the que then processing is returned.

void ProcessGuiMessages (void) {
MSG msg;

while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}

if you want to see how fast the computer is .. this is not the way to go
 

Teamz

J'aime tes seins
yeah you got to be careful with GetMessage and PeekMessage

GetMessage will only return after it gets a message, PeekMessage will return if there is no message or will process it if there is one

a MessageBox could also pause the current process
 
OP
Doomulation

Doomulation

?????????????????????????
ingonab said:
You realize the result you get won't be "instructions per second". Only a number proportional to that. --Though I assume you know this.
Of course I know; it's never accurate. Diffrent results are gathered every time.

Your assumption is only partially correct. The OS is not "too busy to send". Your application is, in essence, too busy to send, but only because you've dead-locked it in a not-very-functional loop.
I see. I knew something was deadlocking, although not sure how or what.

More accurately, the reason why TimerProc is not getting called is because your application is never calling GetMessage() or the likes during the time it expects the message. The events/messages you expect from SetTimer(hWnd, ...) are generated in the calls to GetMessage() of the thread hWnd specifies. If hWnd is not specified, the thread is that which called SetTimer(...) --most often the main application thread. This is true for both when you use choose to use WM_TIMER and specify an ID or a callback procedure (which you've done).
Does that mean that maybe it wouldn't deadlock if called from a diffrent thread?

Now, for a "more proper" way one could do this:
Code:
{
    DWORD dwCounter = 0;

    HANDLE hCounterThread = CreateThread(NULL, 0,
        CounterThread, (LPVOID)&dwCounter CREATE_SUSPENDED, 0);

    ResumeThread(hCounterThread);
    Sleep(1000);
    TerminateThread(hCounterThread, 0);
    CloseHandle(hCounterThread);
}

DWORD WINAPI CounterThread(LPVOID lpParameter)
{
    while (1)
        (*(DWORD *)lpParameter)++;
}
I never thought about that... thanks.

It is generally considered dangerous or bad to use TerminateThread(...) to stop a thread. --You should take note of this (if you didn't already know it) if you ever go about creating your own threads. It's okay in this case because there isn't anything in CounterThread(...) that would be of harm to anything when killed.
What could be an example of bad things when I terminate a thread? Also, according to the windows sdk, handles to threads must be closed before the threads are entirely removed from the system.

ingonab is correct .. you program is dead locking, the OS would be adding the message to your message que .. when DispatchMessage is executed on this message .. that callback function will be called .. so you need to do this in a secondary thread .. having the main thread process messages .. or get it to process messages in that loop.

this is a function I have for polling the message que and processing any messages in it .. if no messages are in the que then processing is returned.

void ProcessGuiMessages (void) {
MSG msg;

while (PeekMessage(&msg,NULL,0,0,PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
It seems awfully stupid to me that you have to dispatch a message when the timer should call a callback function.

if you want to see how fast the computer is .. this is not the way to go
Heh, I know, I know...it isn't the best way, but it most certainly isn't the worst.

Btw...
speaking of callback functions, is it possible to send a callback to a class function as callback?
 

ingonab

New member
Doomulation said:
Does that mean that maybe it wouldn't deadlock if called from a diffrent thread?
It means it wouldn't deadlock if you gave your process a chance to call GetMessage(...). Whether by the means of using separate threads or whatever other way you can devise.

What could be an example of bad things when I terminate a thread?
The "bad things" come down to the fact that you can't predict where in the thread it'll stop.
Consider three lines of operation that happen in a thread:
Code:
PerformTask1();
PerformTask2();
PerformTask3();
If you used TerminateThread(...) to stop the thread, you wouldn't know which of the three tasks, if any, were actually performed. It doesn't come down to whether one task was performed or not either. Each of those function calls will be implemented using lots of discreet CPU instructions. The thread could get terminated 23% into PerformTask1(), 99.99% into PerformTask3(), or even before PerformTask1().

Consider if in those functions, memory allocation and freeing takes place. Stopping the thread at incorrect places can cause memory leaks. (Not that much of a big deal with small programs in our clever modern OSes.)

Getting a little advanced... If you're going to be using threads to their full extent, you'll be worrying about atomicity, memory sharing, critical sections, et al. One common way of sharing resource between multiple threads is to lock it while one thread is using it so that other threads can't touch it during this time and wreck its integrity. Windows provides EnterCriticalSection(...)/LeaveCriticalSection(...) for basic locking.

What would happen if a thread is terminated after it calls EnterCriticalSection(..), to work with a resource, but before it finishes with LeaveCriticalSection()? (The lock will be lost and other threads won't be able to access the resource.) What would happen the thread is terminated 23% into EnterCriticalSection(...)? (It's undocumented.. but you could end up with some "half locked" lock, and this could be more hazardous than just losing the lock.)

Also, according to the windows sdk, handles to threads must be closed before the threads are entirely removed from the system.
Yes, the memory used by a thread is not entirely freed until the thread's handle is closed. That is what CloseHandle(hCounterThread) is for.

If you interpreted it to mean that you need to close the thread BEFORE you can terminate or exit it, then that's an error in your interpretation. If you have doubts, cite the part of the documentation in question so I know where you're coming from.

It seems awfully stupid to me that you have to dispatch a message when the timer should call a callback function.
I'm not sure of the specifics, so I don't know if it's DispatchMessage() that calls the callback or not, but I do know this: There is no timer. --In the sense you're thinking. The OS doesn't use some background thread to keep track of your timer, to put a message on your queue when the time comes. It's all done by your own application. --In a way, I assume, that is very similar to the method I posted couple posts back with GetTickCount(). This is probably done in GetMessage(...). GetMessage(), when it's called, basically looks through your list of active "timers" and check if it's been n + the time when the timer was set. If so, it puts a message on its own queue or calls the callback (or flags DispatchMessage() to do that).

speaking of callback functions, is it possible to send a callback to a class function as callback?
Non-static class methods can't be used as callback functions. (Because there's no THIS pointer)
 
OP
Doomulation

Doomulation

?????????????????????????
ingonab said:
The "bad things" come down to the fact that you can't predict where in the thread it'll stop.
Consider three lines of operation that happen in a thread:
Code:
PerformTask1();
PerformTask2();
PerformTask3();
If you used TerminateThread(...) to stop the thread, you wouldn't know which of the three tasks, if any, were actually performed. It doesn't come down to whether one task was performed or not either. Each of those function calls will be implemented using lots of discreet CPU instructions. The thread could get terminated 23% into PerformTask1(), 99.99% into PerformTask3(), or even before PerformTask1().

Consider if in those functions, memory allocation and freeing takes place. Stopping the thread at incorrect places can cause memory leaks. (Not that much of a big deal with small programs in our clever modern OSes.)

Getting a little advanced... If you're going to be using threads to their full extent, you'll be worrying about atomicity, memory sharing, critical sections, et al. One common way of sharing resource between multiple threads is to lock it while one thread is using it so that other threads can't touch it during this time and wreck its integrity. Windows provides EnterCriticalSection(...)/LeaveCriticalSection(...) for basic locking.

What would happen if a thread is terminated after it calls EnterCriticalSection(..), to work with a resource, but before it finishes with LeaveCriticalSection()? (The lock will be lost and other threads won't be able to access the resource.) What would happen the thread is terminated 23% into EnterCriticalSection(...)? (It's undocumented.. but you could end up with some "half locked" lock, and this could be more hazardous than just losing the lock.)
Ah, I see now the problems there. Of course, terminating a thread without a good reason is stupid. Although it might not be such a big problem if closing it right before exit. But still, I guess a better method would be to use something like a global variable to signal the thread to exit.

Yes, the memory used by a thread is not entirely freed until the thread's handle is closed. That is what CloseHandle(hCounterThread) is for.

If you interpreted it to mean that you need to close the thread BEFORE you can terminate or exit it, then that's an error in your interpretation. If you have doubts, cite the part of the documentation in question so I know where you're coming from.
No, not really, the sdk says to close the handle after the thread is terminate and so I've always done.

I'm not sure of the specifics, so I don't know if it's DispatchMessage() that calls the callback or not, but I do know this: There is no timer. --In the sense you're thinking. The OS doesn't use some background thread to keep track of your timer, to put a message on your queue when the time comes. It's all done by your own application. --In a way, I assume, that is very similar to the method I posted couple posts back with GetTickCount(). This is probably done in GetMessage(...). GetMessage(), when it's called, basically looks through your list of active "timers" and check if it's been n + the time when the timer was set. If so, it puts a message on its own queue or calls the callback (or flags DispatchMessage() to do that).
If you put it that way, it seems quite obvious.

Non-static class methods can't be used as callback functions. (Because there's no THIS pointer)
Seems that either I *have* to use a non-class member function or make it static. I'm not much into static function of classes, but lemme see...I don't suppose the static functions can access class data?
I want to have the class handle a message dispatched to windows, see? One of those is WM_TIMER, hence why I tried the callback function.
But I guess the only gaurantee of a class to get its own messages (instead of putting a call to a class function from your app's window message quene) is to create a new window, am I right?
I'm not too good at creating windows by using api :shifty:

EDIT: Mmmm, forget the asm thing, I found a good tutorial. Anyway, so instead, any hints on making the program "anti-freeze?" Meaning a way to stop the gui from freezing while executing code. I can bet it involves using a diffrent thread, typically for the code, am I right?
 
Last edited:

tooie

New member
ingonab said:
Yes, the memory used by a thread is not entirely freed until the thread's handle is closed. That is what CloseHandle(hCounterThread) is for.

no you close the handle to stop a handle leak .. if you kept creating threads you would run out of handles .. actually you start re-using them at times .. this can be a big issue if you have a file opened .. then opened a new file and it gives the same handle .. your app has a limited amount of handles .. I think like 500 or so.
 

ingonab

New member
tooie said:
ingonab said:
Yes, the memory used by a thread is not entirely freed until the thread's handle is closed.
no you close the handle to stop a handle leak ..

That may be a specific issue of not closing handles but there's nothing incorrect about what I originally wrote.
 

Top