amiga-news ENGLISH VERSION
.
Links| Forum| Kommentare| News melden
.
Chat| Umfragen| Newsticker| Archiv
.

amiga-news.de Forum > Programmierung > Laufwerke Feststellen [ - Suche - Neue Beiträge - Registrieren - Login - ]

-1- [ - Beitrag schreiben - ]

08.04.2003, 16:20 Uhr

Inferno
Posts: 157
Nutzer
Hallo,

wie kann ich die Laufwerksnamen (also z.B. "Work", "RAM", "System", etc.) eines Systems unter C/C++ feststellen? Kann man dazu die MatchFirst / MatchNext - Funktionen benutzen? Falls ja, welche Parameter brauchts dann dazu?

Vielen Dank,

Inf.

[ - Antworten - Zitieren - Direktlink - ]

08.04.2003, 17:27 Uhr

thomas
Posts: 7716
Nutzer

Nein, du benutzt LockDosList, NextDosEntry und UnLockDosList. Ein Beispiel steht in den Autodocs zu LockDosList.

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

08.04.2003, 17:47 Uhr

Inferno
Posts: 157
Nutzer
Vielen Dank !1!

Inf.

[ - Antworten - Zitieren - Direktlink - ]

08.04.2003, 18:11 Uhr

Holger
Posts: 8116
Nutzer
Kurz und knapp
code:
#include <dos/dos.h>
#include <proto/dos.h>

int main(int argc, char**arg)
{
  struct DosList* dlist;
  char *name;
  int flags=LDF_READ|LDF_VOLUMES; /* LDF_ASSIGNS, LDF_DEVICES, can be or'ed */

  dlist = (struct DosList*)LockDosList(flags);
  if(dlist!=NULL)
  {
    do
    {
      dlist = (struct DosList*)NextDosEntry(dlist, flags);
      if(dlist==NULL) break;
      name = (char*)BADDR(dlist->dol_Name)+1;
      VPrintf("Volume: %sn", &name);
    } while(1);
    UnLockDosList(flags);
  }
  else
  {
    PutStr("Couldn't lock dos listn");
    return RETURN_FAIL;
  }

  return RETURN_OK;
}

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

08.04.2003, 21:06 Uhr

thomash
Posts: 172
Nutzer
@Holger:
Zitat:
Good coders do not comment. What was hard to write should be hard to read too.

And good coders do not use DOS functions, while DOSList is locked...

Im Autodoc steht ausdrücklich, die Zeit kurz zu halten, während der die DOSList gesperrt ist. Besser wäre es also, die Namen in einen Puffer zu kopieren. Aber auf keinen Fall bei gesperrter Liste per xxPrintf() ausgeben, das kann funktionieren, muß aber nicht. Und nach Murphy geht sofort etwas schief, wenn es die Möglichkeit dazu gibt. :)

Ciao,
Hoin.

[ - Antworten - Zitieren - Direktlink - ]

09.04.2003, 13:04 Uhr

Tessien
Posts: 55
Nutzer
Zitat:
Und nach Murphy geht sofort etwas schief, wenn es die Möglichkeit dazu gibt. :)

Nein, Murphy ist hier veraltet. In einem ordentlichen Projekt geht es auf dem Rechner des Programmierers und bei allen Betatestern, stürzt aber auf dem Testrechner der wichtigsten Zeitschrift ab. Und bei 80% aller User. Und die schreiben dann wütende EMails.

Bye, Thomas


--
Thomas Schulze - programmer at Dreamworlds Development - http://www.dreamworlds.de

[ - Antworten - Zitieren - Direktlink - ]

09.04.2003, 14:07 Uhr

Solar
Posts: 3680
Nutzer
Ich hätte einen syntaktischen Verbesserungsvorschlag zu machen. (Auf die Sache mit dem Puffer gehe ich jetzt mal gar nicht ein, ich habe mich zu sehr an die STL gewöhnt um das jetzt ad hoc richtig zu machen. ;-) )

code:
dlist = (struct DosList*) LockDosList(flags);
if (dlist == NULL)
{
    PutStr("Couldn't lock DosListn");
    return RETURN_FAIL;
}

