comp.lang.ada
 help / color / mirror / Atom feed
* Re: Glueing ADA to C++: Process sharing
  2001-05-09 19:19 Glueing ADA to C++: Process sharing Tilman Gloetzner
@ 2001-05-09 17:39 ` Ted Dennison
  2001-05-10 10:18   ` Tilman Gloetzner
  2001-05-09 23:33 ` Jeff Creem
  1 sibling, 1 reply; 6+ messages in thread
From: Ted Dennison @ 2001-05-09 17:39 UTC (permalink / raw)


In article <3AF9985D.63B5E511@uundz.de>, Tilman Gloetzner says...
>The main loop is in the KDE application, while the ADA package contains
>an independent
>task which is to be rendezvoued by the KDE application. That all works.
>
>should be running continously. Instead, the ADA task blocks, and only
>continues when 
>the window of the application is moved or an entry point of the Ada task
>is rendezvoued.
>
>I am not sure if this is related to ADA (I am using gnat) or to KDE, 

It might help if you could tell us what platform you are doing this on, and (if
you know) what threading system your Ada compiler (Gnat) is using.

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



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

* Glueing ADA to C++: Process sharing
@ 2001-05-09 19:19 Tilman Gloetzner
  2001-05-09 17:39 ` Ted Dennison
  2001-05-09 23:33 ` Jeff Creem
  0 siblings, 2 replies; 6+ messages in thread
From: Tilman Gloetzner @ 2001-05-09 19:19 UTC (permalink / raw)


Hello,

In the test program below, I am glueing an ADA package to a KDE
application.
The main loop is in the KDE application, while the ADA package contains
an independent
task which is to be rendezvoued by the KDE application. That all works.

Process switching somehow represents a problem: Once the ADA task is
started, it 
should be running continously. Instead, the ADA task blocks, and only
continues when 
the window of the application is moved or an entry point of the Ada task
is rendezvoued.

I am not sure if this is related to ADA (I am using gnat) or to KDE, 
so I posted it to both newsgroups.


Help is very much appriciated (I really have no idea on how to tackle
this).


Thanks,

Tilman



=================== Makefile ==================================
CXXFLAGS = -Wall
INCLUDES= -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/local/include
-I.
QT_INCLUDES = -I/usr/lib/qt/include
 
LDFLAGS = -L/opt/kde/lib -L/usr/X11/lib -L/usr/local/lib
LIB_X11 = -lX11 $(LIBSOCKET)
LIB_QT = -lqt $(LIB_X11)
LIB_KDECORE = -lkdecore -lXext $(LIB_QT)
LIB_KDEUI = -lkdeui $(LIB_KDECORE)
LIB_KFM = -lkfm $(LIB_KDEUI)
LIB_KFILE = -lkfile $(LIB_KFM)
 
 
ada_2_c.ali: ada_2_c.adb ada_2_c.ads
        gnatmake -c ada_2_c.adb -o ada_2_c.o
        gnatbind -n ada_2_c
 
 
c_main.moc: c_main.h
        moc $< > $@
 
c_main.o: c_main.c c_main.h c_main.moc
        $(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@
 
atask_n_kde: c_main.o ada_2_c.ali
        gnatlink -v ada_2_c.ali c_main.o $ $(LIB_KFILE) $(LDFLAGS) -o $@
 
clean:
        rm -f *.o *~ *.ali *.moc atask_n_kde

================== c_main.h ===================================
#ifndef __KTESTAPP_H
#define __KTESTAPP_H
#include <kapp.h>
#include <ktmainwindow.h>
#include <qwidget.h>
#include <qpushbutton.h>
#include <qevent.h>
 
#define VERSION 0.1
 
 
 
class KTestWindow:public KTMainWindow {
  Q_OBJECT
 
public:
  KTestWindow();
  ~KTestWindow();
 
 protected:
  void paintEvent(QPaintEvent *);
 
 protected slots:
  void Start(void);
  void Stop(void);
  void Register(void);
/*   void openWidget(); */
 
 private:
 int paintEventCounter;
 
};
#endif                

================== c_main.c ===================================
#include<stdio.h>
#include <kmenubar.h>
#include <qkeycode.h>
#include <qpainter.h>
#include "c_main.moc"
#include "c_main.h"
#include <iostream.h>
 
#define SUCCESS 0
 
extern "C" {
  void adainit (void);
  void adafinal (void);
  void Ada_TaskStart(void);
  void Ada_TaskStop(void);
  void Ada_TaskQuit(void);
  void Ada_TaskRegister(int a,int b);
}
 
 
 
 
KTestWindow::KTestWindow() : KTMainWindow () {
 
  this->setFixedSize(400,50);
  KMenuBar* mb =  menuBar ();
  mb->insertItem(i18n("&Quit"),kapp, SLOT(quit()),CTRL+Key_Q);
  mb->insertItem(i18n("&TaskStart"),this, SLOT(Start()),CTRL+Key_S);
  mb->insertItem(i18n("TaskSt&op"),this, SLOT(Stop()),CTRL+Key_O);
  mb->insertItem(i18n("Task&Multiply"),this,
SLOT(Register()),CTRL+Key_M);
  paintEventCounter = 0;
}
 
 
KTestWindow::~KTestWindow() {
  Ada_TaskQuit();
}
 
void KTestWindow::Start() {
  Ada_TaskStart();
}
 
void KTestWindow::Stop() {
  Ada_TaskStop();
}
 
void KTestWindow::Register() {
  Ada_TaskRegister(paintEventCounter,2);
}
 
void KTestWindow::paintEvent(QPaintEvent *) {
  char buf[20];
  QPainter
qp;                                                                    
 
  cout<<"KTestWindow::paintEvent"<<endl;
  paintEventCounter++;
  if (qp.begin(this)) {
    sprintf(buf,"#paintEvents = %d",paintEventCounter);
    qp.eraseRect(0,35,200,15);
    qp.drawText(0,35,200,15,AlignBottom |  AlignLeft,buf);
    qp.end();
  }
}
 
int main(int argc,char **argv) {
  KApplication* a;
  KTestWindow *t;
 
  printf("Start main\n");
  adainit();
  a = new \x03KApplication(argc, argv, "ktest");
  a->enableSessionManagement();
  t = new KTestWindow();
  a->setTopWidget(t);
  t->show();
 
  return a->exec();
  adafinal();
  printf("End main\n");
  return(SUCCESS);
}                                 

======================== ada_2_c.ads (package definition)
===========================
with INTERFACES.C;use INTERFACES.C;
with INTERFACES.C.STRINGS; use INTERFACES.C.STRINGS;
use INTERFACES;
 
 
 
package Ada_2_C is
 
   procedure TaskStart;
   procedure TaskStop;
   procedure TaskQuit;
   procedure TaskRegister(A:Int;B:Int);
 
   pragma Export(CPP,TaskStart,"Ada_TaskStart");
   pragma Export(CPP,TaskStop,"Ada_TaskStop");
   pragma Export(CPP,TaskQuit,"Ada_TaskQuit");
   pragma Export(CPP,TaskRegister,"Ada_TaskRegister");
 
   task type MULTIPLY_TASK_T is
      entry Register(A:Integer;B:Integer);
      entry Start;
      entry Stop;
      entry Quit;
   end MULTIPLY_TASK_T;
 
   type MULTIPLY_TASK_REF is access MULTIPLY_TASK_T;
end Ada_2_C;                   

==================== ada_2_C.adb(package body)
============================
with TEXT_IO;use TEXT_IO;
package body Ada_2_C is
   Multiply: Multiply_Task_Ref;
   package Int_IO is new INTEGER_IO(INTEGER);
 
   procedure TaskStart is
   begin
      Multiply := new Multiply_Task_T;
      Multiply.Start;
   end TaskStart;
 
   procedure TaskStop is
   begin
      Multiply.Stop;
   end TaskStop;
 
   procedure TaskQuit is
   begin
      Multiply.Quit;
   end TaskQuit;
 
   procedure TaskRegister(A:Int;B:Int) is
   begin
      Multiply.Register(Integer(A),Integer(B));
   end TaskRegister;
 
 
   task body MULTIPLY_TASK_T is
      C,D : Integer := 0;
      Counter: Integer := 0;
      Run_Flag: Boolean := False;
      Quit_Flag: Boolean := False;
   begin
      while (Quit_Flag = False) loop
         select
            accept Register(A:Integer;B:Integer) do
               if (Run_Flag = True) then
                  C := A;
                  D := B;
               end if;
            end Register;
         or
            accept Start do
               Put_Line("Multiply_Task.Start");
               Counter := 0;
               Run_Flag := True;
            end Start;
         or
            accept Stop do
               Put_Line("Multiply_Task.Stop");
               Run_Flag := False;
            end Stop;
         or  
            accept Quit do
               Put_Line("Multiply_Task.Quit");
               Run_Flag := False;
               Quit_Flag := True;
            end Quit;
         or
            delay(0.0);
            if (Run_Flag = True) then
               Put("Multiply_Task(");
               Int_IO.Put(Counter);
               Put("): ");
               Int_IO.Put(C);
               Put(" * ");
               Int_IO.Put(D);
               Put(" = ");
               Int_IO.Put(C*D);
               New_Line;
               Counter := Counter + 1;
            end if;
         end select;
      end loop;
   end MULTIPLY_TASK_T;
 
 
end Ada_2_C;



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

* Re: Glueing ADA to C++: Process sharing
  2001-05-09 19:19 Glueing ADA to C++: Process sharing Tilman Gloetzner
  2001-05-09 17:39 ` Ted Dennison
@ 2001-05-09 23:33 ` Jeff Creem
  2001-05-10 10:44   ` Tilman Gloetzner
  1 sibling, 1 reply; 6+ messages in thread
From: Jeff Creem @ 2001-05-09 23:33 UTC (permalink / raw)


It is just a guess but if you are using the default Linux thread model of
GNAT (meaning
that you are not using Linux threads but fsu threads).

Check the docs and readme file to figure out how to change the threading
model
to use Linux threads for Ada tasks.


Also you realize that your Ada task as written is a processor hog (I assume
this is
just an example).


Also there is probably no reason that the task spec should be in the package
spec in this case. (Not the problem here just a style issue)


"Tilman Gloetzner" <Tilman.Gloetzner@uundz.de> wrote in message
news:3AF9985D.63B5E511@uundz.de...
> Hello,
>
> In the test program below, I am glueing an ADA package to a KDE
> application.
> The main loop is in the KDE application, while the ADA package contains
> an independent
> task which is to be rendezvoued by the KDE application. That all works.
>
> Process switching somehow represents a problem: Once the ADA task is
> started, it
> should be running continously. Instead, the ADA task blocks, and only
> continues when
> the window of the application is moved or an entry point of the Ada task
> is rendezvoued.
>
> I am not sure if this is related to ADA (I am using gnat) or to KDE,
> so I posted it to both newsgroups.
>
>
> Help is very much appriciated (I really have no idea on how to tackle
> this).
>
>
> Thanks,
>
> Tilman
>
>
>
> =================== Makefile ==================================
> CXXFLAGS = -Wall
> INCLUDES= -I/opt/kde/include -I/usr/lib/qt/include  -I/usr/local/include
> -I.
> QT_INCLUDES = -I/usr/lib/qt/include
>
> LDFLAGS = -L/opt/kde/lib -L/usr/X11/lib -L/usr/local/lib
> LIB_X11 = -lX11 $(LIBSOCKET)
> LIB_QT = -lqt $(LIB_X11)
> LIB_KDECORE = -lkdecore -lXext $(LIB_QT)
> LIB_KDEUI = -lkdeui $(LIB_KDECORE)
> LIB_KFM = -lkfm $(LIB_KDEUI)
> LIB_KFILE = -lkfile $(LIB_KFM)
>
>
> ada_2_c.ali: ada_2_c.adb ada_2_c.ads
>         gnatmake -c ada_2_c.adb -o ada_2_c.o
>         gnatbind -n ada_2_c
>
>
> c_main.moc: c_main.h
>         moc $< > $@
>
> c_main.o: c_main.c c_main.h c_main.moc
>         $(CXX) -c $(CXXFLAGS) $(INCLUDES) $< -o $@
>
> atask_n_kde: c_main.o ada_2_c.ali
>         gnatlink -v ada_2_c.ali c_main.o $ $(LIB_KFILE) $(LDFLAGS) -o $@
>
> clean:
>         rm -f *.o *~ *.ali *.moc atask_n_kde
>
> ================== c_main.h ===================================
> #ifndef __KTESTAPP_H
> #define __KTESTAPP_H
> #include <kapp.h>
> #include <ktmainwindow.h>
> #include <qwidget.h>
> #include <qpushbutton.h>
> #include <qevent.h>
>
> #define VERSION 0.1
>
>
>
> class KTestWindow:public KTMainWindow {
>   Q_OBJECT
>
> public:
>   KTestWindow();
>   ~KTestWindow();
>
>  protected:
>   void paintEvent(QPaintEvent *);
>
>  protected slots:
>   void Start(void);
>   void Stop(void);
>   void Register(void);
> /*   void openWidget(); */
>
>  private:
>  int paintEventCounter;
>
> };
> #endif
>
> ================== c_main.c ===================================
> #include<stdio.h>
> #include <kmenubar.h>
> #include <qkeycode.h>
> #include <qpainter.h>
> #include "c_main.moc"
> #include "c_main.h"
> #include <iostream.h>
>
> #define SUCCESS 0
>
> extern "C" {
>   void adainit (void);
>   void adafinal (void);
>   void Ada_TaskStart(void);
>   void Ada_TaskStop(void);
>   void Ada_TaskQuit(void);
>   void Ada_TaskRegister(int a,int b);
> }
>
>
>
>
> KTestWindow::KTestWindow() : KTMainWindow () {
>
>   this->setFixedSize(400,50);
>   KMenuBar* mb =  menuBar ();
>   mb->insertItem(i18n("&Quit"),kapp, SLOT(quit()),CTRL+Key_Q);
>   mb->insertItem(i18n("&TaskStart"),this, SLOT(Start()),CTRL+Key_S);
>   mb->insertItem(i18n("TaskSt&op"),this, SLOT(Stop()),CTRL+Key_O);
>   mb->insertItem(i18n("Task&Multiply"),this,
> SLOT(Register()),CTRL+Key_M);
>   paintEventCounter = 0;
> }
>
>
> KTestWindow::~KTestWindow() {
>   Ada_TaskQuit();
> }
>
> void KTestWindow::Start() {
>   Ada_TaskStart();
> }
>
> void KTestWindow::Stop() {
>   Ada_TaskStop();
> }
>
> void KTestWindow::Register() {
>   Ada_TaskRegister(paintEventCounter,2);
> }
>
> void KTestWindow::paintEvent(QPaintEvent *) {
>   char buf[20];
>   QPainter
> qp;
>
>   cout<<"KTestWindow::paintEvent"<<endl;
>   paintEventCounter++;
>   if (qp.begin(this)) {
>     sprintf(buf,"#paintEvents = %d",paintEventCounter);
>     qp.eraseRect(0,35,200,15);
>     qp.drawText(0,35,200,15,AlignBottom |  AlignLeft,buf);
>     qp.end();
>   }
> }
>
> int main(int argc,char **argv) {
>   KApplication* a;
>   KTestWindow *t;
>
>   printf("Start main\n");
>   adainit();
>   a = new \x03KApplication(argc, argv, "ktest");
>   a->enableSessionManagement();
>   t = new KTestWindow();
>   a->setTopWidget(t);
>   t->show();
>
>   return a->exec();
>   adafinal();
>   printf("End main\n");
>   return(SUCCESS);
> }
>
> ======================== ada_2_c.ads (package definition)
> ===========================
> with INTERFACES.C;use INTERFACES.C;
> with INTERFACES.C.STRINGS; use INTERFACES.C.STRINGS;
> use INTERFACES;
>
>
>
> package Ada_2_C is
>
>    procedure TaskStart;
>    procedure TaskStop;
>    procedure TaskQuit;
>    procedure TaskRegister(A:Int;B:Int);
>
>    pragma Export(CPP,TaskStart,"Ada_TaskStart");
>    pragma Export(CPP,TaskStop,"Ada_TaskStop");
>    pragma Export(CPP,TaskQuit,"Ada_TaskQuit");
>    pragma Export(CPP,TaskRegister,"Ada_TaskRegister");
>
>    task type MULTIPLY_TASK_T is
>       entry Register(A:Integer;B:Integer);
>       entry Start;
>       entry Stop;
>       entry Quit;
>    end MULTIPLY_TASK_T;
>
>    type MULTIPLY_TASK_REF is access MULTIPLY_TASK_T;
> end Ada_2_C;
>
> ==================== ada_2_C.adb(package body)
> ============================
> with TEXT_IO;use TEXT_IO;
> package body Ada_2_C is
>    Multiply: Multiply_Task_Ref;
>    package Int_IO is new INTEGER_IO(INTEGER);
>
>    procedure TaskStart is
>    begin
>       Multiply := new Multiply_Task_T;
>       Multiply.Start;
>    end TaskStart;
>
>    procedure TaskStop is
>    begin
>       Multiply.Stop;
>    end TaskStop;
>
>    procedure TaskQuit is
>    begin
>       Multiply.Quit;
>    end TaskQuit;
>
>    procedure TaskRegister(A:Int;B:Int) is
>    begin
>       Multiply.Register(Integer(A),Integer(B));
>    end TaskRegister;
>
>
>    task body MULTIPLY_TASK_T is
>       C,D : Integer := 0;
>       Counter: Integer := 0;
>       Run_Flag: Boolean := False;
>       Quit_Flag: Boolean := False;
>    begin
>       while (Quit_Flag = False) loop
>          select
>             accept Register(A:Integer;B:Integer) do
>                if (Run_Flag = True) then
>                   C := A;
>                   D := B;
>                end if;
>             end Register;
>          or
>             accept Start do
>                Put_Line("Multiply_Task.Start");
>                Counter := 0;
>                Run_Flag := True;
>             end Start;
>          or
>             accept Stop do
>                Put_Line("Multiply_Task.Stop");
>                Run_Flag := False;
>             end Stop;
>          or
>             accept Quit do
>                Put_Line("Multiply_Task.Quit");
>                Run_Flag := False;
>                Quit_Flag := True;
>             end Quit;
>          or
>             delay(0.0);
>             if (Run_Flag = True) then
>                Put("Multiply_Task(");
>                Int_IO.Put(Counter);
>                Put("): ");
>                Int_IO.Put(C);
>                Put(" * ");
>                Int_IO.Put(D);
>                Put(" = ");
>                Int_IO.Put(C*D);
>                New_Line;
>                Counter := Counter + 1;
>             end if;
>          end select;
>       end loop;
>    end MULTIPLY_TASK_T;
>
>
> end Ada_2_C;





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

* Re: Glueing ADA to C++: Process sharing
  2001-05-09 17:39 ` Ted Dennison
@ 2001-05-10 10:18   ` Tilman Gloetzner
  2001-05-10 13:26     ` Ted Dennison
  0 siblings, 1 reply; 6+ messages in thread
From: Tilman Gloetzner @ 2001-05-10 10:18 UTC (permalink / raw)


I am using linux 2.4 (I tested it also on version 2.2 -- no difference)
gnatlink links -lgthreads which probably is what Jeff means by "fsu
threads".
> 
> It might help if you could tell us what platform you are doing this on, and (if
> you know) what threading system your Ada compiler (Gnat) is using.



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

* Re: Glueing ADA to C++: Process sharing
  2001-05-09 23:33 ` Jeff Creem
@ 2001-05-10 10:44   ` Tilman Gloetzner
  0 siblings, 0 replies; 6+ messages in thread
From: Tilman Gloetzner @ 2001-05-10 10:44 UTC (permalink / raw)


> Also you realize that your Ada task as written is a processor hog (I assume
> this is just an example).
Yes, it just isolates the threading problem. 


What exactly do you mean by "processor hog" ? 
a) The task loops with out blocking and drives up the load (if works as
I hoped it would ) ?
b) Each time Start is pressed a new task is started without the old task
to termiante ?



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

* Re: Glueing ADA to C++: Process sharing
  2001-05-10 10:18   ` Tilman Gloetzner
@ 2001-05-10 13:26     ` Ted Dennison
  0 siblings, 0 replies; 6+ messages in thread
From: Ted Dennison @ 2001-05-10 13:26 UTC (permalink / raw)


In article <3AFA6AEC.6037CD07@uundz.de>, Tilman Gloetzner says...
>
>I am using linux 2.4 (I tested it also on version 2.2 -- no difference)
>gnatlink links -lgthreads which probably is what Jeff means by "fsu
>threads".
>> 
>> It might help if you could tell us what platform you are doing this on, and (if
>> you know) what threading system your Ada compiler (Gnat) is using.

There's your answer then. "FSU threads" is a system where the Ada tasks all run
inside the context of one OS thread. When that thread gives control over to the
GUI, it won't get it back until the GUI gives it back. To get the behavior you
seem to want, you are probably going to have to use Linux threads instead. That
won't give you fully LRM-conformant tasking behavior, but unless you've got a
contractual problem with that, it shouldn't be a big deal.

Another way of dealing with this problem is to put all the Ada stuff you need to
do in the meantime into a procedure that gets called by a GUI timeout event.
That's the old-fashioned C way of doing things (GUI's are typically built to
work with C).

---
T.E.D.    homepage   - http://www.telepath.com/dennison/Ted/TED.html
          home email - mailto:dennison@telepath.com



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

end of thread, other threads:[~2001-05-10 13:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-05-09 19:19 Glueing ADA to C++: Process sharing Tilman Gloetzner
2001-05-09 17:39 ` Ted Dennison
2001-05-10 10:18   ` Tilman Gloetzner
2001-05-10 13:26     ` Ted Dennison
2001-05-09 23:33 ` Jeff Creem
2001-05-10 10:44   ` Tilman Gloetzner

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