comp.lang.ada
 help / color / mirror / Atom feed
* Tasking and wxWidgets
@ 2005-11-25 10:05 Lucretia
  2005-11-25 10:53 ` Martin Dowie
                   ` (2 more replies)
  0 siblings, 3 replies; 19+ messages in thread
From: Lucretia @ 2005-11-25 10:05 UTC (permalink / raw)


I've posted this to the wxWidgets development list, but I thought I'd
post here as well to get the Ada perspective.

I'm probably going to answer my own question here, but here goes...

I know that wxWidgets isn't thread-safe. I know that the advice given
is to only do GUI related things in the main thread and to use worker
threads as and when required to do other stuff and post the results
back to the main thread via some sort of intermediary event queue or
somesuch. But, there are a few things I would like to discuss with
other developers here before I decide what to do with respect to wxAda.

1) Is there any situation where having multiple threads with it's own
(or shared) GUI makes sense? Can anybody actually think of any examples
where, say, a frame has multiple threads and they all (or some) want to
update the GUI?

As an example, say you have an monitoring application which has on it a
number of controls, e.g. temperature, pressure guages, It would be
possible to set up two threads which monitor the actual sensors and
send events directly to the temperature/pressure wxGuage controls.

Another example would be to provide a log window in which error
messages from these same sensors could be dumped, in this case the
wxEvtHandler derived class is accessed by two different threads
concurrently and would need t synchronised.

2) How portable wuold this be exactly? Could I compile the same code
and have it work correctly on Linux, Win32 and MacOS?

Now, coming round to wxAda, I need to determine what exactly to do:

1) I could provide no support for tasking (multithreading) and require
that the application developer protect his/her own code.

2) I could also go the other way and inside the
wx.Base.Object.Object_Type (wxObject) provide a mutex object, such that
every call in wxAda would lock (on entry) and unlock (on exit) thus
providing thread safety if that particular object were accessed via
multiple tasks. The overhead of constructing/destructing a mutex locker
object, locking/unlocking the mutex object on every call would be
rather high and thus, would most probably slow the application down to
a crawl (although, not tested). Use of inlining might make this nicer?

3) I could go part-way and only provide concurrent access to the event
sending functions.

4) Is it possible that the synchronisation code that *is* in the
wxWidgets library (I'm not talking about the actual wxThread,
wxSemaphore, etc. classes here, but the places where there is critical
sections to protect concurrent access) could interfere with Ada's
tasking and protected types (Ada's implementation of monitors)?

Thanks,
Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 10:05 Tasking and wxWidgets Lucretia
@ 2005-11-25 10:53 ` Martin Dowie
  2005-11-26 17:32   ` Lucretia
  2005-11-25 11:37 ` Dmitry A. Kazakov
  2005-11-26  7:46 ` Simon Wright
  2 siblings, 1 reply; 19+ messages in thread
From: Martin Dowie @ 2005-11-25 10:53 UTC (permalink / raw)


Lucretia wrote:
> 2) I could also go the other way and inside the
> wx.Base.Object.Object_Type (wxObject) provide a mutex object, such
> that every call in wxAda would lock (on entry) and unlock (on exit)
> thus providing thread safety if that particular object were accessed
> via multiple tasks. The overhead of constructing/destructing a mutex
> locker object, locking/unlocking the mutex object on every call would
> be rather high and thus, would most probably slow the application
> down to a crawl (although, not tested). Use of inlining might make
> this nicer?

Is the different between a response in 0.1 seconds and 0.15 seconds
particularly noticable with a GUI? I'm guessing at the actual times but
surely they are going to be very small (to the human eye), no?...

Could you provide the locking as an option at compile time? I.e. have 2
packages that providing locking but one is "begin null end;" (or "is null;"
for Ada2005, yes?) for everything.

Cheers