while (dlist != NULL)
{
    name = (char*) BADDR(dlist->dol_Name)+1;
    VPrintf("Volume: %sn", &name); // FIXME: siehe oben
    dlist = (struct DosList*)NextDosEntry(dlist, flags);
}
UnLockDosList(flags);

return RETURN_OK;


Vorteile:


  • kürzer (um 4 Zeilen bzw. 22%);
  • Fehlerbehandlung da wo der Fehler auftritt, nicht am Ende der Funktion;
  • kein break, keine do-while "Endlos"-Schleife.


Zu letzterem... break ist nur unwesentlich "besser" als goto, und die "kanonische" Schreibweise für eine Endlosschleife ist eigentlich "for (;;)".

Und eine Endlosschleife mit einem break ist ein ziemlich sicheres Zeichen für einen vermurksten Algorithmus.

(Kein Angriff auf Holger; aber Lesbarkeit von Code ist genauso wichtig wie fehlerfreies funktionieren desselben.)

[ Dieser Beitrag wurde von Solar am 09.04.2003 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

09.04.2003, 14:57 Uhr

thomas
Posts: 7716
Nutzer

Nein, das ist falsch. LockDosList gibt keinen gültigen DosEntry zurück. Du mußt mindestens einmal NextDosEntry aufrufen.

Ich würde

while (dl = NextDosEntry())
{
...
}

nehmen.

Oder

dl = NextDosEntry();
while (dl != NULL)
{
...
dl = NextDosEntry();
}

(so lernt man es beim Software-Engeneering).

Gruß Thomas

--
Email: thomas-rapp@web.de
Home: home.t-online.de/home/thomas-rapp/

[ - Antworten - Zitieren - Direktlink - ]

09.04.2003, 15:10 Uhr

Solar
Posts: 3680
Nutzer
Zitat:
Original von thomas:

Nein, das ist falsch. LockDosList gibt keinen gültigen DosEntry zurück. Du mußt mindestens einmal NextDosEntry aufrufen.


Sorry, hatte ich übersehen.

Aber so ist's ja noch besser:

code:
if ((dlist = (struct DosList*) LockDosList(flags)) == NULL)
{
    PutStr("Couldn't lock DosListn");
    return RETURN_FAIL;
}

while ((dlist = (struct DosList*)NextDosEntry(dlist, flags)) != NULL)
{
    ...
}


Zitat:
Oder

dl = NextDosEntry();
while (dl != NULL)
{
...
dl = NextDosEntry();
}

(so lernt man es beim Software-Engeneering).


Hm. Lehrbuch-SE: formal korrekt, praktisch unhandlich. Informatik-Studium?

Zumindest scheinen wir uns einig, was das break; angeht.

[ - Antworten - Zitieren - Direktlink - ]

09.04.2003, 22:50 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von thomash:
And good coders do not use DOS functions, while DOSList is locked...

Wie soll ich dann die DOSList auslesen, wenn ich keine DOS-Funktionen benutzen darf. 8o
Einigen wir uns vielleicht doch darauf, das man keine DOS-Funktionen benutzen darf, die selbige modifizieren könnten (einfache Write-Funktionen gehören nicht dazu.)
Ansonsten auch vielen Dank für die Aufmerksamkeit für dieses Beispielprogramm, das in der Praxis so ohnehin nie eingesetzt wird.
Zitat:
Im Autodoc steht ausdrücklich, die Zeit kurz zu halten, während der die DOSList gesperrt ist. Besser wäre es also, die Namen in einen Puffer zu kopieren.
Beweise erst einmal, daß eine solche Kopieroperation tatsächlich schneller geht, als die mit der Print-Anweisung assoziierte write-Operation.
Zitat:
Aber auf keinen Fall bei gesperrter Liste per xxPrintf() ausgeben, das kann funktionieren, muß aber nicht.
Wenn eine einfache Write-Operation eine Modifikation der DOSList verursacht, ist dies definitiv ein Bug des darunterliegenden File-Systems.
Nebenbei gesagt, für mich bleibt es ein design-Fehler des AmigaOS, daß solche Deadlock-Gefahren überhaupt existieren, insbesondere wenn man so eine einfache Operation durchführen will.

mfg
--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

09.04.2003, 22:57 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von thomas:
Ich würde

while (dl = NextDosEntry())
{
...
}

nehmen.

Ok, mit mehr Zeit wäre ich vielleicht drauf gekommen.:O
Aber für'n einfaches Beispiel....formt doch sowieso jeder nach seinem Geschmack um.
Zitat:
Oder

dl = NextDosEntry();
while (dl != NULL)
{
...
dl = NextDosEntry();
}

Genau diese Doppelung wollte ich vermeiden. Ein Aufruf in der Schleife, ein anderer außerhalb, obwohl es sich semantisch um _einen_ wiederholten Aufruf handelt, ... nee, auch was auch immer sich SE-Leute dabei denken, das iss nich wirklich übersichtlicher.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

10.04.2003, 09:15 Uhr

gni
Posts: 1106
Nutzer
Zitat:
Original von Holger:
Wie soll ich dann die DOSList auslesen, wenn ich keine DOS-Funktionen benutzen darf.

Ab dem Zeitpunkt ab dem Du die DOSListe gelockt hast, darfst Du _keine_ DOS-Funktionen mehr benutzen. Punkt.
Zitat:
Zitat:
Im Autodoc steht ausdrücklich, die Zeit kurz zu halten, während der die DOSList gesperrt ist. Besser wäre es also, die Namen in einen Puffer zu kopieren.
Beweise erst einmal, daß eine solche Kopieroperation tatsächlich schneller geht, als die mit der Print-Anweisung assoziierte write-Operation.
Da gibt es _nichts_ zu beweisen. Die Dokumentation verbietet es expilizit. Was gibt es da zu bezweifeln?
Zitat:
Nebenbei gesagt, für mich bleibt es ein design-Fehler des AmigaOS, daß solche Deadlock-Gefahren überhaupt existieren, insbesondere wenn man so eine einfache Operation durchführen will.
Es ist immer erheiternd, solch qualifizierte Kommentare zu lesen...

[ - Antworten - Zitieren - Direktlink - ]

10.04.2003, 12:39 Uhr

Solar
Posts: 3680
Nutzer
Zitat:
Original von Holger:
Wie soll ich dann die DOSList auslesen, wenn ich keine DOS-Funktionen benutzen darf.


Ganz grundsätzlich gilt: Lock, schnellstmögliches Verarbeiten, Unlock. Schnellstmöglich heißt i.d.R. zwischenpuffern. Dazu kommt die gesunde Paranoia gegenüber jeder Aktion, die komplexer ist als eine Wertzuweisung an fertig allozierten Speicher.

Zitat:
Zitat:
Im Autodoc steht ausdrücklich, die Zeit kurz zu halten, während der die DOSList gesperrt ist. Besser wäre es also, die Namen in einen Puffer zu kopieren.
Beweise erst einmal, daß eine solche Kopieroperation tatsächlich schneller geht, als die mit der Print-Anweisung assoziierte write-Operation.

Öhm... in jedem Fall nicht langsamer? (Abgesehen davon hat man beim Zwischenpuffern die Daten auch nach der Ausgabe noch zur Verfügung; caching, re-use und Konsorten...)

Zitat:
Wenn eine einfache Write-Operation eine Modifikation der DOSList verursacht, ist dies definitiv ein Bug des darunterliegenden File-Systems.

Nebenbei gesagt, für mich bleibt es ein design-Fehler des AmigaOS, daß solche Deadlock-Gefahren überhaupt existieren...


Es geht hier wohl eher nicht darum, das die Liste sich ändern könnte, oder um Deadlocks, sondern daß das Programm bei Problemen mit der Write-Operation bei gesetztem Lock abbrechen könnte.

Das Vermeiden von Deadlocks ist eine akademische Kunst. Ist wie mit Speicherschutz: Perfekt geht nicht. Und wahrscheinlich haben sich die ur-Amiganer bei Deadlocks dasselbe gedacht wie bei Speicherschutz: Wenn wir's nicht perfekt hinbekommen können, dann lassen wir's ganz und freuen uns an der zusätzlichen Performance.

Man kann halt nicht auf der einen Seite die Effizienz des AmigaOS anpreisen und auf der anderen Seite Dinge fordern wie die perfekte Vermeidung von Deadlocks...

[ - Antworten - Zitieren - Direktlink - ]

10.04.2003, 19:39 Uhr

thomash
Posts: 172
Nutzer
Zitat:
Original von Holger:
Wie soll ich dann die DOSList auslesen, wenn ich keine DOS-Funktionen benutzen darf. 8o


strcpy(). Oder CopyMem().

Zitat:
Einigen wir uns vielleicht doch darauf, das man keine DOS-Funktionen benutzen darf, die selbige modifizieren könnten (einfache Write-Funktionen gehören nicht dazu.)

Doch:

Beispielprogramm >Laufwerk:Datei

Wenn der User das Programm wie oben ablaufen läßt, und ein Laufwerk eingibt, das noch nicht im System existiert, wird die DosList auch bei Write(Output(),,) durchsucht. Was dann nicht mehr geht, da gesperrt. Gelesen wird sie wohl noch, aber das Lock auf das Laufwerk schlägt fehl, da die Liste nicht modifiziert werden kann, Output() liefert keinen Wert, und Write() bekommt eine NULL als Ausgabekanal...

Das kommt vielleicht nicht häufig vor, aber Tippfehler passieren eben und schon wird ein unbekanntes Laufwerk angefordert, z.B. dg0: statt df0:.

Zitat:
Ansonsten auch vielen Dank für die Aufmerksamkeit für dieses Beispielprogramm, das in der Praxis so ohnehin nie eingesetzt wird.

Das ist schon klar. Aber viele Neueinsteiger in die Amigaprogrammierung probieren erst mal was aus, freuen sich daß es geht, und vergessen die Sache dann abzusichern. Und wieder gibt es ein Programm mehr, das den Guru beschwört.

Zumindest sollte man auf Gefahren hinweisen, die auftreten können. Ich würde nicht mal die Beispiele aus den Autodocs und RKMs einfach so übernehmen. Da stecken auch oft unsichere Annahmen drin, aber das sind ja auch explizit Programmierbeispiele, keine fertigen Module.

Zitat:
Beweise erst einmal, daß eine solche Kopieroperation tatsächlich schneller geht, als die mit der Print-Anweisung assoziierte write-Operation.

Darum geht es gar nicht. DOS ist immer aktiv und will z.B. ein neues Laufwerk in die DosList einklinken, zu der eine nicht-gesperrte DosList benötigt wird.

Man muß sich im klaren sein, daß der Inhalt der DosList in dem Augenblick veraltet ist, in dem man sie freigibt. Legt der User eine Diskette ein, während die DosList gelockt ist, wird der Diskettenname erst eingefügt, nachdem man die DosList freigegeben hat.

Das ist die eigentliche Bedeutung von "schnell" im DOS-Sinn. Die Liste ist so lange veraltet, wie jemand sie sperrt und das DOS nicht drankommt.

Trotzdem der Beweis:
VPrintf(): VPrintf() ist eine DOS Funktion. Write() wird als eine Funktion der DOS-Library aufgerufen. Output() auch. Es wird implizit ein Wait() (exec) ausgeführt, bis der String geschrieben ist. Hier hängt obiges Beispielprogramm wahrscheinlich schon. Spätestens mit dem Wait() ist ein Taskwechsel fällig, da der unterliegende Handler (Shell, Filesystem) die Ausgabe übernimmt.

strcpy(): Das läuft so schnell, wie der Prozessor es eben kann. Es werden nur Zeichen aus dem RAM (DosList) ins RAM (Puffer) geschrieben, und das normalerweise in einer Schleife mit drei Assemblerbefehlen: "move.b", "tst.b" und "beq". Schneller geht's nimmer. Und man kann sogar das "tst" rausoptimieren, da ein "move" von RAM nach RAM auch schon die Statusbits setzt und "beq" direkt funktioniert.

Zitat:
Wenn eine einfache Write-Operation eine Modifikation der DOSList verursacht, ist dies definitiv ein Bug des darunterliegenden File-Systems.
Nebenbei gesagt, für mich bleibt es ein design-Fehler des AmigaOS, daß solche Deadlock-Gefahren überhaupt existieren, insbesondere wenn man so eine einfache Operation durchführen will.


Naja, wenn, dann ein Bug des DOS (siehe oben). Das tritt bei allen Filesystemen auf.

Und eigentlich verursacht ja nicht Write() ein auslesen der DosList, sondern Output(). Das ist eben die Gefahr, daß eine Funktion recht simpel aussieht, aber wenn ich sie nicht geschrieben habe, weiß ich nicht, wie sie wirklich aussieht. Deswegen gibt es die Autodocs und vor allem die Warnungen und Hinweise die drinstehen.


Ciao,
Hoin.

[ - Antworten - Zitieren - Direktlink - ]

10.04.2003, 23:39 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von thomash:
Zitat:
Original von Holger:
Wie soll ich dann die DOSList auslesen, wenn ich keine DOS-Funktionen benutzen darf. 8o


strcpy(). Oder CopyMem().

Die DOSList wird mit NextDosEntry() ausgelesen, Punkt.
Und NextDosEntry() ist eine DOS-Funktion, Punkt.
Und deshalb ist die Aussage, man dürfe keine DOS-Funktionen während des Auslesens aufrufen, grundsätzlich falsch, man muß sogar eine DOS-Funktion aufrufen, Punkt.
Zitat:
Beispielprogramm >Laufwerk:Datei

Wenn der User das Programm wie oben ablaufen läßt, und ein Laufwerk eingibt, das noch nicht im System existiert, wird die DosList auch bei Write(Output(),,) durchsucht.
...Das kommt vielleicht nicht häufig vor, aber Tippfehler passieren eben und schon wird ein unbekanntes Laufwerk angefordert, z.B. dg0: statt df0:.

Das ist totaler Blödsinn. Der Output-Kanal wird vor dem Aufruf des Programms gesetzt und muß zu diesem Zeitpunkt ein gültiger FileHandle sein. Wenn wer auch immer sich vertippt, passiert das vor dem der Write-Operation, in Deinem Beispiel sogar noch vor dem Start des Programms. Eine Write-Operation kann und darf die DOSList nicht verändern.
Zitat:
Zumindest sollte man auf Gefahren hinweisen, die auftreten können. Ich würde nicht mal die Beispiele aus den Autodocs und RKMs einfach so übernehmen. Da stecken auch oft unsichere Annahmen drin, aber das sind ja auch explizit Programmierbeispiele, keine fertigen Module.
Eben, Beispiele, wie das Programm oben.
Zitat:
Man muß sich im klaren sein, daß der Inhalt der DosList in dem Augenblick veraltet ist, in dem man sie freigibt. Legt der User eine Diskette ein, während die DosList gelockt ist, wird der Diskettenname erst eingefügt, nachdem man die DosList freigegeben hat.

Das ist die eigentliche Bedeutung von "schnell" im DOS-Sinn. Die Liste ist so lange veraltet, wie jemand sie sperrt und das DOS nicht drankommt.

Wenn Du das Einlegen einer Diskette mit der Konsoleausgabe vergleichst, dann kann die Diskette ruhig zwei microsekunden länger warten.
Zitat:
strcpy(): Das läuft so schnell, wie der Prozessor es eben kann. Es werden nur Zeichen aus dem RAM (DosList) ins RAM (Puffer) geschrieben, und das normalerweise in einer Schleife mit drei Assemblerbefehlen:
Das ist eine unzulässige Annahme. In einem Multitasking-System kann man nicht annehmen, daß eine Operation so schnell läuft, wie der Prozessor es kann.
Zitat:
Und eigentlich verursacht ja nicht Write() ein auslesen der DosList, sondern Output().
Output gibt Dir einfach nur den FileHandle, der als Outputkanal gesetzt wurde, da passiert gar nichts.

Wie gesagt, es ist nur ein Beispiel, und die Gefahren sind jetzt auch hinreichend in diesem Thread dokumentiert worden.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 10.04.2003 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

10.04.2003, 23:53 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Solar:
Ganz grundsätzlich gilt: Lock, schnellstmögliches Verarbeiten, Unlock. Schnellstmöglich heißt i.d.R. zwischenpuffern. Dazu kommt die gesunde Paranoia gegenüber jeder Aktion, die komplexer ist als eine Wertzuweisung an fertig allozierten Speicher.

In jedem Programm, das kein Bespiel für ein bestimmtes Teilproblem darstellt, ist dies natürlich richtig.
Zitat:
(Abgesehen davon hat man beim Zwischenpuffern die Daten auch nach der Ausgabe noch zur Verfügung; caching, re-use und Konsorten...)
Das wird wohl in der Praxis immer so sein, daß man die Daten für irgendeinen bestimmten Zweck braucht und sie deshalb lieber speichert, anstatt sie auf der Konsole auszugeben.
Zitat:
Es geht hier wohl eher nicht darum, das die Liste sich ändern könnte, oder um Deadlocks, sondern daß das Programm bei Problemen mit der Write-Operation bei gesetztem Lock abbrechen könnte.
Tut es nicht. Und zeige mir den Programmierer, der in seiner Software an den Fall denkt, das printf fehlschlagen könnte...
Zitat:
Das Vermeiden von Deadlocks ist eine akademische Kunst. Ist wie mit Speicherschutz: Perfekt geht nicht. Und wahrscheinlich haben sich die ur-Amiganer bei Deadlocks dasselbe gedacht wie bei Speicherschutz: Wenn wir's nicht perfekt hinbekommen können, dann lassen wir's ganz und freuen uns an der zusätzlichen Performance.
Das mit der höheren Performance ist zweifelhaft. Da ja jedes sauber geschriebene Programm eine Kopie anlegt (das sagen wir doch alle), wäre es das naheliegenste, eine Funktion im OS zu implementieren, die gleich eine Kopie zurückliefert. Damit sind Deadlocks an dieser Stelle absolut sicher ausgeschlossen und es ist effizienter, da eine einzelne OS-Routine den Prozessorcache besser ausnutzt, als n eigene Versionen dieser Kopierroutine in jedem Programm.

Vergleiche Examine() und ExAll(), ähnliche Problematik.

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ - Antworten - Zitieren - Direktlink - ]

