[comp.sys.atari.st.tech] Memory deallocation after TSR

rfschaa@cs.vu.nl (Schaaf R F ) (11/29/90)

  I have a problem: I have written a device driver for some virtual
device. It performs some initialisations, then quits by using the
gemdos(49) call (TSR). After a while, when I don't need the driver
anymore I would like to free the memory used up by the driver and
give it back for general use. Is there any way this can be done?

 Richard Schaaf
 rfschaa@cs.vu.nl

apratt@atari.UUCP (Allan Pratt) (11/30/90)

rfschaa@cs.vu.nl (Schaaf R F ) writes:
>  I have a problem: I have written a device driver for some virtual
>device. It performs some initialisations, then quits by using the
>gemdos(49) call (TSR). After a while, when I don't need the driver
>anymore I would like to free the memory used up by the driver and
>give it back for general use. Is there any way this can be done?

> Richard Schaaf
> rfschaa@cs.vu.nl

Hmm... TSR... Terminate and Stay Resident... Sounds pretty permanent to me...
Doesn't say, "Terminate and stick around until I decide to free you..." :-)

You can't free memory which has stayed resident as a result of a TSR. 
It's not even accounted for in the system as "allocated" memory -- it's
been UNHOOKED from the memory management lists.  It's GONE.

============================================
Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt

neil@cs.hw.ac.uk (Neil Forsyth) (12/05/90)

In article <8381@star.cs.vu.nl> rfschaa@cs.vu.nl (Schaaf R F ) writes:
>
>  I have a problem: I have written a device driver for some virtual
>device. It performs some initialisations, then quits by using the
>gemdos(49) call (TSR). After a while, when I don't need the driver
>anymore I would like to free the memory used up by the driver and
>give it back for general use. Is there any way this can be done?

I have had a go at doing this too. I don't think it's possible without
tinkering with the OS pool entries. That of course would be a highly
undocumented thing to do and would result in Allan Pratt slapping your
wrists heavily.

What I want to write is a temporary RAM disk for use under Gulam.
That way I could have a RAM disk while compiling a C program but throw it
away afterwards leaving more memory for the compiled application to play
with. Pure joy! Pure fantasy?

I tried some really weird things like re-executing the TSR using Pexec #4
in the hope that a Pterm instead of Ptermres would blow it away on the second
run. Another good try was for the TSR to Mfree it's own basepage. The results
were either no effect or bomb outs.

Come on Allan, help us out on this one.

> Richard Schaaf
> rfschaa@cs.vu.nl

+----------------------------------------------------------------------------+
! DISCLAIMER:Unless otherwise stated, the above comments are entirely my own !
!                                                                            !
! Neil Forsyth                      JANET:  neil@uk.ac.hw.cs                 !
! Dept. of Computer Science         ARPA:   neil@cs.hw.ac.uk                 !
! Heriot-Watt University            UUCP:   ..!ukc!cs.hw.ac.uk!neil          !
! Edinburgh, Scotland, UK           "That was never 5 minutes!"              !
+----------------------------------------------------------------------------+

fischer-michael@cs.yale.edu (Michael Fischer) (12/07/90)

In article <5208@brahma.cs.hw.ac.uk> neil@cs.hw.ac.uk (Neil Forsyth) writes:
>What I want to write is a temporary RAM disk for use under Gulam.
>That way I could have a RAM disk while compiling a C program but throw it
>away afterwards leaving more memory for the compiled application to play
>with. Pure joy! Pure fantasy?

I wrote such a ramdisk some time ago and use it regularly.  The
ramdisk program consists of two parts: a small resident driver and a
configuration program which allocates and frees memory for the
ramdisk.  To keep the memory from disappearing when the configuration
program exits, I change the current process pointer (a documented
system variable in low memory) to another value before doing the
Malloc and restore it to its old value immediately after.  (I think I
set it to the basepage of the driver program, but I might be using the
basepage of the desktop or some other process that isn't likely to go
away.) This causes Gemdos to think the allocated memory "belongs" to
the driver instead of to the configuration program and hence it won't
be freed automatically when the configuration program terminates. 

This method of allocating persistent memory works under TOS 1.4.
However, I don't think it is officially approved for the user to write
to the current process pointer, so this scheme probably isn't
guaranteed to work under future versions of TOS.  (I also don't recall
whether or not it works under older versions of TOS.) Unfortunately, I
don't know of any way that IS officially sanctioned to allocate and
free resident memory. 

I should point out that another problem one faces is memory
fragmentation.  Memory is allocated and freed in blocks.  If one
allocates blocks A, B, C in that order and then frees block B, there
will be a "hole" in memory between blocks A and C.  Free memory has
now been split into two pieces, the hole and the rest of memory after
block C.  Whether or not the memory in the hole is useful depends on
how big it is and how large the blocks are that are needed in the
future.

-- 
==================================================
| Michael Fischer <fischer-michael@cs.yale.edu>  |
==================================================

