Squashed commit of the following:

apps/examples/pwfb: Solve a race condition by changin some relative priorities.  Also removes a delay kludge that used as a workaround.

    apps/examples/pwfb:  Add rate control.  Examples becomes unstable at high update rates.
This commit is contained in:
Gregory Nutt 2019-03-17 13:51:03 -06:00
parent 11d7ac7abe
commit 13555f30f9
4 changed files with 74 additions and 34 deletions

View File

@ -64,34 +64,60 @@ config EXAMPLES_PWFB_BPP
Pixels per pixel to use. Valid options include 2, 4, 8, 16, 24,
and 32. Default is 32.
config EXAMPLES_PWFB_RATECONTROL
int "Frame rate control"
default 100
range 0 1000
---help---
This is the inter-frame period in milliseconds that is used to
control the framerate. A value of zero will disable frame controls
and the rendering will occur as fast as is possible.
If you run this example with high frame rates, it becomes unstable.
This is probably a bug in the example: It may not be accounting
for for some asynchronous behaviors.
config EXAMPLES_PWFB_VERBOSE
bool "Verbose output"
default n
comment "NX Server Options"
comment "Tasking options"
config EXAMPLES_PWFB_STACKSIZE
int "NX Server Stack Size"
config EXAMPLES_PWFB_PROGNAME
string "Program name"
default "pwfb"
depends on BUILD_LOADABLE
---help---
This is the name of the program that will be use when the NSH ELF
program is installed.
config EXAMPLES_PWFB_CLIENT_STACKSIZE
int "Example Main Stack Size"
default 2048
---help---
The stacksize to use when starting the example main().
Default 2048
config EXAMPLES_PWFB_CLIENT_PRIO
int "Client Priority"
default 90
---help---
The priority to use when staring the example main(). This priority
should be lower than both the listener and server priorities (See
CONFIG_NXSTART_SERVERPRIO). Default: 90
config EXAMPLES_PWFB_LISTENER_STACKSIZE
int "Listener Stack Size"
default 2048
---help---
The stacksize to use when creating the NX server. Default 2048
config EXAMPLES_PWFB_CLIENTPRIO
int "Client Priority"
config EXAMPLES_PWFB_LISTENER_PRIO
int "Listener Priority"
default 100
---help---
The client priority. Default: 100
config EXAMPLES_PWFB_SERVERPRIO
int "Server Priority"
default 120
---help---
The server priority. Default: 120
config EXAMPLES_PWFB_LISTENERPRIO
int "Listener Priority"
default 80
---help---
The priority of the event listener thread. Default 80.
The priority of the event listener thread. This priority should be
above the client priority but below the server priority (See
CONFIG_NXSTART_SERVERPRIO). Default 100.
endif

View File

@ -41,14 +41,17 @@ ASRCS =
CSRCS = pwfb_events.c pwfb_motion.c
MAINSRC = pwfb_main.c
CONFIG_PWFB_PROGNAME ?= pwfb$(EXEEXT)
PROGNAME = $(CONFIG_PWFB_PROGNAME)
CONFIG_EXAMPLES_PWFB_PROGNAME ?= pwfb$(EXEEXT)
PROGNAME = $(CONFIG_EXAMPLES_PWFB_PROGNAME)
# NX built-in application info
CONFIG_EXAMPLES_PWFB_CLIENT_PRIO ?= SCHED_PRIORITY_DEFAULT
CONFIG_EXAMPLES_PWFB_CLIENT_STACKSIZE ?= 2048
APPNAME = pwfb
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 2048
PRIORITY = $(CONFIG_EXAMPLES_PWFB_CLIENT_PRIO)
STACKSIZE = $(CONFIG_EXAMPLES_PWFB_CLIENT_STACKSIZE)
MODULE = CONFIG_EXAMPLES_PWFB

View File

@ -62,16 +62,30 @@
#ifndef CONFIG_NX
# error "NX is not enabled (CONFIG_NX)"
#endif
#ifdef CONFIG_DISABLE_MQUEUE
# error "The multi-threaded example requires MQ support (CONFIG_DISABLE_MQUEUE=n)"
#endif
#ifdef CONFIG_DISABLE_PTHREAD
# error "This example requires pthread support (CONFIG_DISABLE_PTHREAD=n)"
#endif
#ifndef CONFIG_NX_BLOCKING
# error "This example depends on CONFIG_NX_BLOCKING"
#endif
/* Task priorities */
#if CONFIG_EXAMPLES_PWFB_CLIENT_PRIO >= CONFIG_EXAMPLES_PWFB_LISTENER_PRIO || \
CONFIG_EXAMPLES_PWFB_CLIENT_PRIO >= CONFIG_NXSTART_SERVERPRIO
# warning Client priority must be lower than both the listener and server priorities
#endif
#if CONFIG_EXAMPLES_PWFB_LISTENER_PRIO >= CONFIG_NXSTART_SERVERPRIO
# warning Listener priority must be lower than the server priority
#endif
/* Default colors */
#ifndef CONFIG_EXAMPLES_PWFB_BGCOLOR

View File

@ -91,7 +91,7 @@ static bool pwfb_server_initialize(FAR struct pwfb_state_s *st)
/* Set the client task priority */
param.sched_priority = CONFIG_EXAMPLES_PWFB_CLIENTPRIO;
param.sched_priority = CONFIG_EXAMPLES_PWFB_CLIENT_PRIO;
ret = sched_setparam(0, &param);
if (ret < 0)
{
@ -159,9 +159,9 @@ static bool pwfb_listener_initialize(FAR struct pwfb_state_s *st)
*/
(void)pthread_attr_init(&attr);
param.sched_priority = CONFIG_EXAMPLES_PWFB_LISTENERPRIO;
param.sched_priority = CONFIG_EXAMPLES_PWFB_LISTENER_PRIO;
(void)pthread_attr_setschedparam(&attr, &param);
(void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_PWFB_STACKSIZE);
(void)pthread_attr_setstacksize(&attr, CONFIG_EXAMPLES_PWFB_LISTENER_STACKSIZE);
ret = pthread_create(&thread, &attr, pwfb_listener, st);
if (ret != 0)
@ -396,17 +396,13 @@ static bool pwfb_configure_window(FAR struct pwfb_state_s *st, int wndx,
goto errout_with_hwnd;
}
/* There is a race condition which we resole by simply waiting a bit here:
* In order for the size and position to take effect, a command is sent to
* server which responds with an event. So we need to synchronize at this
* point, or the following fill will fail.
*
* REVISIT: Here a dumb wait is used. It be better to have a firm
* handshake to when the new size and position are in effect.
/* There is a race condition here we resolve by making the main thread
* lowest in priority. In order for the size and position to take effect,
* a command is sent to server which responds with an event. So we need
* to be synchronized at this point or the following fill will fail because
* it depends on current knowlede of the size and position.
*/
usleep(500 * 1000);
/* Create a bounding box. This is actually too large because it does not
* account for the boarder widths. However, NX should clip the fill to
* stay within the frame.
@ -635,6 +631,7 @@ int pwfb_main(int argc, char *argv[])
for (; ; )
{
usleep(CONFIG_EXAMPLES_PWFB_RATECONTROL * 1000);
if (!pwfb_motion(&wstate))
{
printf("pwfb_main: ERROR:"