11.04.2003, 10:07 Uhr

Solar
Posts: 3680
Nutzer
Zitat:
Original von Holger:
In jedem Programm, das kein Bespiel für ein bestimmtes Teilproblem darstellt, ist dies natürlich richtig.


OK, der Punkt ist angekommen und akzeptiert: Dein Beispielcode war halt nur ein Beispiel. Wir kritisieren nicht, wir fachsimpeln.

Zitat:
Und zeige mir den Programmierer, der in seiner Software an den Fall denkt, das printf fehlschlagen könnte...

fprintf() in jedem Fall. Aber Du hast recht, die meisten interessieren sich nicht mal für den ach-so-unwahrscheinlichen Fall, daß malloc() ein NULL zurückgeben könnte... das hat neulich einer Anwendung auf einer mit zig GByte Arbeitsspeicher ausgestatteten Sun E10000 ein abruptes Ende beschert...

Zitat:
Da ja jedes sauber geschriebene Programm eine Kopie anlegt (das sagen wir doch alle), wäre es das naheliegenste, eine Funktion im OS zu implementieren, die gleich eine Kopie zurückliefert. Damit sind Deadlocks an dieser Stelle absolut sicher ausgeschlossen...

Nein. Die Gefahr wäre nur in die OS-Funktion verlagert. Es ist ziemlich schwierig, eine solche Funktion in eienr Weise zu implementieren, die jedem worst-case von multitasking, multiprocessing und Fehlbedienung standhält. Und wenn man eine solche ösung hat, kostet sie erhebliches an Laufzeit...