-- Martin





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 10:05 Tasking and wxWidgets Lucretia
  2005-11-25 10:53 ` Martin Dowie
@ 2005-11-25 11:37 ` Dmitry A. Kazakov
  2005-11-26 17:26   ` Lucretia
                     ` (3 more replies)
  2005-11-26  7:46 ` Simon Wright
  2 siblings, 4 replies; 19+ messages in thread
From: Dmitry A. Kazakov @ 2005-11-25 11:37 UTC (permalink / raw)


On 25 Nov 2005 02:05:11 -0800, Lucretia wrote:

> 1) Is there any situation where having multiple threads with it's own
> (or shared) GUI makes sense? Can anybody actually think of any examples
> where, say, a frame has multiple threads and they all (or some) want to
> update the GUI?
> 
> As an example, say you have an monitoring application which has on it a
> number of controls, e.g. temperature, pressure guages, It would be
> possible to set up two threads which monitor the actual sensors and
> send events directly to the temperature/pressure wxGuage controls.
>
> Another example would be to provide a log window in which error
> messages from these same sensors could be dumped, in this case the
> wxEvtHandler derived class is accessed by two different threads
> concurrently and would need t synchronised.

Yes both is the case for HMIs (human-machine interface) used to control
some large test system (like a dynamometer.) But it is only one side of the
issue. Another is the actions invoked by the GUI. If an action is
synchronous (that's you cannot continue), and it is often the case, then
with a single-thread design you block the whole GUI. Now, imagine, the
operator starts daily log print, which is busy opening that idiotic printer
properties dialog. Suddenly something gets wrong, really wrong ... and the
"emergency stop" button is dead.

> 2) I could also go the other way and inside the
> wx.Base.Object.Object_Type (wxObject) provide a mutex object, such that
> every call in wxAda would lock (on entry) and unlock (on exit) thus
> providing thread safety if that particular object were accessed via
> multiple tasks. The overhead of constructing/destructing a mutex locker
> object, locking/unlocking the mutex object on every call would be
> rather high and thus, would most probably slow the application down to
> a crawl (although, not tested). Use of inlining might make this nicer?

That depends on the architecture of the GUI system. I don't know wxWidgets.

In the GUI system we developed for HMIs, rendering and data feeding are
often separated. They have independent cycles and consequently are used
from different threads. Locking overhead was never a problem [well, I
presume, you aren't going to perform pixelwise image transformation.] We
often use a specialized "mutex" which allows parallel read access if there
is no any write access. It would be nice to use Ada's protected objects
here, because they basically have this functionality, but unfortunately 1)
the thing is in C++, 2) Ada's protected objects aren't OO composable, they
are not tagged.

You should also consider Ada tasks, which sometimes are more natural than
protected objects.

And more than two mutexes is a problem. You should try to make the API
composable without or minimal deadlock danger. For example, Windows GUI API
can deadlock, and often do.

> 4) Is it possible that the synchronisation code that *is* in the
> wxWidgets library (I'm not talking about the actual wxThread,
> wxSemaphore, etc. classes here, but the places where there is critical
> sections to protect concurrent access) could interfere with Ada's
> tasking and protected types (Ada's implementation of monitors)?

Very unlikely, IMO. [Provided, Ada run-time is using native threads.]

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 10:05 Tasking and wxWidgets Lucretia
  2005-11-25 10:53 ` Martin Dowie
  2005-11-25 11:37 ` Dmitry A. Kazakov
@ 2005-11-26  7:46 ` Simon Wright
  2005-11-28 10:37   ` Lucretia
  2 siblings, 1 reply; 19+ messages in thread
From: Simon Wright @ 2005-11-26  7:46 UTC (permalink / raw)


"Lucretia" <lucretia9@lycos.co.uk> writes:

> 2) I could also go the other way and inside the
> wx.Base.Object.Object_Type (wxObject) provide a mutex object, such
> that every call in wxAda would lock (on entry) and unlock (on exit)
> thus providing thread safety if that particular object were accessed
> via multiple tasks. The overhead of constructing/destructing a mutex
> locker object, locking/unlocking the mutex object on every call
> would be rather high and thus, would most probably slow the
> application down to a crawl (although, not tested). Use of inlining
> might make this nicer?

Not clear that inlining would help a lot here.

What would be acceptable? Using a Lock from the Booch �components
(http://booch95.sourceforge.net) takes just under 20 us on a 1.5GHz
Powerbook.

   with Ada.Text_IO; use Ada.Text_IO;
   with BC.Support.High_Resolution_Time;
   with BC.Support.Synchronization;
   procedure Time_Lock is
      Mutex : aliased BC.Support.Synchronization.Semaphore;
      Start, Finish : BC.Support.High_Resolution_Time.Time;
      use type BC.Support.High_Resolution_Time.Time;
   begin
      Start := BC.Support.High_Resolution_Time.Clock;
      declare
         L : BC.Support.Synchronization.Lock (Mutex'Access);
         pragma Unreferenced (L);
      begin
         --  Mutex now secured and will be released on block exit (even
         --  on exception)
         null;
      end;
      Finish := BC.Support.High_Resolution_Time.Clock;
      Put_Line ("took " & Duration'Image (Finish - Start));
   end Time_Lock;



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 11:37 ` Dmitry A. Kazakov
@ 2005-11-26 17:26   ` Lucretia
  2005-11-27 11:15     ` Dmitry A. Kazakov
  2005-11-26 17:26   ` Lucretia
                     ` (2 subsequent siblings)
  3 siblings, 1 reply; 19+ messages in thread
From: Lucretia @ 2005-11-26 17:26 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On 25 Nov 2005 02:05:11 -0800, Lucretia wrote:
>
> Yes both is the case for HMIs (human-machine interface) used to control
> some large test system (like a dynamometer.) But it is only one side of the
> issue. Another is the actions invoked by the GUI. If an action is
> synchronous (that's you cannot continue), and it is often the case, then
> with a single-thread design you block the whole GUI. Now, imagine, the
> operator starts daily log print, which is busy opening that idiotic printer
> properties dialog. Suddenly something gets wrong, really wrong ... and the
> "emergency stop" button is dead.

Hmm, but if each wxAda type had it's own mutex, surely you'd only end
up locking that particular object at any one time?

> > 2) I could also go the other way and inside the
> > wx.Base.Object.Object_Type (wxObject) provide a mutex object, such that
> > every call in wxAda would lock (on entry) and unlock (on exit) thus
> > providing thread safety if that particular object were accessed via
> > multiple tasks. The overhead of constructing/destructing a mutex locker
> > object, locking/unlocking the mutex object on every call would be
> > rather high and thus, would most probably slow the application down to
> > a crawl (although, not tested). Use of inlining might make this nicer?
>
> That depends on the architecture of the GUI system. I don't know wxWidgets.

