j
...@cs.tu-berlin.de (Joerg Schilling) wrote:
>Hartmut Welpmann <hartmut.welpm
...@gmx.de> wrote:
>>bekanntlich führt sowohl "cdda2wav -paranoia" als auch "mkisofs |
>>cdrecord -" unter Cygwin ab Version 1.3.18 zum Einfrieren des
>>kompletten Systems. Da bisher AFAIK noch keine Lösung des Problems
>>gefunden wurde, habe ich die aktuellen cdrtools mit
>>Debug-Informationen kompiliert und mit dem GNU Debugger gdb
>>untersucht.
>>Dabei ist mir nach einiger Zeit aufgefallen, dass das Einfrieren immer
>>in Zusammenhang mit der Änderung der Prozess-Priorität mittels der
>>Funktionen rt_raisepri() [cdrecord.c] bzw.
>>switch_to_realtime_priority() [cdda2wav.c] stand. Daraufhin habe ich
>>eben diese Funktionen testweise selbiger beraubt und die cdrtools neu
>>kompiliert.
>>Dadurch sind nicht nur die Systemabstürze bei cdda2wav -paranoia
>>verschwunden, auch das Pipen von mkisofs nach cdrecord geht jetzt mit
>>voller Geschwindigkeit [1]! Natürlich kann ich nicht sagen, ob dieser
>>Patch auch auf anderen Systemen seine Wirkung zeigt, hier mit Cygwin
>>1.3.22/Windows XP SP1 [2] und Athlon XP 2000+/VIA KT266A funktioniert
>>es bisher jedenfalls wunderbar.
>Damit bastelst Du nur an den Symptomen!
Das ist klar, das komplette Deaktivieren obiger Funktionen sollte auch
nur ein QAD hack sein, um der Ursache des Problems näher zu kommen.
>Als Ergebnis hast Du eine erheblich höhere Wahrscheinlichkeit für Buffer
>underruns. Es ist allgemein bekannt (vielleich nur nicht den RedHat Leuten)
>daß es sich um ein durch Cygwin hausgemachtes Problem handelt, denn
>alte Cywin Versionen haven nicht dieses Problem.
Das ist auch mir bekannt [1]. Ich habe nun, statt die Funktionen ganz
zu entfernen, lediglich die zu setzende priority class von REALTIME in
HIGH abgeändert. Das funktioniert hier mindestens ebenso gut wie mein
erster Workaround. Offensichtlich bekommt Cygwin unter bestimmten
Bedingungen Probleme, sobald Prozesse mit realtime priority ausgeführt
werden sollen [2].
Es scheint also, dass zur Zeit mehr als high priority für cdrecord
bzw. cdda2wav unter Cygwin nicht drin ist. Spricht also grundsätzlich
etwas dagegen, hier (und nur hier unter Cygwin) das Setzen von
realtime priority zu vermeiden?
Gruß, Hartmut
P.S.: neue Patches siehe unten
[1] siehe <4qn2bvsnd8tdu6pg468huchgp9qm4oo...@4ax.com> ;)
[2] und ist offenbar darauf auch gar nicht ausgelegt, siehe
http://sources.redhat.com/ml/cygwin/2002-11/msg01491.html "Cygwin is a
general purpose tool, and internally not quite up to running at
realtime" --Robert Collins
--- cdrecord/cdrecord.org.c 2003-04-29 21:59:14.000000000 +0200
+++ cdrecord/cdrecord.c 2003-05-02 10:16:14.000000000 +0200
@@ -321,8 +321,9 @@
cdr_version,
HOST_CPU, HOST_VENDOR, HOST_OS);
+#define SOURCE_MODIFIED
#ifdef SOURCE_MODIFIED
-#define INSERT_YOUR_EMAIL_ADDRESS_HERE
+#define INSERT_YOUR_EMAIL_ADDRESS_HERE "hartmut.welpm...@gmx.de"
printf("NOTE: this version of cdrecord is an inofficial (mofified) release of cdrecord\n");
printf(" and thus may have bugs that are not present in the original version.\n");
printf(" Please send bug reports and support requests to <%s>.\n", INSERT_YOUR_EMAIL_ADDRESS_HERE);
@@ -3903,14 +3904,14 @@
int prios[] = {THREAD_PRIORITY_TIME_CRITICAL, THREAD_PRIORITY_HIGHEST};
/* set priority class */
- if (SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS) == FALSE) {
- errmsgno(EX_BAD, "No realtime priority class possible.\n");
+ if (SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS) == FALSE) {
+ errmsgno(EX_BAD, "No high priority class possible.\n");
return (-1);
}
/* set thread priority */
if (pri >= 0 && pri <= 1 && SetThreadPriority(GetCurrentThread(), prios[pri]) == FALSE) {
- errmsgno(EX_BAD, "Could not set realtime priority.\n");
+ errmsgno(EX_BAD, "Could not set high priority.\n");
return (-1);
}
return (0);
--- cdda2wav/cdda2wav.org.c 2003-03-31 13:47:33.000000000 +0200
+++ cdda2wav/cdda2wav.c 2003-05-02 10:18:45.000000000 +0200
@@ -1004,14 +1004,14 @@
switch_to_realtime_priority()
{
/* set priority class */
- if (FALSE == SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS)) {
- fprintf(stderr, "No realtime priority possible.\n");
+ if (FALSE == SetPriorityClass(GetCurrentProcess(), HIGH_PRIORITY_CLASS)) {
+ fprintf(stderr, "No high priority possible.\n");
return;
}
/* set thread priority */
if (FALSE == SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_HIGHEST)) {
- fprintf(stderr, "Could not set realtime priority.\n");
+ fprintf(stderr, "Could not set high priority.\n");
}
}
#else
--
Hartmut Welpmann