Zitat:
...und es ist effizienter, da eine einzelne OS-Routine den Prozessorcache besser ausnutzt, als n eigene Versionen dieser Kopierroutine in jedem Programm.

Na, na. Die allermeisten OS-Routinen werden wohl kaum oft genug aufgerufen, um zwischen zwei Aufrufen nicht aus dem Cache zu wandern. (Wie oft fragst Du die verfügbaren Laufwerke ab?)

[ - Antworten - Zitieren - Direktlink - ]

11.04.2003, 20:26 Uhr

thomash
Posts: 172
Nutzer
Zitat:
Original von Holger:
Die DOSList wird mit NextDosEntry() ausgelesen, Punkt.
Und NextDosEntry() ist eine DOS-Funktion, Punkt.
Und deshalb ist die Aussage, man dürfe keine DOS-Funktionen während des Auslesens aufrufen, grundsätzlich falsch, man muß sogar eine DOS-Funktion aufrufen, Punkt.


Gut, dann drücke ich es genauer aus: Die einzige DOS-Funktion, die während eines LockDosList() ungefährlich ist, ist NextDosEntry(), da ausdrücklich erlaubt.

Aber eine Ausnahme zur Regel zu machen ? Ohne mich.

Zitat:
Beispielprogramm >Laufwerk:Datei

