Mail Archives: djgpp/2004/12/16/11:12:24
On Thu, 16 Dec 2004 06:48:32 +0200
"Eli Zaretskii" <eliz AT gnu DOT org> wrote:
> > Date: Wed, 15 Dec 2004 23:46:45 -0200
> > From: Jonatan Liljedahl <lijon AT kymatica DOT com>
> >
> > > Does the problem go away if you hook the timer interrupt, but do
> > > not reprogram the timer to a higher frequency?
> >
> > I just tried this: I leave the PIT alone and I chain to the original
> > handler at the end of my own handler every time. Yes, the problem
> > goes away!
>
> Then I'd suspect that with a reprogrammed PIT, the next timer
> interrupt hits you while SmartDRV is still writing data to disk, and
> that causes the machine to hang. Perhaps your handler is invoked
> again, for example.
Ah, yes of course. The original handler is _called_ from my handler, so
my handler doesn't return before the original handler is finished (when
smartdrv is finished writing), therefore it's quite possible that a new
interrupt happens before my handler has returned.
I remember that in the past, when I used borlands C compiler (realmode),
it was possible to have reentrant interrupts, it was no problem if a
interrupt interrupted itself, and I could set a global variable to
detect this... But I think I wasn't able to do this in DJGPP...
> Yes, I saw that you called `disable', but as you
> might know, this not necessarily actually disables the hardware
> interrupt from happening.
Ok, No, I didn't know that. So how do I actually disable interrupts?
> I'd suggest to check whether the interrupt
> happens while the previous one is still being processed.
How could I check this? (It hangs, so it's hard to report anything to
the user)
> > By the way, I have also tried to disable interrupts while writing to
> > disc, and to flush smartdrv before enabling interrupts again
> > (assuming that sync() does signal to smartdrv to flush it's cache,
> > as it says in the info).
>
> `sync' does force SmartDRV tp flush its buffers, just look at the
> library sources, and ou will see.
Btw, I see there that it checks for _USE_LFN and thinks this means that
it's running under W95, but this isn't true as I'm running under DOS
6.22 with a LFN driver loaded (which also sets _USE_LFN):
if (_USE_LFN)
{
/* Windows 95 have special function to do what we want. */
/* FIXME: What if LFN is supported by a platform other than W95?
*/
r.x.ax = 0x710d;
r.x.cx = 1; /* flush buffers and cache, reset drive */
r.x.dx = drv + 1;
__dpmi_int (0x21, &r);
/* According to docs (Interrupt list), this doesn't return
any error codes (??). */
}
else
....
> > > If everything else fails, you can include in your program's
> > > initialization routine code to disable SmartDRV automatically.
> > > Ralf Brown's Interrupt List documents the API exported by SmartDRV
> > > via interrupt 2Fh.
> >
> > Yes, that would be OK.
>
> I meant to disable the write-behind mode, not disable SmartDRV
> entirely, btw.
Yes, I've done this now. At startup I see if smartdrv is installed, and
if so I save a table of what drives has write-behind cache activated,
and then turn it off for those drives. At exit, I turn it back on for
those drives. It seems to work well! Thanks for the tip.
Does anyone know If it's OK to just turn the write-cache off, or should
I tell smartdrv to flush it's cache first? (I assume it does so
itself...)
> > Does it work under Windows too?
>
> I don't know, maybe. Do you have similar problems on Windows, and if
> so, what version(s) of Windows?
I don't have Windows at home, but a friend of mine has tested my program
on a couple of windows versions. It runs on 95 and 98, but with similar
problems. On XP it just hangs almost right away.
/Jonatan -=( http://kymatica.com )=-
- Raw text -