Acfboy commented on issue #18566:
URL: https://github.com/apache/nuttx/issues/18566#issuecomment-4702351213

   Hi @ppisa,
   
   Here is a weekly report about my work. I have implemented the fb, mouse, and 
keyboard drivers for Microwindows, and ported mwdemo.c to examples in the three 
commits below. It seems to be running well in my qemu-intel64 and sim 
environments.
   
   1. fb driver: 
https://github.com/Acfboy/nuttx-apps/commit/8877bb49cfe9d4af1c499132997b294d324432cf
   2. keyboard and mouse driver: 
https://github.com/Acfboy/nuttx-apps/commit/29058f0c70020ab4f925b1b8618d4f65b9dd762e
   3. mwdemo.c: 
https://github.com/Acfboy/nuttx-apps/commit/b500978d0b339ced516cd328cb483f354622be14
   
   ## Something strange
   
   However, I encountered a strange issue when running `mwdemo.c` on QEMU. The 
animation sometimes gets stuck at the beginning until a mouse or keyboard event 
occurs. After digging deep into the codebase, I found the reason:
   
   In `microwindows/src/mwin/winmain.c`, there is a function `MwSelect` which 
waits until an event occurs (timer, mouse, or keyboard). 
   [code 
permalink](https://github.com/ghaerr/microwindows/blob/1e71398cc6f650687f406547230c33788eeaf9c7/src/mwin/winmain.c#L281-L300)
   
   ```c
        int poll = (!canBlock || dragwp);               /* just poll if can't 
block or window move in progress*/
        if (!poll)
        {
                if ((timeout = MwGetNextTimeoutValue()) == (MWTIMEOUT) -1L)     
/* get next mwin timer*/
                        timeout = 0;                                            
                                        /* no mwin timers*/
   #if MW_FEATURE_TIMERS
                /* get next timer or use passed timeout and convert to timeval 
struct*/
                if (!GdGetNextTimeout(&tout, timeout))          /* no VTSWITCH 
timer?*/
   #else
                // we don't enter this branch
   #endif
                {
                        to = NULL;                                              
                /* no timers, block*/
                }
        }
   
   ```
   
   I noticed that if a timer expires, `MwGetNextTimeoutValue()` returns 0, so 
`timeout = 0`. However, if there is no VTSWITCH timer (which is the case in 
QEMU), `GdGetNextTimeout(&tout, timeout)` will directly return false, and `to` 
will be set to `NULL`. In other words, the code assumes there are no mwin 
timers, which is inaccurate and causes an endless block until other events 
occur (`select(setsize, &rfds, &wfds, &efds, NULL)`).
   
   And in `mwdemo.c`, we run this event loop:
   [code 
permalink](https://github.com/ghaerr/microwindows/blob/1e71398cc6f650687f406547230c33788eeaf9c7/src/demos/mwin/mwdemo.c#L509-L512)
   
   ```c
    while (GetMessage(&msg, NULL, 0, 0))
       {
         TranslateMessage(&msg);
         DispatchMessage(&msg);
       }
   
   ```
   
   In the first few iterations, it sets the timer (50 + rand ms), draws the 
background and geometry, waits for the timer, and then resets it. This is where 
the bug occurs: if the drawing process is quite time-consuming, we get `timeout 
= 0` and get stuck there.
   
   The observations above indicate two things:
   
   1. `MwSelect` does not behave as its implementation implies. It should 
return immediately if the timer has already expired.
   2. Why is the drawing process so slow (about 100ms)? I think it might be 
because we use `NO_CACHE` in the QEMU fb driver, and we write to the 
framebuffer pixel-by-pixel during drawing.
   
https://github.com/apache/nuttx/blob/1282b94792767bf40cdb8fb50faf9051db0bda42/arch/x86_64/src/intel64/intel64_fb.c#L265-L267
   
   I would love to hear your thoughts, @ppisa, on this issue and my recent 
commits.
   Also, @ghaerr, I wonder your insight on this. Is this behavior in `MwSelect` 
expected under certain conditions, or could it be a potential edge-case bug 
when the drawing process takes longer than the timeout?
   
   Thank you both for your time and help!


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to