Das ist totaler Blödsinn. Der Output-Kanal wird vor dem Aufruf des Programms gesetzt und muß zu diesem Zeitpunkt ein gültiger FileHandle sein. Wenn wer auch immer sich vertippt, passiert das vor dem der Write-Operation, in Deinem Beispiel sogar noch vor dem Start des Programms.


Hm, das stimmt sogar. Naja, nach 9 Stunden Arbeit... Übrigens ist noch ein Fehler von mir drin, die letzte Assembleranweisung ist ein "bne", nicht "beq"...

Zitat:
Eine Write-Operation kann und darf die DOSList nicht verändern.

Das Problem liegt ja auch nicht bei Write(), sondern Output(), bzw. jedem anderen übergebenem Filehandle. Außerdem ist xxPrintf() eine gepufferte Funktion. Da kommt am Programmende und bei Linefeeds noch ein Flush() dazu. Und Commodore weiß, was noch alles, schließlich werden hier Formatzeichen (exec/RawDoFmt()) verwendet.

Ich kann nicht wissen, welche Funktionen intern von einer DOS-Funktion aufgerufen werden. Es können auch gefährliche dabei sein. Daß sie bei Printf() nicht dabei sind, ist unerheblich. Gut für das Beispielprogramm, schlecht für produktiven Code, der nicht mehr Printf() benutzt, sondern potentiell DosList-modifizierende Funktionen.

Zitat:
Wenn Du das Einlegen einer Diskette mit der Konsoleausgabe vergleichst, dann kann die Diskette ruhig zwei microsekunden länger warten.

Du hast es noch nicht kapiert: Das Diskettenbeispiel ist ein Beispiel. Genauso kann es das einbinden von Netzlaufwerken verzögern, von anderen Wechseldatenträgern (ZIP, PCMCIA, USB-Geräte), usw. Es ist einfach schlecht, mehr Zeit zu verbrauchen, als absolut nötig ist. Davon lebt das Amiga-OS schon von Anfang an. Wenn wir das über Bord werfen, unterscheidet uns nichts mehr von Windows.

Zitat:
Zitat:
strcpy(): Das läuft so schnell, wie der Prozessor es eben kann. Es werden nur Zeichen aus dem RAM (DosList) ins RAM (Puffer) geschrieben, und das normalerweise in einer Schleife mit drei Assemblerbefehlen:

Das ist eine unzulässige Annahme. In einem Multitasking-System kann man nicht annehmen, daß eine Operation so schnell läuft, wie der Prozessor es kann.


Ich habe es deshalb vernachlässigt, weil auch der Aufruf einer DOS-Funktion davon betroffen ist. Irgendwann muß ja auch der Handler den Puffer von Write() auslesen und zwar auf genau dieselbe Art und Weise. Anders geht es nicht. Nur legt DOS zwangsweise eine Pause (Taskwechsel) ein, durch das Wait(). Bei strcpy() kann man Glück haben, daß keiner stattfindet.

Und innerhalb des Task-Quantums hat der Prozess den Prozessor tatsächlich für sich alleine (ja, ich weiß: Interrupts. Aber damit wird auch DOS ausgebremst). Und Speicher auslesen ist schnell.

Zitat:
Output gibt Dir einfach nur den FileHandle, der als Outputkanal gesetzt wurde, da passiert gar nichts.

Oder NULL. Was eigentlich niemand abfragt (ich auch nicht, weil ich xxPrintf() nur zum debuggen und für Testprogramme benutze), obwohl man es sollte.

Zitat:
Wie gesagt, es ist nur ein Beispiel, und die Gefahren sind jetzt auch hinreichend in diesem Thread dokumentiert worden.

Das auf jeden Fall. :)


Ciao,
Hoin.

[ - Antworten - Zitieren - Direktlink - ]

12.04.2003, 17:38 Uhr

Holger
Posts: 8116
Nutzer
Zitat:
Original von Solar:
Nein. Die Gefahr wäre nur in die OS-Funktion verlagert. Es ist ziemlich schwierig, eine solche Funktion in eienr Weise zu implementieren, die jedem worst-case von multitasking, multiprocessing und Fehlbedienung standhält.

Wir waren uns doch einig, daß Deadlocks zu riskieren absolut indiskutabel ist. Also egal, ob die Lock-Iteration-Unlock Geschichte im OS oder in der Anwendung stattfindet, die muß korrekt sein.
Und ja, es ist ziemlich schwierig, sie korrekt zu implementieren. Und genau deshalb gehört sie ins OS. Damit diese Arbeit einmal gemacht wird und dann ist gut. Was nützt es, wenn ein oder zwei Programmierer eine abgesicherte und in allen Punkten korrekte Lösung entwickeln, wenn tausend andere es nicht tun und irgendeine Zeitbombe implementieren?
Zitat:
Und wenn man eine solche ösung hat, kostet sie erhebliches an Laufzeit...
Ja nun, Laufzeit oder Absturzsicherheit, darüber müssen wir doch nicht diskutieren, oder?
Du hast doch selbst gesagt, "Ganz grundsätzlich gilt: Lock, schnellstmögliches Verarbeiten, Unlock." grundsätzlich und nicht "wenn man auf performance verzichten kann".
Wenn es also eine grundsätzliche Vorgehensweise gibt, kann man sie auch im OS fixieren. Auch wenn sie langsamer ist, als eine fehlerhafte. (Und auch das Anwendungsbeispiel wäre kürzer)
Zitat:
Na, na. Die allermeisten OS-Routinen werden wohl kaum oft genug aufgerufen, um zwischen zwei Aufrufen nicht aus dem Cache zu wandern. (Wie oft fragst Du die verfügbaren Laufwerke ab?)
Dieses pattern zieht sich aber nunmal durchs gesamte OS, Lock-Iteration in der Anwendung-Unlock. Deshalb auch das Beispiel Examine/ExAll. Dort haben die OS-Entwickler eingesehen, daß es unvorteilhaft ist.
Ich könnte auch die Gegenfrage stellen: Kennst Du einen anderen Anwendungsfall, als die DOS-Liste in einen Puffer zu kopieren (wobei jede andere OS-Routine innerhalb der Iteration vermieden werden soll)?

mfg

--
Good coders do not comment. What was hard to write should be hard to read too.

[ Dieser Beitrag wurde von Holger am 12.04.2003 editiert. ]

[ - Antworten - Zitieren - Direktlink - ]

14.04.2003, 13:01 Uhr

Solar
Posts: 3680
Nutzer
Leider ist es nicht ganz so einfach. Wenn Du "die sichere Linie" fahren willst, müßtest Du z.B. auch malloc() mit einem Garbage Collector versehen... und der "perfekte" GC muß auch noch erst entwickelt werden.

[ - Antworten - Zitieren - Direktlink - ]

14.04.2003, 15:19 Uhr

Inferno
Posts: 157
Nutzer
Hallo Leute,

vielen Dank für den Input. Ich habe (Gott sei Dank) von Anfang an vorgehabt, die Daten in 'ner Array-Klasse abzulegen und nicht auszugeben, so daß es **eigentlich** keine Deadlocks geben sollte.

Wenn die Array-Klasse von anderen Klassen benutzt wird um etwas auszugeben, ist die Liste also längst wieder freigegeben ...

Gruß,

Inf

[ - Antworten - Zitieren - Direktlink - ]


-1- [ - Beitrag schreiben - ]


amiga-news.de Forum > Programmierung > Laufwerke Feststellen [ - Suche - Neue Beiträge - Registrieren - Login - ]


.
Impressum | Datenschutzerklärung | Netiquette | Werbung | Kontakt
Copyright © 1998-2024 by amiga-news.de - alle Rechte vorbehalten.
.