[comp.sys.handhelds] HP 48 Faster PGDIR

akcs.joehorn@hpcvbbs.UUCP (Joseph K. Horn) (06/06/91)

FPGDIR, a FAST PGDIR, by Joseph K Horn.  Makes PGDIR obsolete.

When you use PGDIR on a very large directory, it can take a long time
to finish.  For example, I just used Donnelly's XTIME function to time
PGDIR on a big directory, and it took a painful 50 seconds!

Bill Wickes explains why in his excellent book, "HP 48 Insights":

     "PGDIR removes a directory specified by name.  It does
      this by recursively executing CLVAR and PURGE recursively
      on each subdirectory until the original directory is
      empty.  (This process can take a relatively long time if
      the directory is large.)"  [Part I, page 96]

Guess what!  There's a better way!

Those of you with HP-41CX's will remember the CLRALMS command that
cleared all the alarms out.  If you had a lot of alarms, it took a
long time to finish, because it looped through the alarm buffer
clearing each one individually.  But a much better way was to treat
the entire buffer as one object, and clear it in one fell swoop.
This was possible with the buffer clearing functions available in
several plug-in ROMs.  For example, with the Extended-IL ROM, just
execute 10 CLRBUF, and instantly the entire alarm buffer gets
cleared, no matter how large it is.

It turns out that there is a similar trick for purging directories
on the HP 48.  Rather than painfully looping through them, clearing
their contents, we can treat the whole thing as a single object and
PURGE it in one fell swoop.

Here's the trick.  The HP 48 Owner's Manual says:

     "Once a directory is empty, you can purge it like any
      other variable -- put its name on the stack and execute
      PURGE."  [Volume 1, page 123]

But "empty" means "when VARS == { }".  And VARS == { } when all
the vars are "hidden" behind a null-named object (see NULLNAME.DOC
on Goodies Disk #1).

So the quick way to purge a directory is:

(1) Put its name on the stack;
(2) Get into that directory: DUP EVAL;
(3) Unhide everything (just in case): '' PURGE;
(4) Hide all its vars: 0 '' STO;
(5) Go back to the parent directory: UPDIR;
(6) Purge the "empty" directory: PURGE.

This process is automated by the following replacement for PGDIR:

---------------------< FPGDIR >---------------------------------
%%HP:T(1);
\<<
    IF DUP TYPE 6 ==
    THEN
      IF DUP VTYPE -1 ==
      THEN DROP
      ELSE
        IF DUP VTYPE 15 ==
        THEN DUP EVAL 0 # 15777h SYSEVAL DUP PURGE STO UPDIR PURGE
        ELSE 515 DOERR
        END
      END
    ELSE 514 DOERR
    END
\>>
----------------------------------------------------------------

Except for its improved speed, its action is exactly like PGDIR.
It even generates the same error messages as PGDIR in case of bad
arguments.  Nonexistent names simply get dropped (like PGDIR does).

To use: place name of directory on stack, and run it.

It does full argument type checking, so it should be idiot proof.

I keep it assigned to my blue-shifted DEL key.  That way it takes only
three keystrokes to delete a directory (tic, menu, FPGDIR).

It should be in "system RPL" ... but that's left as an exercise for
the reader.  :-)

--  Joseph K Horn  --  Peripheral Vision, Ltd.  --

billw@hpcvra.cv.hp.com. (William C Wickes) (06/07/91)

An extra benefit of Joseph's method is that it can not only blow away a
directory instantly, but it can also blow away everything in main RAM
at no extra charge.

> Except for its improved speed, its action is exactly like PGDIR.

Not quite.  PGDIR is safe.

In my excellent book I explained what PGDIR does, not WHY it does it.
Guess what!  There isn't a better way!  What? you mean there's a
reason that PGDIR goes through all that agony?  Well, yes: directories
are not composite objects, and thus a directory in temporary memory,
such as might be created by PURGE, must not contain referenced
objects.  Garbage collection is doomed by such references, so PGDIR's
labor is to remove the directory without leaving any references to any
of its innards.  PURGE doesn't bother with such niceties, so it's not
allowed to handle directories.  Fooling it with null-named variables
is courting disaster.  FPGDIR may work safely most of the time if you
execute a system halt (ON-C) first, but even that's not 100%
bulletproof.

In case the above is too subtle for anyone, just take it that using FPGDIR
(i.e. creating a null-named variable, then purging a directory) is NOT
a good thing to do.

