Date: Fri, 18 Aug 95 21:53 MDT From: mat AT ardi DOT com (Mat Hostetter) To: gantose AT lerc DOT nasa DOT gov (Dave Gantose) Subject: Re: Please define "locking" Newsgroups: comp.os.msdos.djgpp References: <412kkg$s0p AT sulawesi DOT lerc DOT nasa DOT gov> Cc: djgpp AT sun DOT soe DOT clarkson DOT edu >>>>> "Dave" == Dave Gantose writes: Dave> Anyway, I've noticed that several recent posts about Dave> interrupts (dpmi, go32, etc.) have talked about "locking" Dave> parts of code, writing the interrupt handlers in GAS so as Dave> to handle the locking better, etc. What does this mean? Dave> And, how is it related to "paging"--another subject I know Dave> little about? Like I said above, I wrote a couple generally Dave> successful interrupt routines without knowing this, and I Dave> wonder if they are just accidents waiting to happen? I've written DPMI interrupt handlers that properly lock memory. Here's a quick, imprecise oversimplification of the issues involved (off the top of my head). Since I'm not sure how much you know, and how much various people reading this post know, I'll probably explain more than I need to. But too much is always better than not enough, eh? :-) Often, programs require more memory than the system has available as physical RAM. One solution is to use hard drive space for "virtual memory". This is what DPMI providers and go32 do for you seamlessly. They give your program the illusion that it has lots of memory available, and they worry about the specifics of how to make hard drive space look like extra RAM. In case I explained that badly, let's say you have 4M of free RAM, and your program uses 6M. What will happen is that at any given time, 2M of that memory will be stored on disk, and the other 4M will be in RAM. When your program tries to access memory actually stored the hard drive, that access causes a "page fault". This is magically handled for you by the DPMI provider (or go32). Since all of your RAM is busy, the DPMI provider moves some old 4K "page" lying around in RAM to the hard disk to make room, and moves the 4K "page" containing the requested byte back into RAM where it belongs. The memory access is retried, and this time it works. So "paging" is the process of moving RAM to disk and vice versa to provide programs with the illusion of more memory than is physically available. It's slow. Since paging requires disk accesses, it requires DOS calls. Unfortunately, DOS isn't reentrant! So let's say your program is executing a DOS call for some reason, and an interrupt comes in. The DOS call is temporarily interrupted, and your interrupt handler is called. But let's say that your interrupt handler accesses memory that has been "paged out". This causes a page fault, which calls DOS to grab the byte from disk, but DOS is already busy! So your program might crash, your machine might reboot, etc. Another scenario is that the page fault handler calls DOS, and DOS enables interrupts inside your interrupt handler when you're not expecting them to be enabled. To solve this problem, programmers "lock down" critical memory. When you lock memory, you tell the DPMI provider to *never* page those bytes out to disk. They will always be in RAM. You need to lock every single byte that can get touched at interrupt time: code, data, and stack (although DPMI provides you with a locked, 4K interrupt stack by default). Unfortunately, the wrappers allocated by the _go32_dpmi_* functions are not locked, so it is dangerous to use them in a low-memory situation. I ended up writing my own interrupt handlers and locking their memory myself. If you want robust interrupts, I strongly suggest you use djgpp V2. V1.x had some serious interrupt problems, but V2 is rock solid if you play by the rules. Unfortunately, those rules are tricky. I hope this helps. Good luck! -Mat