Yeah.

> In the GUI system we developed for HMIs, rendering and data feeding are
> often separated. They have independent cycles and consequently are used
> from different threads. Locking overhead was never a problem [well, I
> presume, you aren't going to perform pixelwise image transformation.] We

It's a possibility if somebody wanted to create an image manipulation
program with wxAda?!

> often use a specialized "mutex" which allows parallel read access if there
> is no any write access. It would be nice to use Ada's protected objects
> here, because they basically have this functionality, but unfortunately 1)
> the thing is in C++, 2) Ada's protected objects aren't OO composable, they
> are not tagged.

Exactly, and getting multiple objects using protected objects is
impossible, unfortunately.

> You should also consider Ada tasks, which sometimes are more natural than
> protected objects.

Still would be impossible to do, this is why I was considering leaving
the library as non-thread-safe and allowing the application developer
to handle concurrency issues.

> And more than two mutexes is a problem. You should try to make the API
> composable without or minimal deadlock danger. For example, Windows GUI API

I'm not sure what you mean about "composable without or minimal
deadlock danger"

> can deadlock, and often do.
>
> > 4) Is it possible that the synchronisation code that *is* in the
> > wxWidgets library (I'm not talking about the actual wxThread,
> > wxSemaphore, etc. classes here, but the places where there is critical
> > sections to protect concurrent access) could interfere with Ada's
> > tasking and protected types (Ada's implementation of monitors)?
>
> Very unlikely, IMO. [Provided, Ada run-time is using native threads.]

Yeah, I know that the RTS uses native threads...This is what I thought,
I just needed to be sure.

Thanks,
Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 11:37 ` Dmitry A. Kazakov
  2005-11-26 17:26   ` Lucretia
@ 2005-11-26 17:26   ` Lucretia
  2005-11-26 17:28   ` Lucretia
  2005-11-26 17:34   ` Lucretia
  3 siblings, 0 replies; 19+ messages in thread
From: Lucretia @ 2005-11-26 17:26 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On 25 Nov 2005 02:05:11 -0800, Lucretia wrote:
>
> Yes both is the case for HMIs (human-machine interface) used to control
> some large test system (like a dynamometer.) But it is only one side of the
> issue. Another is the actions invoked by the GUI. If an action is
> synchronous (that's you cannot continue), and it is often the case, then
> with a single-thread design you block the whole GUI. Now, imagine, the
> operator starts daily log print, which is busy opening that idiotic printer
> properties dialog. Suddenly something gets wrong, really wrong ... and the
> "emergency stop" button is dead.

Hmm, but if each wxAda type had it's own mutex, surely you'd only end
up locking that particular object at any one time?

> > 2) I could also go the other way and inside the
> > wx.Base.Object.Object_Type (wxObject) provide a mutex object, such that
> > every call in wxAda would lock (on entry) and unlock (on exit) thus
> > providing thread safety if that particular object were accessed via
> > multiple tasks. The overhead of constructing/destructing a mutex locker
> > object, locking/unlocking the mutex object on every call would be
> > rather high and thus, would most probably slow the application down to
> > a crawl (although, not tested). Use of inlining might make this nicer?
>
> That depends on the architecture of the GUI system. I don't know wxWidgets.

Yeah.

> In the GUI system we developed for HMIs, rendering and data feeding are
> often separated. They have independent cycles and consequently are used
> from different threads. Locking overhead was never a problem [well, I
> presume, you aren't going to perform pixelwise image transformation.] We

It's a possibility if somebody wanted to create an image manipulation
program with wxAda?!

> often use a specialized "mutex" which allows parallel read access if there
> is no any write access. It would be nice to use Ada's protected objects
> here, because they basically have this functionality, but unfortunately 1)
> the thing is in C++, 2) Ada's protected objects aren't OO composable, they
> are not tagged.

Exactly, and getting multiple objects using protected objects is
impossible, unfortunately.

> You should also consider Ada tasks, which sometimes are more natural than
> protected objects.

Still would be impossible to do, this is why I was considering leaving
the library as non-thread-safe and allowing the application developer
to handle concurrency issues.

> And more than two mutexes is a problem. You should try to make the API
> composable without or minimal deadlock danger. For example, Windows GUI API

I'm not sure what you mean about "composable without or minimal
deadlock danger"

> can deadlock, and often do.
>
> > 4) Is it possible that the synchronisation code that *is* in the
> > wxWidgets library (I'm not talking about the actual wxThread,
> > wxSemaphore, etc. classes here, but the places where there is critical
> > sections to protect concurrent access) could interfere with Ada's
> > tasking and protected types (Ada's implementation of monitors)?
>
> Very unlikely, IMO. [Provided, Ada run-time is using native threads.]

Yeah, I know that the RTS uses native threads...This is what I thought,
I just needed to be sure.

Thanks,
Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 11:37 ` Dmitry A. Kazakov
  2005-11-26 17:26   ` Lucretia
  2005-11-26 17:26   ` Lucretia
@ 2005-11-26 17:28   ` Lucretia
  2005-11-26 17:34   ` Lucretia
  3 siblings, 0 replies; 19+ messages in thread
From: Lucretia @ 2005-11-26 17:28 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On 25 Nov 2005 02:05:11 -0800, Lucretia wrote:
>
> Yes both is the case for HMIs (human-machine interface) used to control
> some large test system (like a dynamometer.) But it is only one side of the
> issue. Another is the actions invoked by the GUI. If an action is
> synchronous (that's you cannot continue), and it is often the case, then
> with a single-thread design you block the whole GUI. Now, imagine, the
> operator starts daily log print, which is busy opening that idiotic printer
> properties dialog. Suddenly something gets wrong, really wrong ... and the
> "emergency stop" button is dead.

Hmm, but if each wxAda type had it's own mutex, surely you'd only end
up locking that particular object at any one time?

> > 2) I could also go the other way and inside the
> > wx.Base.Object.Object_Type (wxObject) provide a mutex object, such that
> > every call in wxAda would lock (on entry) and unlock (on exit) thus
> > providing thread safety if that particular object were accessed via
> > multiple tasks. The overhead of constructing/destructing a mutex locker
> > object, locking/unlocking the mutex object on every call would be
> > rather high and thus, would most probably slow the application down to
> > a crawl (although, not tested). Use of inlining might make this nicer?
>
> That depends on the architecture of the GUI system. I don't know wxWidgets.

Yeah.

> In the GUI system we developed for HMIs, rendering and data feeding are
> often separated. They have independent cycles and consequently are used
> from different threads. Locking overhead was never a problem [well, I
> presume, you aren't going to perform pixelwise image transformation.] We

It's a possibility if somebody wanted to create an image manipulation
program with wxAda?!

> often use a specialized "mutex" which allows parallel read access if there
> is no any write access. It would be nice to use Ada's protected objects
> here, because they basically have this functionality, but unfortunately 1)
> the thing is in C++, 2) Ada's protected objects aren't OO composable, they
> are not tagged.