apratt@atari.UUCP (Allan Pratt) (12/07/90)

neil@cs.hw.ac.uk (Neil Forsyth) writes:
>In article <8381@star.cs.vu.nl> rfschaa@cs.vu.nl (Schaaf R F ) writes:
>>... quits by using the gemdos(49) call (TSR).
>>... I would like to free the memory used up by the driver ...

>I have had a go at doing this too. I don't think it's possible without
>tinkering with the OS pool entries. That of course would be a highly
>undocumented thing to do and would result in Allan Pratt slapping your
>wrists heavily.
> [...]
>Come on Allan, help us out on this one.

You lose.  You can't Terminate and Stay Resident, then not Stay Resident.
There is no help to give: you asked to stay resident, and you got it.
You'll have to look at some other approach.

============================================
Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt

apratt@atari.UUCP (Allan Pratt) (12/08/90)

fischer-michael@cs.yale.edu (Michael Fischer) writes:
>... I change the current process pointer ...

BOGON ALERT!  This is NOT approved and should NOT be used and will NOT
work in the future and all sorts of bad things!  Please don't do this!
And CERTAINLY don't make anything that does it available for general use.
You are a VERY BAD BOY for doing this.  That variable is only to be used
in really strange cases that real people shouldn't come up against,
and moreover it is stated in the documentation that you can only read
it, not write it.

============================================
Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt

cadp15@vaxa.strath.ac.uk (12/11/90)

In article <5208@brahma.cs.hw.ac.uk>, neil@cs.hw.ac.uk (Neil Forsyth) writes:
> In article <8381@star.cs.vu.nl> rfschaa@cs.vu.nl (Schaaf R F ) writes:
>>
>>  I have a problem: I have written a device driver for some virtual
>>device. It performs some initialisations, then quits by using the
>>gemdos(49) call (TSR). After a while, when I don't need the driver
>>anymore I would like to free the memory used up by the driver and
>>give it back for general use. Is there any way this can be done?
> 
> I have had a go at doing this too. I don't think it's possible without
> tinkering with the OS pool entries. That of course would be a highly
> undocumented thing to do and would result in Allan Pratt slapping your
> wrists heavily.

Distributed a while back was a program to speed up GEM (not Quick ST, the other
one) in a demo version.  It removed itself from memory after a certain amount
of use so its possible...

Sorry I can't remember the name of the demo program :-(
-- 
       The Sorcerer is 'Only visiting this planet' but can be found at:
              (cadx862 @ uk.ac.strathclyde.computer-centre-sun)
                      (cadp15 @ uk.ac.strathclyde.vaxb)

          or second star to the right and straight on 'till morning.

cjr@cs.bham.ac.uk (Chris Ridd <RiddCJ>) (12/11/90)

In article <5208@brahma.cs.hw.ac.uk> neil@cs.hw.ac.uk (Neil Forsyth) writes:
>In article <8381@star.cs.vu.nl> rfschaa@cs.vu.nl (Schaaf R F ) writes:
>>
>>  I have a problem: I have written a device driver for some virtual
>>device. It performs some initialisations, then quits by using the
>>gemdos(49) call (TSR). After a while, when I don't need the driver
>>anymore I would like to free the memory used up by the driver and
>>give it back for general use. Is there any way this can be done?
>
[...deleted...]
>What I want to write is a temporary RAM disk for use under Gulam.
>That way I could have a RAM disk while compiling a C program but throw it
>away afterwards leaving more memory for the compiled application to play
>with. Pure joy! Pure fantasy?

  The latter, I think...  The Lattice C5 manual says something to the
effect that any memory belonging to a process which does a Ptermres is
*removed* from the free-memory pool, and is effectively lost forever
(or until the next reboot, whichever comes first).

  A thought - can you stick the code above phystop, making it
reset-resident, and then move phystop back up again to 'delete' it?
Or do changes to phystop only get noticed on reboots?  I might have
the wrong variable here, but do you all know what I mean?

>
>I tried some really weird things like re-executing the TSR using Pexec #4
>in the hope that a Pterm instead of Ptermres would blow it away on the second
>run. Another good try was for the TSR to Mfree it's own basepage. The results
>were either no effect or bomb outs.
>

  Presumably the Mfree would not be able to re-insert the memory back
into the main 'pool'?

>Come on Allan, help us out on this one.

   Chris

-- Chris Ridd, Computer Science, Birmingham Uni, UK -- RiddCJ@Cs.Bham.Ac.Uk --

"'It's going to look pretty good, then, isn't it,' said War testily, 'the One
Horseman and Three Pedestrians of the Apocralypse.'" - Sourcery

neil@cs.hw.ac.uk (Neil Forsyth) (12/13/90)

In article <1990Dec11.113843.9395@vaxa.strath.ac.uk> cadp15@vaxa.strath.ac.uk
writes:
>Distributed a while back was a program to speed up GEM (not Quick ST, the
>other one) in a demo version.  It removed itself from memory after a certain
>amount of use so its possible...

Possible yes, but legal? I suspect that the memory used by it was still not
available to Malloc.

+----------------------------------------------------------------------------+
! DISCLAIMER:Unless otherwise stated, the above comments are entirely my own !
!                                                                            !
! Neil Forsyth                      JANET:  neil@uk.ac.hw.cs                 !
! Dept. of Computer Science         ARPA:   neil@cs.hw.ac.uk                 !
! Heriot-Watt University            UUCP:   ..!ukc!cs.hw.ac.uk!neil          !
! Edinburgh, Scotland, UK           "That was never 5 minutes!"              !
+----------------------------------------------------------------------------+

72347.2767@CompuServe.COM ("Robert D. Royar, Cratylus Soft") (12/16/90)

One technique is to load no go (seems to work as documented after TOS 1.4).  I
use this technique to load RSXs into my CLI.  They stay in memory until I ask
them to leave.  Each RSX registers with a resident manager that keeps up with
the address of a clean-up routine to call before kicking the program loose. 
The clean-up routine should Mfree() any Malloc()ed memory the RSX requested. 
It should also keep track of Files the RSX openned on its own and and other
variables that must be reset.  One RSX I have is an installable/uninstallable
printer spooler.  Others add to the CLI built-in command set.

Once cleanup is called the resident manager Mfree()s the basepage and the
prog's environment space.  I've been using this technique very successfully for
a few years without problems--except you should be careful about uninstalling
RSXs out of order since Malloc and Mfree lose efficiency then.

BTW RSX==Resident System eXtension (an old CPM acronym).

Robert Royar

Cratylus Educational Software

One thing I forgot in rushing to respond to the thread about deallocating
TSRs was that the RSX scheme I described does not depend on Ptermres().  In
fact if the RSX were to call either of the Pterm()s or Ptermres(), disaster
would ensue.  TOS believes the RSX's parent is the owner of all resources the
RSXs control, and the RSXs run as subroutines of the parent, not as separate
processes.  I don't use "just go" to start an RSX, rather when the RSX loads,
the resident manager computes the starting-instruction address from the
basepage returned by the Pexec() load, no-go call.  That starting address is
an init routine that sets up the RSX internally and registers its "official"
entry and clean-up routines with the resident manager.  For spoolers the init
routine is just a dummy, but for CLI extensions, the entry routine dispatches
that RSX's working code.

As an added benefit to the RSX and to keep RSX size small, the resident
manager installs pointers to some re-entrant routines in an RSX jump table.
In the RSX a function can call strcmp(str1,str2) normally, but the internal
routine is
  _strcmp: jmp _strcmp
The jump is patched up by the resident manager so the call goes into a
routine in the CLI's shared library. This added stuff is not required to make
an RSX scheme work, and would break in an environment where routine's
addresses may change after load, but for most uses on an ST, the jump table
is a real win.  Just being able to write a program that calls all the
standard C string functions and the formatted print functions without their
having to be linked into the executable saves quite a bit in file space,
executable space, and load time.

Robert Royar

rfschaa@cs.vu.nl (Schaaf R F ) (12/18/90)

In article <2767@atari.UUCP> apratt@atari.UUCP (Allan Pratt) writes:
>neil@cs.hw.ac.uk (Neil Forsyth) writes:
>>In article <8381@star.cs.vu.nl> rfschaa@cs.vu.nl (Schaaf R F ) writes:
>>>... quits by using the gemdos(49) call (TSR).
>>>... I would like to free the memory used up by the driver ...
>
>>I have had a go at doing this too. I don't think it's possible without
>>tinkering with the OS pool entries. That of course would be a highly
>>undocumented thing to do and would result in Allan Pratt slapping your
>>wrists heavily.
>> [...]
>>Come on Allan, help us out on this one.
>
>You lose.  You can't Terminate and Stay Resident, then not Stay Resident.
>There is no help to give: you asked to stay resident, and you got it.
>You'll have to look at some other approach.
>
>============================================
>Opinions expressed above do not necessarily	-- Allan Pratt, Atari Corp.
>reflect those of Atari Corp. or anyone else.	  ...ames!atari!apratt

How about the following (is this legal?)
1. Use Pexec to just load the program in memory and save the pointer,
   say 'basepage_pointer', to the basepage
2. Execute the program, again using Pexec. The program then exits
   using Ptermres.
3. When finished perform 'Mfree(basepage_pointer)'

This seems to work, but the memory gets fragmented and I still seem
to lose some memory. Therefore: 1. Is this legal?
                                2. can I recompact the memory so it
				   becomes contiguous?

-------------------------------------------------------------------
Richard Schaaf (rfschaa@cs.vu.nl)

P.S. I will not be at the university for at least 4 weeks, so please
     send any reply via email otherwise the article will probably
     not be available when I return..... THANKS