multi thread in PhAB

Hi, I would like to run a simple multi threaded program in Photon
using PhAB. In my GUI I have two buttons where one button is to
lunch thread1 and the other button is to lunch thread2. The task of
thread 1 and 2 is to display number from 1 to 100 in two seperate
label box.
There is the code:

thread1.c
/* Y o u r D e s c r i p t i o n /
/
AppBuilder Photon Code Lib /
/
Version 2.03 */

/* Standard headers /
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <errno.h>
/
Local headers */
#include “ablibs.h”
#include “abimport.h”
#include “proto.h”

void * t1()
{
int i;
char buf[10];
for (i=0;i<100;i++)
{
sprintf(buf,"%d",i);
PtSetResource(ABW_Thread1_display,Pt_ARG_TEXT_STRING,buf,0);
PtFlush();
PtBkgdHandlerProcess();
usleep(100000);
}
pthread_exit(NULL);
}

int
thread1( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t
*cbinfo )

{
int thread_id;
pthread_t p_thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;
thread_id=pthread_create(&p_thread,&attr,t1,NULL);
pthread_join(p_thread,NULL);
return( Pt_CONTINUE );
}

Thread2.c

/* Y o u r D e s c r i p t i o n /
/
AppBuilder Photon Code Lib /
/
Version 2.03 */

/* Standard headers */
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>

/* Local headers */
#include “ablibs.h”
#include “abimport.h”
#include “proto.h”


void * t2()
{
int i;
char buf[10];

for (i=0;i<100;i++)
{
sprintf(buf,"%d",i);
PtSetResource(ABW_Thread2_display,Pt_ARG_TEXT_STRING,buf,0);
PtFlush();
PtBkgdHandlerProcess();
usleep(100000);
}
pthread_exit(NULL);
}

int
thread2( PtWidget_t *widget, ApInfo_t *apinfo, PtCallbackInfo_t
*cbinfo )

{
int thread_id;
pthread_t p_thread;
pthread_attr_t attr;
pthread_attr_init(&attr);
/* eliminate ‘unreferenced’ warnings */
widget = widget, apinfo = apinfo, cbinfo = cbinfo;
thread_id=pthread_create(&p_thread,&attr,t2,NULL);
pthread_join(p_thread,NULL);
return( Pt_CONTINUE );
}


When I press button1 it runs thread1.c and works fine.
but when I press button2 it blocks thread1 and runs thread2.
and only when thread2 finishes running it runs thread1 again.
Is using PtEnter() and PtLeave a key here?
if so can you suggest a fix. Thanks

jinma wrote:

Hi, I would like to run a simple multi threaded program in Photon
using PhAB. In my GUI I have two buttons where one button is to
lunch thread1 and the other button is to lunch thread2. The task of
thread 1 and 2 is to display number from 1 to 100 in two seperate
label box.

When I press button1 it runs thread1.c and works fine.
but when I press button2 it blocks thread1 and runs thread2.
and only when thread2 finishes running it runs thread1 again.
Is using PtEnter() and PtLeave a key here?

Yes.

if so can you suggest a fix. Thanks

void * t1()
{
int i;
char buf[10];
for (i=0;i<100;i++)
{
sprintf(buf,"%d",i);
PtEnter(0);
PtSetResource(ABW_Thread1_display,Pt_ARG_TEXT_STRING,buf,0);
PtFlush();
PtLeave(0);
usleep(100000);
}
pthread_exit(NULL);
}

I have tried this way but it still doesn’t work. The app seems to
blize after a button press.
It seems like doing a PtEnter and PtLeave in a for loop many times
doesn’t seem to be a good idea?
Maybe the t1 thread is not getting the lock.

jinma wrote:

I have tried this way but it still doesn’t work. The app seems to
blize after a button press.
It seems like doing a PtEnter and PtLeave in a for loop many times
doesn’t seem to be a good idea?
Maybe the t1 thread is not getting the lock.

When you wait for the thread with a pthread_join, you’re in
a Photon callback. So Photon is locked, and you’ve blocked
the main Photon thread at the pthread_join. If the thread you
started then calls PtEnter, it will block and your application
will deadlock.

John Nagle
Team Overbot

Sorry, I didn’t notice the pthread_join() calls in there… Yes, that’s a
problem, too. If you need the callback to block in pthread_join(), you’ll
have to call PtLeave() before pthread_join() and PtEnter() after. But while
the main thread remains blocked, you need to process events. Putting the
PtBkgdHandlerProcess() calls back in would make it somewhat better – you
will check for events at least every 100ms. But in general, it’s a cleaner
design to have your main thread process events without blocking in
callbacks, while separate worker threads do their work without processing
events. (In rare cases, it may be simpler to just have several “main”
threads that run the main loop and process events most of the time, but
occasionally run a callback that calls PtLeave(), blocks for a while, and
calls PtEnter() before returning. But you have to be careful to avoid a
situation where all your threads have blocked for too long and there’s no
thread taking care of events.)

“John Nagle” <nagle@overbot.com> wrote in message
news:d1t39m$5ll$1@inn.qnx.com

jinma wrote:
I have tried this way but it still doesn’t work. The app seems to
blize after a button press.
It seems like doing a PtEnter and PtLeave in a for loop many times
doesn’t seem to be a good idea?

That’s another thing. If you remove the blocking join() calls

Maybe the t1 thread is not getting the lock.

When you wait for the thread with a pthread_join, you’re in
a Photon callback. So Photon is locked, and you’ve blocked
the main Photon thread at the pthread_join. If the thread you
started then calls PtEnter, it will block and your application
will deadlock.

John Nagle
Team Overbot

Ok I think I get it now. do you think using thread in PhAB is a good
idea? or should I be using timers to wake up callbacks periodically?
I know that I can use PtTimer or RtTimer but they are not hard
real-time.
If I would like to use hard real-time to wake up these callbacks, do I
need to create a thread out side of the PhAB and talk to PhAB app? If
so what mechanism should I use for this communication link?

Thanks

jinma wrote:

Ok I think I get it now. do you think using thread in PhAB is a good
idea? or should I be using timers to wake up callbacks periodically?

It depends on what exacty you want to do. If you have hard-realtime
requirements, a high-priority thread may be your only choice.

I know that I can use PtTimer or RtTimer but they are not hard
real-time.

No, but RtTimer is much “harder” than PtTimer. A RtTimer is basically a
POSIX timer hooked up to the Photon main loop with a pulse. The main
problem with using RtTimer to do hard realtime is that even though the
pulse can carry priority information, there are a few things in the
Photon library that can cause priority inversion. (This includes things
that happen without any explicit calls made by application code – for
instance, as a reaction to a window manager event.)

If I would like to use hard real-time to wake up these callbacks, do I
need to create a thread out side of the PhAB and talk to PhAB app? If
so what mechanism should I use for this communication link?

The realtime thread doesn’t need to be outside the PhAB app (i.e. in a
separate process). There’s nothing wrong about it being part of the
PhAB app; you just need to be careful about how it communicates with
other threads.

Ok if a real-time thread can be within the PhAB how can I execute this
thread without callback function having to wait for it by
pthread_join? Do I have to make the thread attribute with
PTHREAD_CREATE_DETACH? Furthermore, if my thread uses Photon library
calls, how can I make it work safely? For example, if I made the
callback function to wait for thread using pthread_join, I can do

PtLeave(0);
pthread_join();
PtEnter(0);

but if I don’t have this, can my thread still be able to get the lock
for PtEnter(0)?
Thanks

jinma wrote:

Ok I think I get it now. do you think using thread in PhAB is a good
idea? or should I be using timers to wake up callbacks periodically?
I know that I can use PtTimer or RtTimer but they are not hard
real-time.
If I would like to use hard real-time to wake up these callbacks, do I
need to create a thread out side of the PhAB and talk to PhAB app? If
so what mechanism should I use for this communication link?

Thanks

Tell us more about what you’re trying to do, and it may be
possible to provide more help.

We’ve done hard real time control within Photon applications.
We drive the Overbot (http://www.overbot.com) in teleoperator
mode that way, using a steering wheel and pedals interfaced
through the USB HID interface, with network connections to
the Galil controllers on the vehicle using UDP. Meters
and dials on screen update as the vehicle moves. So
it’s certainly possible to do this, and it’s not all that hard.

We don’t make Photon calls from the real time
threads. We pass data between threads using shared
data protected by pthread mutexes, not Photon locks.
We did have to use PtEnter and PtLeave in one or two
places that aren’t time-critical.

All this works quite well in QNX. But you have
to know how to design multithread programs with
proper intercommunication.

John Nagle
Team Overbot

“John Nagle” <nagle@downside.com> wrote in message
news:d20dq8$k3r$1@inn.qnx.com

jinma wrote:

Tell us more about what you’re trying to do, and it may be
possible to provide more help.

We’ve done hard real time control within Photon applications.

Personaly I always try to decouple GUI and real time control. From
experience GUI are subjected to lots of update, move this button there,
change color here, add popup there. Having the real time control in a
Photon application means you have shutdown the system in order to update the
GUI or come up with some clever means of upgrading the software if it’s
important the system be up all the time.

Having the GUI in a different process also makes it a lot easier to have the
GUI run on another machine if need be.

Mario Charest wrote:

“John Nagle” <> nagle@downside.com> > wrote in message
news:d20dq8$k3r$> 1@inn.qnx.com> …

jinma wrote:

Tell us more about what you’re trying to do, and it may be
possible to provide more help.

We’ve done hard real time control within Photon applications.


Personaly I always try to decouple GUI and real time control. From
experience GUI are subjected to lots of update, move this button there,
change color here, add popup there. Having the real time control in a
Photon application means you have shutdown the system in order to update the
GUI or come up with some clever means of upgrading the software if it’s
important the system be up all the time.

I agree. We only did that for the teleoperated manual driving test mode,
where the GUI really is in the control loop.
All the operational software is QNX client/server.

John Nagle
Team Overbot

jinma wrote:

Ok if a real-time thread can be within the PhAB how can I execute this
thread without callback function having to wait for it by
pthread_join? Do I have to make the thread attribute with
PTHREAD_CREATE_DETACH? Furthermore, if my thread uses Photon library
calls, how can I make it work safely? For example, if I made the
callback function to wait for thread using pthread_join, I can do

PtLeave(0);
pthread_join();
PtEnter(0);

but if I don’t have this, can my thread still be able to get the lock
for PtEnter(0)?
Thanks

It all depends on what you’re trying to do and why… Typically, a
callback will create the realtime thread and return, and while the
thread is doing its realtime thing, the GUI thread will continue to
process Photon events. If the realtime thread needs to tell the GUI
that it’s done, it could send a pulse just before terminating, and then
an input proc attached to the pulse could do the join in the GUI thread.
But it may be simpler for the realtime thread to just call PtEnter(),
update the GUI, and terminate. Calling PtEnter() gives up the
realtimeness, but should be OK after you’re done with your realtime job.

You do want your GUI to keep reacting to GUI events while the realtime
thread is doing its realtime thing, don’t you?

Wojtek Lerch wrote:

jinma wrote:

Ok if a real-time thread can be within the PhAB how can I execute this
thread without callback function having to wait for it by
pthread_join? Do I have to make the thread attribute with
PTHREAD_CREATE_DETACH? Furthermore, if my thread uses Photon library
calls, how can I make it work safely? For example, if I made the
callback function to wait for thread using pthread_join, I can do
PtLeave(0);
pthread_join();
PtEnter(0);

but if I don’t have this, can my thread still be able to get the lock
for PtEnter(0)?
Thanks


It all depends on what you’re trying to do and why… Typically, a
callback will create the realtime thread and return, and while the
thread is doing its realtime thing, the GUI thread will continue to
process Photon events. If the realtime thread needs to tell the GUI
that it’s done, it could send a pulse just before terminating, and then
an input proc attached to the pulse could do the join in the GUI thread.
But it may be simpler for the realtime thread to just call PtEnter(),
update the GUI, and terminate. Calling PtEnter() gives up the
realtimeness, but should be OK after you’re done with your realtime job.

You do want your GUI to keep reacting to GUI events while the realtime
thread is doing its realtime thing, don’t you?
fwiw,

Our lab has a process that gets analog data from an A/D card and
displays the data in PtRaw widgets. To start data collection, the GUI
thread creates a realtime thread. The realtime thread sets up the A/D
board and enables interrupts, then sits in a loop, waiting for
interrupts. The A/D board dma’s the data into a circular buffer and
generates an interrupt. After each interrupt, the realtime thread sets a
pointer to the top of the new data, then processes the new data.
Interrupts occur every 1024 microseconds. The GUI thread contains a
PtTimer widget which fires every 16 milliseconds. The timer widget
callback calls a function that sets up the new data and calls
PtDamageWidget on the PtRaw widget.

JohnMcClurkin wrote:

fwiw,
Our lab has a process that gets analog data from an A/D card and
displays the data in PtRaw widgets. To start data collection, the GUI
thread creates a realtime thread. The realtime thread sets up the A/D
board and enables interrupts, then sits in a loop, waiting for
interrupts. The A/D board dma’s the data into a circular buffer and
generates an interrupt. After each interrupt, the realtime thread sets a
pointer to the top of the new data, then processes the new data.
Interrupts occur every 1024 microseconds. The GUI thread contains a
PtTimer widget which fires every 16 milliseconds. The timer widget
callback calls a function that sets up the new data and calls
PtDamageWidget on the PtRaw widget.

That sounds very reasonable… In cases where you need a tighter
coupling between the two threads, you could replace the PtTimer with a
pulse and an input proc, or a condvar and a third thread.

Wojtek Lerch wrote:

JohnMcClurkin wrote:

fwiw,
Our lab has a process that gets analog data from an A/D card and
displays the data in PtRaw widgets. To start data collection, the GUI
thread creates a realtime thread. The realtime thread sets up the A/D
board and enables interrupts, then sits in a loop, waiting for
interrupts. The A/D board dma’s the data into a circular buffer and
generates an interrupt. After each interrupt, the realtime thread sets
a pointer to the top of the new data, then processes the new data.
Interrupts occur every 1024 microseconds. The GUI thread contains a
PtTimer widget which fires every 16 milliseconds. The timer widget
callback calls a function that sets up the new data and calls
PtDamageWidget on the PtRaw widget.


That sounds very reasonable… In cases where you need a tighter
coupling between the two threads, you could replace the PtTimer with a
pulse and an input proc, or a condvar and a third thread.
We considered a condvar, but chose not to go that route because we

didn’t want to damage the PtRaw widgets more often than the refresh rate
of our monitors (16.67 msec). After all, what the user sees in the PtRaw
widget cannot change more often than the refresh rate of the monitor. In
summary, it seems that the tightness of the coupling between the
realtime thread and the GUI thread will be limited by the refresh rate
of the monitor.

JohnMcClurkinwrote:

Our lab has a process that gets analog data from an A/D card and
displays the data in PtRaw widgets. To start data collection, the
GUI
thread creates a realtime thread. The realtime thread sets up the
A/D
board and enables interrupts, then sits in a loop, waiting for
interrupts. The A/D board dma’s the data into a circular buffer and

generates an interrupt. After each interrupt, the realtime thread
sets a
pointer to the top of the new data, then processes the new data.
Interrupts occur every 1024 microseconds. The GUI thread contains a

PtTimer widget which fires every 16 milliseconds. The timer widget
callback calls a function that sets up the new data and calls
PtDamageWidget on the PtRaw widget.

Can you post your code about Pttimer and Ptraw . Thanks

dxwang wrote:

JohnMcClurkinwrote:


Our lab has a process that gets analog data from an A/D card and
displays the data in PtRaw widgets. To start data collection, the

GUI

thread creates a realtime thread. The realtime thread sets up the

A/D

board and enables interrupts, then sits in a loop, waiting for
interrupts. The A/D board dma’s the data into a circular buffer and


generates an interrupt. After each interrupt, the realtime thread

sets a

pointer to the top of the new data, then processes the new data.
Interrupts occur every 1024 microseconds. The GUI thread contains a


PtTimer widget which fires every 16 milliseconds. The timer widget
callback calls a function that sets up the new data and calls
PtDamageWidget on the PtRaw widget.


Can you post your code about Pttimer and Ptraw . Thanks

Posting the code here might be too combersome. If any one is interested,

go to http://lsr-web.net and click on Tools->Mex, and download
rtpMex25_28Mar2006.tar.gz. Unpack the tarball and change to the src
subdirectory. The code that switches the graphics timer is in the
function switchSampling in the file mexClock.c. The timer callback is
mexGraphicsInterrupt in the file mexGraphics.c. There are a number of
PtRaw widgets, but a simple example is setSignalData in the file
mexSignal.c. In this file, the function signalExtent is called in
response to window resizes, and the function signalDraw is the function
that is called in response to PtDamageWidget events.

dxwang wrote:

JohnMcClurkinwrote:


Our lab has a process that gets analog data from an A/D card and
displays the data in PtRaw widgets. To start data collection, the

You are adding to a message thread from April 2005. Is this a new
problem, or what?

You might find our “mutexlock.h” from this page useful.

http://www.overbot.com/public/qnx

Create an instance of BoundedBuffer, which is a queue
class for multithreaded programs. Put entries into it
using “tryput” from the real-time thread. In the screen update
thread, repeatedly do “tryget” to get new items to display,
until you a false return from “tryget”. This will handle your
circular buffer locking problems, if you’re not familiar
with how to do that yourself.

John Nagle

On Mon, 05 Jun 2006 20:48:27 -0700, John Nagle wrote:

You might find our “mutexlock.h” from this page useful.

http://www.overbot.com/public/qnx

John - I quite like your approach there but we can’t use it as it is LGPL
and we are a closed source shop. Are you prepared to consider a different
license?

Rob Rutherford
Ruzz Technology

Robert Rutherford wrote:

On Mon, 05 Jun 2006 20:48:27 -0700, John Nagle wrote:

You might find our “mutexlock.h” from this page useful.

http://www.overbot.com/public/qnx



John - I quite like your approach there but we can’t use it as it is LGPL
and we are a closed source shop. Are you prepared to consider a different
license?

No, that would be inappropriate.

Realize that most of the libraries used with GCC are licensed under the LGPL,
so most QNX applications already contain LGPL code. This is not usually a
problem unless you modify the library.

John Nagle