Exactly, and getting multiple objects using protected objects is
impossible, unfortunately.

> You should also consider Ada tasks, which sometimes are more natural than
> protected objects.

Still would be impossible to do, this is why I was considering leaving
the library as non-thread-safe and allowing the application developer
to handle concurrency issues.

> And more than two mutexes is a problem. You should try to make the API
> composable without or minimal deadlock danger. For example, Windows GUI API

I'm not sure what you mean about "composable without or minimal
deadlock danger"

> can deadlock, and often do.
>
> > 4) Is it possible that the synchronisation code that *is* in the
> > wxWidgets library (I'm not talking about the actual wxThread,
> > wxSemaphore, etc. classes here, but the places where there is critical
> > sections to protect concurrent access) could interfere with Ada's
> > tasking and protected types (Ada's implementation of monitors)?
>
> Very unlikely, IMO. [Provided, Ada run-time is using native threads.]

Yeah, I know that the RTS uses native threads...This is what I thought,
I just needed to be sure.

Thanks,
Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 10:53 ` Martin Dowie
@ 2005-11-26 17:32   ` Lucretia
  2005-11-26 18:23     ` Martin Dowie
  0 siblings, 1 reply; 19+ messages in thread
From: Lucretia @ 2005-11-26 17:32 UTC (permalink / raw)



Martin Dowie wrote:
> Lucretia wrote:
> > 2) I could also go the other way and inside the
> > wx.Base.Object.Object_Type (wxObject) provide a mutex object, such
> > that every call in wxAda would lock (on entry) and unlock (on exit)
> > thus providing thread safety if that particular object were accessed
> > via multiple tasks. The overhead of constructing/destructing a mutex
> > locker object, locking/unlocking the mutex object on every call would
> > be rather high and thus, would most probably slow the application
> > down to a crawl (although, not tested). Use of inlining might make
> > this nicer?
>
> Is the different between a response in 0.1 seconds and 0.15 seconds
> particularly noticable with a GUI? I'm guessing at the actual times but
> surely they are going to be very small (to the human eye), no?...

Well, yeah. It is unlikely that wxAda will be used within the embedded
sector, so it may not be that feasible, but I was wondering more about
the fact that there are a lot of calls in wxWidgets and that if every
call was blocking, it may end up being particularly slooow when
multiple tasks start to use the objects concurrently.

> Could you provide the locking as an option at compile time? I.e. have 2
> packages that providing locking but one is "begin null end;" (or "is null;"
> for Ada2005, yes?) for everything.

That would be a big job as there is no preprocessor for Ada (only GNAT
- and this lib is to be portable).

Yeah, there will be an Ada 2005 version after the Ada 95 version.

Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-25 11:37 ` Dmitry A. Kazakov
                     ` (2 preceding siblings ...)
  2005-11-26 17:28   ` Lucretia
@ 2005-11-26 17:34   ` Lucretia
  3 siblings, 0 replies; 19+ messages in thread
From: Lucretia @ 2005-11-26 17:34 UTC (permalink / raw)


Dmitry A. Kazakov wrote:
> On 25 Nov 2005 02:05:11 -0800, Lucretia wrote:
>
> Yes both is the case for HMIs (human-machine interface) used to control
> some large test system (like a dynamometer.) But it is only one side of the
> issue. Another is the actions invoked by the GUI. If an action is
> synchronous (that's you cannot continue), and it is often the case, then
> with a single-thread design you block the whole GUI. Now, imagine, the
> operator starts daily log print, which is busy opening that idiotic printer
> properties dialog. Suddenly something gets wrong, really wrong ... and the
> "emergency stop" button is dead.

Hmm, but if each wxAda type had it's own mutex, surely you'd only end
up locking that particular object at any one time?

> > 2) I could also go the other way and inside the
> > wx.Base.Object.Object_Type (wxObject) provide a mutex object, such that
> > every call in wxAda would lock (on entry) and unlock (on exit) thus
> > providing thread safety if that particular object were accessed via
> > multiple tasks. The overhead of constructing/destructing a mutex locker
> > object, locking/unlocking the mutex object on every call would be
> > rather high and thus, would most probably slow the application down to
> > a crawl (although, not tested). Use of inlining might make this nicer?
>
> That depends on the architecture of the GUI system. I don't know wxWidgets.

Yeah.

> In the GUI system we developed for HMIs, rendering and data feeding are
> often separated. They have independent cycles and consequently are used
> from different threads. Locking overhead was never a problem [well, I
> presume, you aren't going to perform pixelwise image transformation.] We

It's a possibility if somebody wanted to create an image manipulation
program with wxAda?!

> often use a specialized "mutex" which allows parallel read access if there
> is no any write access. It would be nice to use Ada's protected objects
> here, because they basically have this functionality, but unfortunately 1)
> the thing is in C++, 2) Ada's protected objects aren't OO composable, they
> are not tagged.

Exactly, and getting multiple objects using protected objects is
impossible, unfortunately.

> You should also consider Ada tasks, which sometimes are more natural than
> protected objects.

Still would be impossible to do, this is why I was considering leaving
the library as non-thread-safe and allowing the application developer
to handle concurrency issues.

> And more than two mutexes is a problem. You should try to make the API
> composable without or minimal deadlock danger. For example, Windows GUI API

I'm not sure what you mean about "composable without or minimal
deadlock danger"

> can deadlock, and often do.
>
> > 4) Is it possible that the synchronisation code that *is* in the
> > wxWidgets library (I'm not talking about the actual wxThread,
> > wxSemaphore, etc. classes here, but the places where there is critical
> > sections to protect concurrent access) could interfere with Ada's
> > tasking and protected types (Ada's implementation of monitors)?
>
> Very unlikely, IMO. [Provided, Ada run-time is using native threads.]

Yeah, I know that the RTS uses native threads...This is what I thought,
I just needed to be sure.

Thanks,
Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-26 17:32   ` Lucretia
@ 2005-11-26 18:23     ` Martin Dowie
  2005-11-29  3:07       ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Martin Dowie @ 2005-11-26 18:23 UTC (permalink / raw)


Lucretia wrote:
> Well, yeah. It is unlikely that wxAda will be used within the embedded
> sector, so it may not be that feasible, but I was wondering more about
> the fact that there are a lot of calls in wxWidgets and that if every
> call was blocking, it may end up being particularly slooow when
> multiple tasks start to use the objects concurrently.

Only if they lock and then do something slow or if you have loads of 
tasks all queue on the same lock.


>>Could you provide the locking as an option at compile time? I.e. have 2
>>packages that providing locking but one is "begin null end;" (or "is null;"
>>for Ada2005, yes?) for everything.
> 
> 
> That would be a big job as there is no preprocessor for Ada (only GNAT
> - and this lib is to be portable).
> 
> Yeah, there will be an Ada 2005 version after the Ada 95 version.

You won't need a preprocessor (although GNAT does have one 'gnatprep') - 
same spec, different bodies.

-- Spec
procedure Foo;

-- Body
procedure Foo is null;

Cheers

-- Martin



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-26 17:26   ` Lucretia
@ 2005-11-27 11:15     ` Dmitry A. Kazakov
  2005-11-28 10:48       ` Lucretia
  0 siblings, 1 reply; 19+ messages in thread
From: Dmitry A. Kazakov @ 2005-11-27 11:15 UTC (permalink / raw)


On 26 Nov 2005 09:26:17 -0800, Lucretia wrote:

> Dmitry A. Kazakov wrote:
>> On 25 Nov 2005 02:05:11 -0800, Lucretia wrote:
>>
>> Yes both is the case for HMIs (human-machine interface) used to control
>> some large test system (like a dynamometer.) But it is only one side of the
>> issue. Another is the actions invoked by the GUI. If an action is
>> synchronous (that's you cannot continue), and it is often the case, then
>> with a single-thread design you block the whole GUI. Now, imagine, the
>> operator starts daily log print, which is busy opening that idiotic printer
>> properties dialog. Suddenly something gets wrong, really wrong ... and the
>> "emergency stop" button is dead.
> 
> Hmm, but if each wxAda type had it's own mutex, surely you'd only end
> up locking that particular object at any one time?

Depends on what is the object here, and what is allowed to do with a mutex
taken. If there is a possibility to perform blocking actions within other
actions, then be ready for hell. One way to get out of this is to remove
mutexes from objects and pass them as parameters or discriminants. Another
is to use monitor tasks.

>> In the GUI system we developed for HMIs, rendering and data feeding are
>> often separated. They have independent cycles and consequently are used
>> from different threads. Locking overhead was never a problem [well, I
>> presume, you aren't going to perform pixelwise image transformation.] We
> 
> It's a possibility if somebody wanted to create an image manipulation
> program with wxAda?!

Do you ask me? (:-)) Look at absolutely useless Window's SetPixel. Then
you'll need double buffering and all that stuff. 

>> often use a specialized "mutex" which allows parallel read access if there
>> is no any write access. It would be nice to use Ada's protected objects
>> here, because they basically have this functionality, but unfortunately 1)
>> the thing is in C++, 2) Ada's protected objects aren't OO composable, they
>> are not tagged.
> 
> Exactly, and getting multiple objects using protected objects is
> impossible, unfortunately.

