Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interrupt handling very slow


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
10 replies to this topic

#1 Magogan   Members   -  Reputation: 170

Like
0Likes
Like

Posted 06 August 2014 - 02:06 AM

Hi,

 

when I scroll very fast, I have the problem that the interrupt handling is too slow. When I scroll in the opposite direction, it takes a long time (up to some seconds) until the camera moves in the opposite direction. Does anyone knows how to solve this issue?

LRESULT CALLBACK WndProc(HWND hwnd, UINT umessage, WPARAM wparam, LPARAM lparam)
{
    switch(umessage)
    {
        // Check if the window is being destroyed.
        case WM_DESTROY:
        {
            PostQuitMessage(0);
            return 0;
        }

        // Check if the window is being closed.
        case WM_CLOSE:
        {
            PostQuitMessage(0);        
            return 0;
        }

        

        // All other messages pass to the message handler in the system class.
        default:
        {
            return ApplicationHandle->MessageHandler(hwnd, umessage, wparam, lparam);
        }
    }
}
LRESULT CALLBACK SystemClass::MessageHandler(HWND hwnd, UINT umsg, WPARAM wparam, LPARAM lparam)
{
    if(umsg == WM_MOUSEWHEEL)
        {
            //MessageBox(m_hwnd, L"Mouse wheel", L"Test", MB_OK);
            

            short x = (short)HIWORD(wparam);
            m_Application->HandleInterrupt(MOUSEWHEEL_ROTATED,x);
 
        }
    return DefWindowProc(hwnd, umsg, wparam, lparam);
}
void ApplicationClass::HandleInterrupt(int buttonID, int param1){
    //WaitForSingleObject(InterruptMutex,INFINITE);
    if(buttonID==MOUSEWHEEL_ROTATED){
        if(param1<0){
            targetCameraDistance+=0.5f;
            if(targetCameraDistance>=m_settings->maxCameraDistance){
            targetCameraDistance=m_settings->maxCameraDistance;
            }
        }
        if(param1>0){
            targetCameraDistance-=0.5f;
            if(targetCameraDistance<=0){
            targetCameraDistance=0;
            }
        }
    }
    //ReleaseMutex(InterruptMutex);
}

Do I need the Mutex when handling interrupts?

 

Greetings,

Magogan


Edited by Magogan, 06 August 2014 - 02:06 AM.


Sponsor:

#2 Zaoshi Kaba   Crossbones+   -  Reputation: 4352

Like
1Likes
Like

Posted 06 August 2014 - 03:03 AM

I noticed a lot of people make mistake of using if(PeekMessage(&message, 0, 0, 0, PM_REMOVE)) instead of while(...) inside game loop, this might be source of the problem.



#3 Magogan   Members   -  Reputation: 170

Like
0Likes
Like

Posted 06 August 2014 - 03:10 AM

No, I just used the WndProc function, but it seems that it is too slow for my purposes. PeekMessage seems to be fast enough. Now it works :D



#4 Aardvajk   Crossbones+   -  Reputation: 5982

Like
5Likes
Like

Posted 06 August 2014 - 03:14 AM

What has this got to do with handling interrupts? These messages are just dispatched inside your main message loop. There are no interrupts involved so no need for mutexes, no. This is all running in the same thread.



#5 iMalc   Crossbones+   -  Reputation: 2306

Like
5Likes
Like

Posted 06 August 2014 - 03:51 AM

Generally when the problem appears to be that the Windows message queue mechanism is too slow, that is usually not the case at all.

It can only deliver you the next message when you request it, and you normally only request it when you are finished dealing with the current message. So basically your own slow message processing slows down the receipt of further messages.

 

One mistake I've come across when processing Windows messages is when you only allow at most one Windows message to be processed each time around your main loop, seemingly giving maximum time to the rest of your drawing code. In reality what happens is that this slows the program down horribly. You should endeavour to process ideally all messages before doing any other stuff in your main loop. Although this may be counter-intuitive, it actually makes a world of difference. Give Windows more attention and promptly process its messages, and your program's performance will be greatly rewarded.

 

Those are not interrupts and no you do not need a mutex there. In fact the term "interrupts" doesn't have much applicability at all in a Windows program. The terms that you need to be familiar with are synchronous / asynchronous, blocking / non-blocking, or single-threaded / multi-threaded.

You can confirm this for yourself by placing a breakpoint within the HandleInterrupt function, and when the breakpoint is hit, examine the Call Stack window. When you can look back through the call stack of the same thread and find the original GetMessage or PeekMessage call, then what your application is doing is entirely synchronous, or blocking.


"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms

#6 Madhed   Crossbones+   -  Reputation: 2974

Like
0Likes
Like

Posted 06 August 2014 - 04:10 AM

Magogan, post the code of your message loop.

That's probably where the problem lies. (As others have pointed out already)



#7 Magogan   Members   -  Reputation: 170

Like
0Likes
Like

Posted 06 August 2014 - 04:34 AM

I have fixed the message loop and now it should work.

 

void SystemClass::Run()
{
    MSG msg;
    bool done, result;


    ZeroMemory(&msg, sizeof(MSG));
    
    done = false;
    while(!done)
    {
        if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
            
            if(msg.message == WM_QUIT){
                done = true;
            }
            else if(msg.message == WM_MOUSEWHEEL){
                short x = (short)HIWORD(msg.wParam);
                m_Application->HandleInterrupt(MOUSEWHEEL_ROTATED,x);
            }
        }
        else
        {
            
            result = Frame();
            if(!result)
            {
                done = true;
            }
        }

    }

    return;
}


#8 Aardvajk   Crossbones+   -  Reputation: 5982

Like
0Likes
Like

Posted 06 August 2014 - 05:27 AM

Seems reasonable, although the use of an if-then confused me a bit. Mine looks like:

    while(msg.message != WM_QUIT)
    {
        while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
        {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }

        doGameLoopStuff();
    }

Guess no difference really though.

 

Why are you manually handling WM_MOUSEWHEEL like that? Does it not get passed to your WndProc like every other message? My concern is you are processing that message twice each time it is issued, based on this and your previous code.


Edited by Aardvajk, 06 August 2014 - 05:30 AM.


#9 SmkViper   Members   -  Reputation: 792

Like
0Likes
Like

Posted 06 August 2014 - 07:38 AM

One thing I noticed is that you aren't quite correctly handling the parameter of WM_MOUSEWHEEL.

You're correctly checking for negative or positive values to determine direction, but the value is important too. As the documentation states, the value is in multiples of WHEEL_DELTA, so the larger the value, the larger your response should be. Otherwise the mousewheel will feel slow or laggy as your game doesn't respond to how fast the user is scrolling the wheel.

#10 wintertime   Members   -  Reputation: 1714

Like
0Likes
Like

Posted 06 August 2014 - 08:53 AM

Btw., you are handling WM_CLOSE wrongly. Instead of calling PostQuitMessage you should call DestroyWindow (which then causes WM_DESTROY message and some other things for cleanup). http://msdn.microsoft.com/en-us/library/windows/desktop/ms632617%28v=vs.85%29.aspx



#11 SeanMiddleditch   Members   -  Reputation: 5855

Like
1Likes
Like

Posted 06 August 2014 - 03:50 PM

These aren't "interrupts" by any sense of the word I know; your app isn't being interrupted since you're explicitly polling for events.

There's nothing that normally requires a mutex unless you've added some thread synchronization problems on your own.




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS