* Was machen wir mit Properties, die den Datentyp `Structure' 
  haben, z.B. MagnInfo?

-> Ok! Ist implementiert.
 

* Gibt's eigentlich nur asynchrones *Lesen* oder z.B. auch
  ein asynchrones *Call*? Ich denke ja! Wir schalten doch jetzt
  schon Magnete entlang einer Beamline asynchron ein, weil das 
  synchrone Einschalten zu lange dauern würde. 

  Die gleiche Frage steht für "konnektierte Aufträge". Ist
  es nicht vorstellbar, dass man vom Operating aus sagen kann,
  dass dem DC-Magneten XX1MU2 alle 200ms der (DPR-) Sollwert 
  geschickt werden soll?

-> Ok! Geht für alle nicht synchronen Aufträge.
 

* Wählen wir für Callbacks die Implementierung mit "oneway", 
  dann [1] beachten! Bei Callbacks ebenso "TRANSIENT" beachten, 
  siehe [2].

-> Ok, aber TRANSIENT fehlt noch.
  

* UsrArray::addUsr() wirft eine Exception, wenn das Array
  bereits voll ist, und wird *im Konstruktor* von MxUsrs
  benutzt. Wie geht das? Wo endet die Exception, also wer
  fängt sie?

-> Ok, wg. Benutzung von " vector".


* UsrArray::getUsrs(...) sucht eine passende Usr mit einer
  ziemlich schlechten Suchmethode, indem nämlich einfach 
  das Array von Anfang an durchgeklappert wird. Kann man
  da was besseres, schnelleres erfinden? Möglicherweise mit
  "map" implementieren.

-> Ok! Mit "map" aus der STL implementiert.


* Die Kennung konnektierter Aufträge mit IDs ist nicht
  mehr uptodate. Die Methode connect() sollte eine Referenz
  auf die "Konnektierung" (was immer das genau ist) zurück 
  liefern, die von der Methode disconnect() benutzt werden
  kann.

-> Ok, ID und Objektreferenz mit "set" (STL) implementiert.


* Geräte müssen die virtuellen (s.o.) Methoden setOnline() 
  und setOffline() zur Verfügung stellen. setOnline() muss
  die Attribute MxDevice::_devDataP und VmeDevice::_ecNum   
  versorgen.

  Wer weiß genau, wo die Daten des Gerätes im DPR anfangen?
  Was kann MOPS als Parameter an setOnline() übergeben? 

  Die Methoden mit mutex abichern.

-> Ok!


* Wie setze ich das Attribut _devConst der Klasse MxDevice? 
  Die Gerätekonstanten _devConst müssen (neu) gefüllt werden, 
  wenn neue Konstanten von oben (Operating-Ebene) geschickt
  werden. 

  Wenn _devConst neu gefüllt wird, müssen auch die Konstanten
  im DPR neu geschrieben werden!

  Geräte müssen eine virtuelle Methode setDevConst()
  zur Verfügung stellen zum Setzen/Updaten der Geräte-
  konstanten. "Virtuell", weil MOPS VmeDevice::setDevConst()
  aufruft (er soll nix von MxDevice wissen), aber aktuell
  natürlich MxDevice::setDevConst() aufgerufen werden muss.
  Welcher allgemeine Datentyp wird benutzt, um die Konstanten
  auszutauschen? Etwa ein Array of Structures ähnlich dem in
  narrowifc.idl deklarierten?

     union DevConstElement switch (DataType) {
        ...
   case DATA_SLONG: long sl;
   ...
      }

      typedef vector<DevConstElement> DevConstArray;

      virtual void VmeDevice::setdevConst(DevConstArray& dca);
      virtual void  MxDevice::setdevConst(DevConstArray& dca);

  Kann/soll man direkt den IDL-Typ `StructArray' benutzen?

-> Ok!


* Kann der MOPS Geräte (z.B. PlaDevice) instanziieren, *ohne*
  dass er konkret was von dem Device weiß, also ohne dass er
  pla-device.hh includieren muss? 

  Vielleicht geht's so: Jedes Gerätemodell steckt in einer eigenen
  Shared Library. Jedes Gerätemodell hat eine Methode, die etwa
  `instantiate()' heißen könnte. Diese instanziiert ein Gerät 
  (new PlaDevice) und liefert dem MOPS eine Referenz (oder einen 
  Pointer) auf das Objekt zurück. Die Referenz kann vom Typ 
  `VmeDevice' oder `AccDevice' oder einfach `CORBA::Object[_var]' 
  sein. (Dabei ist `CORBA::Object_var' wohl besser als
  `CORBA::Object', weil der `Smart'-Pointer Eigentümer des 
  Objekts wird und es damit auch zur passenden Zeit wieder 
  löschen kann.)

-> Ok!


* Nach einem disconnect() kommt in der Regel trotzdem noch *eine*
  konnektierte Antwort. Das liegt an der Implementierung in
  vmedevice.cc. Will man diese letzte Antwort vermeiden, muss 
  nach dem Warten nochmal explizit geguckt werden, ob die USR
  mittlerweile disconnected wurde.

-> Ok! In ConnectThread::run() implementiert.


* Absturz (Segmentation fault) des Servers, wenn das konnektierte
  FIELDA einen Parameter bekommt, der eigentlich für CALC gedacht 
  war. Mit cl2.cc reproduzierbar. Woran liegt's? Stürzt der
  Server eigentlich auch bei einem (a-)synchronen Auftrag ab? Weder
  noch, Absturz also *nur* nach einem konnektierten Auftrag!

-> Ok! War das Dereferenzieren eines NULL-Pointers in der FieldA-USR, 
   weil ich einen primStat nicht getestet hatte. Warum das aber nur
   bei einem konnektierten Auftrag passiert ist, fragt mich bitte 
   keiner!


* Für asynchrone und konnektierte Aufträge müssen die von einer
  USR geworfenen Ausnahmen gefangen und als AccDevRetStatus an
  den Client (-Callback) zurück geliefert werden.

-> Ok!

  Ist kein Callback angegeben (ohne quit), muss die Ausnahme
  auf der Server-Seite ausgegeben werden (cerr).

-> Ok! Zumindest als Kommentar in vmedevice.cc implementiert. 


* Was machen wir mit den Standard-USRs? In Gerätemodell-USRs
  includiren? Dazu linken? Vererben? Oder was?

-> Vorläufig ok! Default- und Therapie-USRs werden weiterhin
   einfach includiert. Für andere Implementierungen (z.B. erben)
   muss man noch gut nachdenken, weil die includierten USRs
   gerätemodell-spezifische Informationen benötigen, die sie
   jetzt einfach haben, weil diese vor dem Include definiert
   werden. In etwa so, z.B. in mx-usrs.cc:

     #define MEDIMODE_TIMEOUT 15

     #include "therapy-usrs.cc"


* Namespaces auch für VmeDevice und AccDevice erfinden? Ja!

-> Ok, im Namespace DeviceAccess


* Wie machen wir die Incode Documentation? Mit Doxygen?
  Wieder einen (oder mehrere) Rahmen für Klassen, USRs, 
  etc. entwickeln?

-> Ok, mit Doxygen. Einen Rahmen gibt's (noch) nicht.


* Allgemeines, CORBA-unabhängiges AccData implementieren. Nur damit
  gibt es auch die Konvertierung beim Lesen von AccData (also wenn 
  Daten an ein Gerät geschickt werden)! Zur Zeit ist *keine* 
  Datenkonvertierung eingebaut.

-> Ok!


* Überall den Server bzw. den nMOPS von Klaus benutzen. Dieser
  kann u.a. die Datenbank (Geräte- und Konstanten-Tabelle) 
  via File einlesen. 

-> Ok!


* Wie behandeln wir die Geräte-Software-Shared-Objects, also z.B. "mx.so" oder
  "pla.so"? Diese werden ja zur Laufzeit "dazugelinkt". Liegen sie für jeden GuP
  allgemein zugänglich, dann hat jeder GuP automatisch die neueste GSW. Das ist
  schön, man mag's aber manchmal gerade so *nicht* haben, weil man auf einem
  GuP noch mit älterer Software fahren möchte! Was machen wir dann? Anders 
  linken? Oder benutzen wir gar keine Shared Objects? Oder was? Shared Objects
  getrennt für jeden GuP macht jedenfalls keinen Sinn.

-> Ok, auf dem Root-Directory des PPC gibt es z.B. einen Link "mx.so", der 
   z.B. auf "/usr/local/lib/mx.so.9.2" zeigt. Das ist ein Link, der z.B. auf
   "/usr/local/lib/mx.so.9.2.7" zeigt. Das ist die Shared Library für MX. 
   Änderungen von 9.2.7 auf 9.2.8 werden also "automatisch" von allen PPCs 
   berücksichtigt, Änderungen von 9.2 auf 9.3 müssen für jeden PPC einzeln
   "released" werden, indem der Link mx.so auf dem Root-Directory umgesetzt
   wird.


* Manchmal werden gewisse Deklarationen für ein Gerätemodell
  auf Server- *und* Clientseite gebraucht, z.B. MagnInfoType
  bei MX. Auf der Clientseite soll man deshalb aber *nicht* 
  mx-usrs.hh oder mx-device.hh includieren müssen, da das
  einen Rattenschwanz von weiteren Includes nach sich zieht.
  Erfinden wir sowas wie ein mx-global.hh? Oder muss man
  MagnInfoType auf der Clientseite einfach nochmal deklarieren?
  So wurde es wohl bisher gemacht.

  Auch sollte der (mehr oder weniger Standalone-) Server (MOPS)
  weitgehend von gerätespezifischen Includes (z.B. mx-dev-def.h)
  verschont bleiben. Das bedeutet,dass die Include-Files
  entflochten werden müssen!

  Im Moment habe ich für die MX-Properties MAGNINFO und CALC
  die Datei mx-structtypes.hh erfunden. Es ist wohl sinnig, für 
  strukturierte Datentypen auch auf der Server-Seite ein (dieses)
  Include zu haben.

  Die Grenzen dieser Lösung zeigt nun therapy-structtypes.hh auf.
  Jedes enum-Element muss einen *eindeutigen* Namen haben. So 
  kann man z.B. "iFocus" nicht in 2 Aufzählungen als Namen 
  nehmen. Und einen Typ wie z.B.

    typedef struct RCheckSetSndType {
      ULong OperMode;
      ULong MstCompl;
      ULong SlvCompl;
      ULong VfyCompl;
      ULong CntBadSets;
      DEFIType BadSets[CNTBADSETS_MAX];
    } RCheckSetSndType;

  (der nur aus ULong-Elementen besteht) in eine Aufzählung zu
  überführen, ist ziemlich unschön. Wollen wir also die 
  "typedef struct ..." auch alle beibehalten? Sehen wir da 
  Probleme mit Alignment usw.?

-> Ok!
   - gm-structtypes.hh wird implementiert und nach $incvme kopiert.
   - Eindeutige Benennung von Aufzählungselementen wird durch 
     property-ähnliche Zusätze erreicht (siehe md-structtypes.hh).
   - Arrays bekommen nur _einen_ Index auf den Array-Anfang.
   - Alignment-Probleme gibt es keine, da man auf AccData-Elemente
     nur einzeln zugreifen kann.


* UsrSet::addUsr(): Fehlerbehandlung beim Versuch, eine Property
  mehrfach anzumelden.

 -> Ok, es gibt eine Exception.


* Was machen wir generell mit Fehlern, die nicht an einen Client
  gemeldet werden können? Vorschlag wäre, sie in ein Logfile zu
  schreiben. Diese Möglichkeit hätten wir jetzt mit den neuen 
  PPC-GuPs (via NFS).

-> Ok, Logfile.


* Man muss beachten, *wohin* Geräte-Software eine Exception wirft. 
  - Wenn eine USR eine Exception wirft, dann wird sie in Richtung
    Anwendung (Operating-Programm) geworfen. Dort kann sie ausgewertet
    werden.
  - Geräte (Klassen VmeDevice, MxDevice) haben aber u.a. auch Methoden, 
    die *nicht* von einem Operating-Programm, sondern von DevMan
    aufgerufen werden, z.B. online() oder getDevConstants(). Eine darin 
    geworfenen Exception landet also in DevMan. Was macht der damit? 
    Wollen wir ein GuP-spezifisches Logfile erfinden, in das solche 
    Exceptions (und andere Probleme) geloggt werden? (Siehe dazu auch
    einen Punkt weiter oben.)
  Je nachdem, wer wirft und wohin geworfen wird, muss man gucken,
  ob man eine CORBA-abhängige AccDevExc wirft oder eine unabhängige
  AccDevException.
  - Wirft man Richtung DevMan, dann sollte (muss?) es eine 
    AccDevException sein, also die CORBA-unabhängige. 
  - USRs werfen auch AccDevExceptions, die von VmeDevice in eine 
    entsprechende AccDevExc konvertiert und mit Hilfe von CORBA
    weitergeworfen werden.
  - Im Sinne der Trennung von Anwendung und Transport sollte
    MxDevice eigentlich auch nur AccDevExceptions werfen. MxDevice 
    ist aber ein Kind von VmeDevice. Und ich weiß (im Moment noch)
    nicht, wie man da VmeDevice noch konvertieren lassen könnte, 
    wenn die Exception Richtung Anwendung fliegt. Im Moment haben 
    wir das Problem (noch) nicht, da die Exceptions aus MxDevice 
    alle Richtung DevMan geworfen werden.

-> Ok!
   - USRs und DevMan schreiben in ein GuP-spezifisches Logfile.
   - Nur CORBA-Module und (zum Teil) die Interfaces zwischen
     CORBA und den CORBA-unabhängigen Teilen werfen AccDevExc.
     Alle anderen Module werfen AccDevException.

-> Ok!
   - Beim Starten des DevMan kann es zu Fehlermeldungen wie z.B.

     Couldn't load so file ec.so (ec.so: cannot open shared 
     object file: No such file or directory)

     kommen. Die werden im Moment noch am Bildschirm ausgegeben, 
     müssen aber perspektivisch auf das Logfile umgelenkt werden.

-> Ok! Meldungen umgelenkt!

* Devman sollte verhindern, dass er mehr als einmal läuft. Das geht nämlich
  wegen der Resource VME nicht und macht zudem Probleme mit den Objekt-
  Referenzen, die dem Nameservice bekannt gegeben werden. 

  Ich habe nach einem Lock-Mechanismus Ausschau gehalten. So richtig was 
  Schönes gibt es anscheinend unter Linux nicht. Am praktikabelsten erscheint
  mir die Methode der Dateisperrung, wie sie in "Linux Programmierung" ab
  Seite 258 beschrieben ist. Das würde für den Devman etwa so aussehen:

    {
      if (kreiere(Lockdatei) != ok) {
        log error
        exit
      }
      ...
    }

    exithandler()      
    {
      lösche(Lockdatei)
      ...
    }

  Eine Lockdatei könnte etwa devman.lock heißen und müsste
  auf einem rechnerspezifischen Directory liegen. Wo könnte
  das sein? 

-> Ok! Sieht zwar im Detail ganz anders aus, aber funktioniert.
       Lockdatei heisst: /var/lock/acc/devman


* Callback bremst konnektierte Aufträge aus. So, wie die run-Methode des
  ConnectThreads im Moment implementiert ist, wird die Zeit, die die
  Callback-Methode der Anwendung braucht, zur sleep()-Zeit _addiert_! Das
  kommt daher, weil die Callback-Methoden _synchrone_ Methoden sind. Hat der
  Anwender eine periodische Konnektierung aufgesetzt, die z.B. alle 10s 
  antworten soll, und sein Callback braucht 5s, dann gibt es nur alle 15s
  eine Antwort, weil das "_client->readResponse(...)" in "ConnectThread::run(...)"
  erst nach 5s zurück kommt und dann noch 10s geschlafen wird. 

  So kann man das nicht lassen. Peter hat aber eine gute Idee, wie man das
  beheben kann. Und die Realisierung hat noch einen zusätzlichen angenehmen 
  Nebeneffekt. Der sleep()-Timer wird in einem eigenen Thread aufgesetzt, der 
  ConnectThread ruft den Callback auf und macht anschließend ein join() mit dem 
  sleep()-Thread. Solange der Callback weniger lange dauert als die sleep()-Zeit, 
  bekommt der Anwender seine Antworten in der gewünschten Frequenz. Braucht der 
  Callback länger als die sleep()-Zeit, dann bremst der Anwender den ConnectThread 
  aus. Er bekommt seltener eine Antwort, weil zum join()-Zeitpunkt der sleep()-
  Thread schon längst abgelaufen ist. Die Periode entspricht dann der Laufzeit
  des Callbacks. Und das ist der angenehme Nebeneffekt: Es macht keinen Sinn, mehr 
  bzw. öfter Antworten an den Anwender zu schicken als dieser verarbeiten kann. 

-> Ok! Ist nun so realisiert, dass die USR-Laufzeit von der Periode abgezogen
   wird. Das hat den gleichen Effekt wie oben beschrieben. Nur zwischen Aufsetzen
   des Auftrags und erstem Ablauf addieren sich die Zeiten.


* Die Gruppierung der Doxygen-Doku für VmeDevice, Default- und Therapie-USRs, 
  USR-Support neu machen oder aufheben. Nötig, weil die USRs in ein eigenes
  Projekt "usrs" gerutscht sind.

-> Ok!


* A long lasting problem with event connected commands should be
  solved:
  It is possible to connect to events in *all* virtual accelerators.
  But presently the call is executed for the virtual accelerator which
  is specified in the device access description, which is the same then
  for all execution of the event connected command.
  What is more naturally expected would be:
  - When the event is recognized in the virtual accelerator n, the
    call should be made for the virtual accelerator n,
  - when the event is recognized in the virtual accelerator m, the
    call should be made for the virtual accelerator m.
  Should in case of event connection the virtual accelerator of the
  event be used (that is, for connection to all events, the momentarily
  running virtual accelerator?
  Or should this behavior explicitly be requested?

-> Ok!

   * Auf asl (x86) will <nop>DevMan "ec.so" laden. Das sollte er aber nicht
     wollen, da es hier keine SEs gibt. Fehlermeldungen im Logfile sind:
       Aug  3 09:08:47 asl710 DevMan[23020]: devman.cc::initSE:397: Couldn't load so file ec.so 
           (ec.so: cannot open shared object file: No such file or directory)
       Aug  3 09:08:47 asl710 DevMan[23020]: devman.cc::initSE:444: terminated with exception: 
           ec.so, Primary status = 202153792, Secondary status = 202153792

-> Ok! initSE wird nur noch auf der __powerpc__ -Plattform ausgeführt.

   * Ein Gerät wird _offline_ gemeldet, ist aber auf 
     der SE gar nicht (mehr) vorhanden (_unknown_). 

     =TR2QT21  XSR-E-DEV_OFFLINE, Gerät ist offline=

     War wohl mal online, auf der SE gab's aber 
     mittlerweile einen INIT. Ist's nicht auf der SE 
     bekannt, sollte es als unknown gemeldet werden.
     Oder anders: Es sollte immer der Zustand gemeldet 
     werden, der von der SE gemeldet wird und den 
     man im SE-Display sehen kann.

-> Ok!

   * Der Devman legt _immer_ alle neun EC-Objekte an, auch wenn nicht
     alle Slots mit SEs bestückt sind. Schön wäre, wenn es nur für die
     vorhandenen SEs ein entsprechendes Objekt gäbe.
  
-> Ok! das macht er jetzt nicht mehr, sondern nur noch SEs, die mindestens 
   mapped (also als physischer Speicher vorhanden) sind

   * Beim Generieren des Devman sollte sowas wie ein devman-version.hh
     erzeugt werden, das in der Methode getVersionStrings()  in
     dman-device.cc benutzt werden kann. Beachten: X86- und PPC-Devman
     haben unterschiedliche Versionsnummern! X86 hat 01.xx.yy und PPC
     hat 09.xx.yy.
 
    Das dman-usrs-version.hh für die Version der Devman-USRs muss auch
     generiert werden. Das ist zur Zeit noch handgemacht!

-> Ok! ist in make.mk drin

   * ec-online-check verbessern, sodass in der Restart-Phase der SE kein
     Unsinn passiert (von devman aus). Dazu z.B. ecmDisplay.status != STAT_INIT
     prüfen

-> Ok! hat sich anderweitig erledigt

* Für DEVDESC - und wohl für andere Properties auch -
  muss man bedenken, dass sie auch von Userface aus
  gelesen werden können. So müssen Strings, etwa die
  Nomenklaturen, immer gleich lang (8 Zeichen) sein.
  Notfalls ist vor dem verschicken Blank-Padding 
  notwendig!

-> Ok, DEVDESC2 erfunden.


* Brauchen wir eigentlich auch ein reldevman, wie wir unter V08 ein
  relmops hatten? Also auf /opt/acc/cpu einen Link setzen auf 
  den gewünschten devman.so.ss.dd.pp, der auf /usr/local/lib liegt?
  Und was ist mit all den anderen "Nicht-Gerätemodell"-so-Files auf 
  /usr/local/lib, wie z.B. vmeconfig.so.ss.dd.pp, accdata.so.ss.dd.pp 
  usw.? Die müsste man doch auch cpu-spezifisch versionieren können.

-> Ok, wird mit Release 8 erledigt.


* Sollte man im DevMan statt fest verdrahteter Directories, wie z.B.
  /opt/acc/cpu, nicht besser auf Umgebungsvariablen zurückgreifen? Die
  kann man dann plattform-spezifisch setzen. Und man hätte den Vorteil,
  dass man nicht überall die gleiche Umgebung braucht.

-> Ok, bleibt zunächst so.

Topic revision: r14 - 18 Aug 2011, UnknownUser
This site is powered by FoswikiCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding Foswiki? Send feedback