Hmm, do you mean multiple protected actions here?

>> You should also consider Ada tasks, which sometimes are more natural than
>> protected objects.
> 
> Still would be impossible to do, this is why I was considering leaving
> the library as non-thread-safe and allowing the application developer
> to handle concurrency issues.

You should separate it into safe and unsafe parts. You don't need
thread-safe String, you probably need safe Show_Text.

>> And more than two mutexes is a problem. You should try to make the API
>> composable without or minimal deadlock danger. For example, Windows GUI API
> 
> I'm not sure what you mean about "composable without or minimal
> deadlock danger"

From the messages loop [in a deeply nested callback subprogram] you spin
for a mutex held by another thread that does SetWindowText to the window.
Here you are.

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-26  7:46 ` Simon Wright
@ 2005-11-28 10:37   ` Lucretia
  2005-11-29 21:38     ` Simon Wright
  0 siblings, 1 reply; 19+ messages in thread
From: Lucretia @ 2005-11-28 10:37 UTC (permalink / raw)


> Not clear that inlining would help a lot here.

To avoid the actual function calls (of which the bodies are tiny),
makes the binary slightly bigger, but then that's teh tradeoff, isn't
it?

> What would be acceptable? Using a Lock from the Booch çcomponents
> (http://booch95.sourceforge.net) takes just under 20 us on a 1.5GHz
> Powerbook.

I really doubt that the Booch components are written any differently to
mine. So, why would I need to?

Thanks, 
Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-27 11:15     ` Dmitry A. Kazakov
@ 2005-11-28 10:48       ` Lucretia
  2005-11-28 14:41         ` Dmitry A. Kazakov
  0 siblings, 1 reply; 19+ messages in thread