Bill Wickes
HP Corvallis

akcs.joehorn@hpcvbbs.UUCP (Joseph K. Horn) (06/07/91)

Bill Wickes writes that Joe Horn's FPGDIR is too dangerous to use.

Please post an example of how to lose memory with its use.  I've tried,
and haven't been able to.  Thanx!

-- Joe Horn --

billw@hpcvra.cv.hp.com. (William C Wickes) (06/08/91)

Joe Horn requests:

> Please post an example of how to lose memory with its use.  I've tried,
> and haven't been able to.

Using FPGDIR gives the 48 a chance to execute code at a random
address; what will actually happen is hard to predict--most of the
time you just get a system halt, but you can get Memory Clear (it's
just like executing SYSEVAL with random addresses).  The easiest way
to see the danger is to recall some objects from a directory you are
going to purge, then execute FPGDIR.  Everything looks fine, but now execute
MEM and see your recalled objects turn to Externals.  Try executing
one, if you're brave.  In a running program, of course, this can be
disastrous--one example is to insert a MEM into FPGDIR after the
directory PURGE, then use FPGDIR to purge the subdirectory that
contains FPGDIR.  I tried this on my HP48 (with everything archived,
of course), and got a system halt.  Another way is to use FPGDIR to
purge a directory containing a suspended program, then execute MEM and
CONT.  (The use of MEM in these examples forces a garbage collection,
which otherwise might happen most anytime, like a ticking time bomb.)

> Thanx!

Yer welcome!

Bill Wickes
HP Corvallis

akcs.joehorn@hpcvbbs.UUCP (Joseph K. Horn) (06/08/91)

Bill Wickes writes that running my FPGDIR after recalling objects from
the target directory to the stack can cause problems.

Wow!  That's for sure!  I just tried it, and the very first attempt
tanked everything in the machine.

Rats.  The moral here is twofold:

(1) The obvious: don't use FPGDIR unless you KNOW FOR SURE that there are
no references to objects that will be left floating in limbo.

(2) Less obvious: Be Careful When You Hide Objects In Directories!  Many
articles and programs about "hiding" things have floated down this
bitstream, and not once did anybody mention that hiding things in
directories can send the 48 out to lunch.  But if ALL the items in a
directory are hidden, it's an accident waiting to happen.  Because then
simply PURGEing the directory (if there are any memory references to its
contents) will cause problems at the next garbage collection.

The first moral is worded with "unless" because the situation is exactly
the same for the new 256K and 512K bankswitched cards now available for
the 48.  I just played with a 512K card tonight at the 48 Club meeting in
L.A., and it has a BANKN function that allows you to bank switch WITHOUT
PERFORMING A SYSTEM HALT.  The owner's manual clearly states that doing
this while there are any memory references to objects in the bank being
switched out will "at best cause unpredictable results."  The reason this
is so is the same as the reason that FPGDIR is dangerous.  If Tripod can
sell an item with functionality that's dangerous to use and assumes that
the user takes proper precautions, then I hope I can give away FPGDIR for
free with the same danger and assumptions.

What scares me, however, is the second moral.  People are hiding things
gleefully, without any idea that Memory Clear awaits them if they don't
know the pitfalls of PURGE on directories whose contents are all hidden.

EduCALC Goodies Disk #5 will, of course, have all this documented,
hopefully to make up for the blissful endorsement of using null-named
objects that has been on previous Goodies Disks.

Thanx, Bill, for warning us of the dangers here, before my "wonderful new
discovery" (*sigh*) proliferated too far.

-- a crestfallen jkh --

peraino@gmuvax.gmu.edu (06/10/91)

> 
>Bill Wickes writes that running my FPGDIR after recalling objects from
>the target directory to the stack can cause problems.
> 
>Wow!  That's for sure!  I just tried it, and the very first attempt
>tanked everything in the machine.
> 
>Rats.  The moral here is twofold:
 
     Instead of all the caveats, I would think that the safe thing to
do is forget FPGDIR and use the slower, safer method. After all, how often
would you really do this that the speed is such a bother?

     Sorry it didn't work out, but thanx Joe, for all your efforts.

And another thanx to Dr. Wickes for taking the time to warn users of
a potentially dangerous situation. Without your warning, some users would
have been bitten, and Joe would have probably spent hours trying to find
the problem.
 
>-- a crestfallen jkh --

Keep up the good work.


peraino@gmuvax.gmu.edu