LBAcache devel BUGFIX and improved release

Eric Auer <[email protected]> Mon, 11 Nov 2002 09:44:07 +0100 (MET)
Newsgroups gmane.os.freedos.devel,gmane.spam.detected
Message-ID <[email protected]>
Hi, I have to re-release LBAcache-devel for some bugfixes.

First bug: Probably due to a kernel bug. When I try to resize
a MCB, the MCB just VANISHES !?!?   

The issue: When LBAcache STOP detects that an instance cannot be removed
completely (because it cannot reconstruct the interrupt vectors), it tries
to reduce the size so that only the "interrupt chaining" part stays in RAM.
However, when this happens, with kernel 2027 in Dosemu the complete
instance is released from RAM, which will VERY soon crash your system at
the time that the next disk access occurs :-(. Luckily it happens ONLY if
you load other disk drivers after LBAcache or load TWO instances of LBAcache.

Second bug: You cannot redirect output in a nice way. Related to a kernel bug
in version 2027, which has already been fixed. See my other mail. However,
THIS version of LBAcache has been compiled with:

nasm -DMCBBUG -DREDIRBUG -o lbacache.sys lbacache.asm
cat comcache.bin lbacache.sys > lbacache.com

The "MCBBUG" and "REDIRBUG" defines activate workarounds for the two bugs
mentioned above.



Other, non kernel related bug fixes and improvements:

The STAK option has been removed. As STAK is needed to run with FreeDOS
and activating it only takes 0.5k of RAM, it is now permanently enabled.
For MS DOS, it would probably not have been necessary, but indeed better
to enable it. This is a reaction to a suggestion of Tom.

When you select BUF 0, you now get 30 MB cache. 33 MB were actually too
big to work. However, I recommend that you do not use this. Use BUF nn
instead, nn being the number of 0.25 MB units of cache size in XMS.

The help message is now shorter. Generally, output takes less lines.

The statistics page (lbacache INFO) now uses two columns, which makes
it much shorter. I also fixed a stupid bug that made the hit percentage
statistics display completely wrong values.

I have also cleaned up the code a bit and removed some "bug potential"
from it. Just a bit.

Open issue:

  I am not satisfied with the slot allocating algorithm. Even when I use
  25 megs of XMS, new sectors cause old sectors to leave the cache. This
  causes efficiency problems. So I will change that, to use MORE CPU time
  while keeping LESS of the allocated XMS cache idle :-).

My current plan is to re-introduce scanning for free slots in BINSEL.ASM:
Currently, every sector on disk has a single "home" in XMS. As there are
more sectors than XMS slots, caching many sectors can cause slots to be
full long before the cache itself is full. So I will allow sectors to sit
down in XMS in a more flexible way. This will take more CPU but CPU is
cheap compared to disk accesses. That way I hope to make better use of the
allocated amount of XMS.

Call for BINSEL help:

Feel free to design a really good algorithm for BINSEL. You may not change
the table format nor the interface. The only functions that you should
change are (feel free to change hashme, it is only used internally):

findbin - input: LBA sector number EAX, drive DL
          output: XMS slot where the sector is stored in AX, or CARRY set.
          The table uses ONE entry for EIGHT consecutive sector numbers,
          but you are supposed to return a linear number (which is then
          8*tableEntry + SubEntryNumber).

newbin - input: LBA sector number in EAX, drive in DL
         output: XMS slot as with findbin. However, this function inserts
                 the information about sector/drive into the table.
         A SubTableEntry must have the same sector number and drive as the
         main table entry, only that the lower bits are always equal to the
         sub entry number.
         When newbin finds a slot already in use but not suitable to hold
         the new sector as well, it must free the slot or find another free
         slot. You can free whichever slot you want, as writes are never
         delayed in LBAcache. However, the more slots you free the less
         performance you get from LBAcache!

Table format is simple:
struct cachetable {
  unsigned long int sectorNumber; /* 3 lower bits are set to 0 */
  unsigned char driveNumber /* BIOS drive number, like 0, 1, 0x80, ... */
  ; unsigned char LRU; /* free for your statistical use */
  unsigned int /* 16bit */ bitMask; /* If bit N is set, then sector
    sectorNumber+N can be found at XMS slot tableIndex*8 + N, obvious... */
}

So each entry is 8 bytes long and holds information about 8 sectors. You
can change this in the range 1..16 sectors, but please leave it at 4 or 8.
You should use BINSHR, BINMASK and BINBITS and BINTABFORM to adjust this.

Some algorithms from the past:
- always use a new slot. If all slots are full, search for the slot that
  was touched by findbin and newbin least often. May take lots of CPU.
- always use a slot that selected by slot number = sector number modulo
  number of slots. Bad performance as slots may be discarded (in packages
  of up to 8, you can only discard whole 8 byte entries, if you re-use a
  sub-entry you must discard all other sub entries of the affected main
  entry!) long before all slots are filled. This is the current algorithm!
- a mix of both algorithms: A new sector will end up in the range of
  N = sector number modulo (number of slots / 64) ... N + 63.
  So at most 63 slot entries have to be searched (actually, 8 main
  table entries only), but there can be up to 8 different 8-sector-
  ranges in use for each of (number of slots / 64) different subsets
  of all sectors. I think this mixed approach is promising, what do you
  think??? Determining a good choice AMONG the 8 checked main entries is
  however as hard as doing the first "pick least used" algorithm, just for
  a small sub-table, so it should still be tens to hundreds of times faster
  than the raw "pick least used of whole table" approach.

Eric