From: Lucretia @ 2005-11-28 10:48 UTC (permalink / raw)


> > Hmm, but if each wxAda type had it's own mutex, surely you'd only end
> > up locking that particular object at any one time?
>
> Depends on what is the object here, and what is allowed to do with a mutex
> taken. If there is a possibility to perform blocking actions within other
> actions, then be ready for hell. One way to get out of this is to remove
> mutexes from objects and pass them as parameters or discriminants. Another
> is to use monitor tasks.

The object could be any of the wx objects, a wxFrame, wxButton,
wxToolBar, wxStatusBar, etc.

> > It's a possibility if somebody wanted to create an image manipulation
> > program with wxAda?!
>
> Do you ask me? (:-)) Look at absolutely useless Window's SetPixel. Then
> you'll need double buffering and all that stuff.

No! I mean't it is possible that somebody would want to.

> >> often use a specialized "mutex" which allows parallel read access if there
> >> is no any write access. It would be nice to use Ada's protected objects
> >> here, because they basically have this functionality, but unfortunately 1)
> >> the thing is in C++, 2) Ada's protected objects aren't OO composable, they
> >> are not tagged.
> >
> > Exactly, and getting multiple objects using protected objects is
> > impossible, unfortunately.
>
> Hmm, do you mean multiple protected actions here?

No! I mean you cannot create derivable types from protected types. The
wxAda hierarchy matches that of the C++ wxWidgets hierarchy. wxObject
(wx.Base.Object.Object_Type) is the base type and everything derives
from there. wxEvtHandler (wx.Base.Event_Handler.Event_Handler_Type)
derives from wxObject. wxWindow derives from wxEvtHandler. wxControl
derives from wxWindow. etc.

So, how do you make this thread safe? All controls are windows and all
events go through the event handler classes. In the wxWidgets library
there is minimal thread safe code in the event handling code, but do I
want to make a completely thread safe library or leave it up to the
application developer?

> >> And more than two mutexes is a problem. You should try to make the API
> >> composable without or minimal deadlock danger. For example, Windows GUI API
> >
> > I'm not sure what you mean about "composable without or minimal
> > deadlock danger"
>
> From the messages loop [in a deeply nested callback subprogram] you spin
> for a mutex held by another thread that does SetWindowText to the window.
> Here you are.

Eh?

Thanks,
Luke.




^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-28 10:48       ` Lucretia
@ 2005-11-28 14:41         ` Dmitry A. Kazakov
  0 siblings, 0 replies; 19+ messages in thread
From: Dmitry A. Kazakov @ 2005-11-28 14:41 UTC (permalink / raw)


On 28 Nov 2005 02:48:26 -0800, Lucretia wrote:

> The object could be any of the wx objects, a wxFrame, wxButton,
> wxToolBar, wxStatusBar, etc.

This is rather a "visual" hierarchy, i.e. things are arranged on the
screen. But how does it work. Does wxButton send a message to wxFrame, or
wxFrame queries wxButton for its state, or maybe wxButton has On_Click
abstract method to override etc.

> No! I mean you cannot create derivable types from protected types.

Yes. However you can:

   type Protected_Action is abstract tagged ...
   procedure Perform (What : in out Protected_Action) is abstract;

   protected type Subject is
      entry Request (What : in out Protected_Action'Class);
      ...

   protected body Subject is
      entry Request (What : in out Protected_Action'Class) ... is
      begin
         Perform (What); -- Dispatches
      end;

Yet, it would be a very bad idea to perform rendering from a protected
action.

> wxAda hierarchy matches that of the C++ wxWidgets hierarchy. wxObject
> (wx.Base.Object.Object_Type) is the base type and everything derives
> from there. wxEvtHandler (wx.Base.Event_Handler.Event_Handler_Type)
> derives from wxObject. wxWindow derives from wxEvtHandler. wxControl
> derives from wxWindow. etc.

Does wxEvtHandler encapsulate a thread?

> So, how do you make this thread safe? All controls are windows and all
> events go through the event handler classes. In the wxWidgets library
> there is minimal thread safe code in the event handling code, but do I
> want to make a completely thread safe library or leave it up to the
> application developer?

I will be difficult if possible in thin bindings if the library design
wasn't thread safe.

>>>> And more than two mutexes is a problem. You should try to make the API
>>>> composable without or minimal deadlock danger. For example, Windows GUI API
>>>
>>> I'm not sure what you mean about "composable without or minimal
>>> deadlock danger"
>>
>> From the messages loop [in a deeply nested callback subprogram] you spin
>> for a mutex held by another thread that does SetWindowText to the window.
>> Here you are.
> 
> Eh?

The messages loop waits for the mutex. The thread holding the mutex waits
for SendMessage to return the result. Deadlock.

Things like this happen. [ The design problem is that rendering actions
(like SetWindowText) and semantic actions (potentially lengthy and
serialized) are served by the same thread. ]

-- 
Regards,
Dmitry A. Kazakov
http://www.dmitry-kazakov.de



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-26 18:23     ` Martin Dowie
@ 2005-11-29  3:07       ` Randy Brukardt
  2005-11-29  9:13         ` Martin Dowie
  0 siblings, 1 reply; 19+ messages in thread
From: Randy Brukardt @ 2005-11-29  3:07 UTC (permalink / raw)



"Martin Dowie" <martin.dowie@btopenworld.com> wrote in message
news:dma971$fvc$1@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
> You won't need a preprocessor (although GNAT does have one 'gnatprep') -
> same spec, different bodies.
>
> -- Spec
> procedure Foo;
>
> -- Body
> procedure Foo is null;

While it's not germane to Martin's point, this code is illegal in Ada 200Y:
a null procedure cannot be a completion. Why not? Null procedures are
similar to abstract subprograms in use and description, and those clearly
can't be a completion. And it didn't seem worth a new bunch of rules to
avoid typing 12 characters - the least important savings that one could
imagine.

                     Randy Brukardt.





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-29  3:07       ` Randy Brukardt
@ 2005-11-29  9:13         ` Martin Dowie
  2005-11-29 21:46           ` Randy Brukardt
  0 siblings, 1 reply; 19+ messages in thread
From: Martin Dowie @ 2005-11-29  9:13 UTC (permalink / raw)


Randy Brukardt wrote:
> "Martin Dowie" <martin.dowie@btopenworld.com> wrote in message
> news:dma971$fvc$1@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
>> You won't need a preprocessor (although GNAT does have one
>> 'gnatprep') - same spec, different bodies.
>>
>> -- Spec
>> procedure Foo;
>>
>> -- Body
>> procedure Foo is null;
>
> While it's not germane to Martin's point, this code is illegal in Ada
> 200Y: a null procedure cannot be a completion. Why not? Null
> procedures are similar to abstract subprograms in use and
> description, and those clearly can't be a completion. And it didn't
> seem worth a new bunch of rules to avoid typing 12 characters - the
> least important savings that one could imagine.

So we're stuck with "procedure Foo is begin null; end;" and a "pragma
Inline"?

To me a null completion would be _very_ useful where you have different
package bodies for different targets but want to share a common package
spec.

Cheers

-- Martin





^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-28 10:37   ` Lucretia
@ 2005-11-29 21:38     ` Simon Wright
  0 siblings, 0 replies; 19+ messages in thread
From: Simon Wright @ 2005-11-29 21:38 UTC (permalink / raw)


"Lucretia" <lucretia9@lycos.co.uk> writes:

>> What would be acceptable? Using a Lock from the Booch �components
>> (http://booch95.sourceforge.net) takes just under 20 us on a 1.5GHz
>> Powerbook.
>
> I really doubt that the Booch components are written any differently
> to mine. So, why would I need to?

You thought that there might be a performance problem using locks. It
seemed to me that you might be just being apprehensive without having
any real evidence, and I produced a data point that showed that a
particular implementation has a particular performance and asked
whether that would be acceptable or not given your scenario.

Of course your locks will be programmed in standard Ada, so their
performance will likely be similar to the BCs. Whether you choose to
use the BCs or not is entirely a matter for you. Whether you can
afford to use locks at all depends on your chosen implementation's
performance * the invocation rate. Might need to be quite clever about
where the locks are applied .. 20 us isn't that fast, after all.



^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-29  9:13         ` Martin Dowie
@ 2005-11-29 21:46           ` Randy Brukardt
  2005-11-29 22:46             ` Martin Dowie
  0 siblings, 1 reply; 19+ messages in thread
From: Randy Brukardt @ 2005-11-29 21:46 UTC (permalink / raw)


"Martin Dowie" <martin.dowie@baesystems.com> wrote in message
news:438c19c5_1@glkas0286.greenlnk.net...
> Randy Brukardt wrote:
> > "Martin Dowie" <martin.dowie@btopenworld.com> wrote in message
> > news:dma971$fvc$1@nwrdmz01.dmz.ncs.ea.ibs-infra.bt.com...
> >> You won't need a preprocessor (although GNAT does have one
> >> 'gnatprep') - same spec, different bodies.
> >>
> >> -- Spec
> >> procedure Foo;
> >>
> >> -- Body
> >> procedure Foo is null;
> >
> > While it's not germane to Martin's point, this code is illegal in Ada
> > 200Y: a null procedure cannot be a completion. Why not? Null
> > procedures are similar to abstract subprograms in use and
> > description, and those clearly can't be a completion. And it didn't
> > seem worth a new bunch of rules to avoid typing 12 characters - the
> > least important savings that one could imagine.
>
> So we're stuck with "procedure Foo is begin null; end;" and a "pragma
> Inline"?

I don't get it. The body of "is null" would have the same meaning as "is
begin null; end;", so an Inline pragma would be necessary anyway. The only
difference would be 11 less characters to type.

If you wanted to get rid of the Inline pragma, you'd have to put "is null"
into the specification (which of course is the entire point of the "is null"
feature anyway).

> To me a null completion would be _very_ useful where you have different
> package bodies for different targets but want to share a common package
> spec.

Yes, but that's already possible with "begin null; end;". You seem to be
imagining semantics that wouldn't exist. It would be very unusual for an "is
null" completion to imply some sort of body dependence. Even renames-as-body
are potentially implemented as automatically generated subprogram bodies
(meaning that you need a pragma Inline to prevent that). Ada is very
consistent about requiring only the specification of a subprogram in order
to determine how it can be called (and code generated for it).

                     Randy.






^ permalink raw reply	[flat|nested] 19+ messages in thread

* Re: Tasking and wxWidgets
  2005-11-29 21:46           ` Randy Brukardt
@ 2005-11-29 22:46             ` Martin Dowie
  0 siblings, 0 replies; 19+ messages in thread
From: Martin Dowie @ 2005-11-29 22:46 UTC (permalink / raw)


Randy Brukardt wrote:
> Yes, but that's already possible with "begin null; end;". You seem to be
> imagining semantics that wouldn't exist.

Yes, I think I am!

And by coincidence I've just watched a programme on the "Da Vince Code" 
where the same is 'see what you want to see' rationale is given to 
explain the hokum in that book ;-)

Cheers

-- Martin



^ permalink raw reply	[flat|nested] 19+ messages in thread

end of thread, other threads:[~2005-11-29 22:46 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-25 10:05 Tasking and wxWidgets Lucretia
2005-11-25 10:53 ` Martin Dowie
2005-11-26 17:32   ` Lucretia
2005-11-26 18:23     ` Martin Dowie
2005-11-29  3:07       ` Randy Brukardt
2005-11-29  9:13         ` Martin Dowie
2005-11-29 21:46           ` Randy Brukardt
2005-11-29 22:46             ` Martin Dowie
2005-11-25 11:37 ` Dmitry A. Kazakov
2005-11-26 17:26   ` Lucretia
2005-11-27 11:15     ` Dmitry A. Kazakov
2005-11-28 10:48       ` Lucretia
2005-11-28 14:41         ` Dmitry A. Kazakov
2005-11-26 17:26   ` Lucretia
2005-11-26 17:28   ` Lucretia
2005-11-26 17:34   ` Lucretia
2005-11-26  7:46 ` Simon Wright
2005-11-28 10:37   ` Lucretia
2005-11-29 21:38     ` Simon Wright

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox