Board index » delphi » allocating memory for exec

allocating memory for exec

Quote
> i have a 276 kb exe called rcomms which i call
> using exec from my 237 kb application

> problem being is that rcomms unexpectedly terminates
> when i call it..though it runs fine by itself when i call it
> from a dos command line without my app being present.

> i have $m 5000 , 20000  65500

> is there some sort of formala/rule of thumb to go by when
> setting the $m?

   Formula, no.  You have to know what your program is doing (allocating
dynamic data, using nesting/recursion, the amount of local data declared
in subprograms, etc.  All these affect the parameters you must set in the
$M.
   In a situation such as yours, I recommend using {$M 8192,0,0} to
start, and see if the program runs - it's about as little as you can
safely run any TP/BP program, so it's a place to start the "trial-
and-error" process you have to apply to this problem.  Of course, if you
_know_ that you'll allocate some Heap, then you should change the
Heap_Max to that value.  In your example, why did you pick those values?  
Did you know those to be the minimum you'll need, or were they guesses?
   Lastly, it's important that you _don't_ execute your program in the
IDE: unless you're using BP7.0, you'll consume a large amount of the
system Heap by running within the IDE.  Always best to compile to Disk
and execute as a DOS command.
   Also, it's useful to insert the code to check DOSError and DOSExitCode
following the Exec call, to see what error was returned...
 

Re:allocating memory for exec


hello (again)
i have a 276 kb exe called rcomms which i call
using exec from my 237 kb application

problem being is that rcomms unexpectedly terminates
when i call it..though it runs fine by itself when i call it
from a dos command line without my app being present.

i have $m 5000 , 20000  65500

is there some sort of formala/rule of thumb to go by when
setting the $m?

Regards
Bryce Burrows

Re:allocating memory for exec


In article <T5jGDEAxWn40E...@mtf.co.nz>,
Bryce Burrows  <br...@mtf.ZEROSPAMco.nz> wrote:

Quote
>hello (again)
>i have a 276 kb exe called rcomms which i call
>using exec from my 237 kb application

>problem being is that rcomms unexpectedly terminates
>when i call it..though it runs fine by itself when i call it
>from a dos command line without my app being present.

>i have $m 5000 , 20000  65500

>is there some sort of formala/rule of thumb to go by when
>setting the $m?

Get rid of that and use the following:

Unit Xheap;

Interface

uses dos;

{$ifdef msdos }

type string128=string[128];

procedure exec(const com,par:string128);
Function MaxProg:word;  { kilobytes }

Const Swapstack{:boolean}=true;    { Change if you wish }
Const UseXMS{:boolean}=true;

{$endif}

Const envsize:word=1000;

Procedure Shell(const st:string);
Procedure Push;

Implementation

{$ifdef msdos}

{-------------------------- XMS routines -----------------------}

Var Handle:word;
    xmsentry:pointer;

Procedure GetXMSentry;
var rg:registers;
begin
  fillchar(rg,sizeof(rg),0);
  rg.ax:=$4300;
  intr($2f,rg);
  if rg.al<>$80 then xmsentry:=nil
   else begin
      rg.ax:=$4310;
      intr($2f,rg);
      xmsentry:=ptr(rg.es,rg.bx);
    End;
End;

Function FreeXms:word;
begin
  if Xmsentry=Nil then FreeXms:=0
    else asm
         mov ah,8;
         call xmsentry
         mov @result,ax
         end;
End;

Function XInit(Kb:word):byte;
var h:word;
begin
  h:=0;
  if xmsentry=nil then Xinit:=255
    else
     asm
           mov dx,kb
           mov ah,9
           call XmsEntry
           cmp ax,1
           jne @f
           mov @result,0
           mov h,dx
           jmp @ulos
    @f:    mov @result,bl

    @ulos: end;
  handle:=h;
End;

Procedure XWrite(p:pointer; count:longint);
type  emm=record
            count:longint;
            zero:word;
            P:pointer;
            handle:word;
            Pos:longint;
          End;
const e:emm=(count:0;zero:0;p:nil;handle:0;pos:0);
begin
  e.count:=count;
  e.p:=p;
  e.handle:=handle;
  asm
   mov ah,$b
   mov si,offset e
   call XmsEntry
  end;
End;

Procedure XRead(p:pointer; count:longint);
type  emm=record
            count:longint;
            handle:word;
            Pos:longint;
            zero:word;
            P:pointer;
          End;
const e:emm=(count:0;handle:0;pos:0;zero:0;p:nil);
begin
  e.count:=count;
  e.p:=p;
  e.handle:=handle;
  asm
   mov ah,$b
   mov si,offset e
   call XmsEntry
  end;
End;

procedure XDone; assembler;
  asm
  mov dx,handle
  mov ah,$a
  call xmsentry
  end;

{-----------------------  End XMS routines ----------------------- }

var xmsinuse:boolean;
    len:longint; { no of bytes in XMS }
    ints:word;   { segment address }

Type Words=Record
             lo,hi:Word;
           End;

     wp=^word;
     pp=^longint;

function topmem:word;
begin
  topmem:=wp(ptr(prefixseg,2))^;
End;

Function p2i(p:pointer):longint;
begin
  p2i:=longint(words(p).hi) shl 4+words(p).lo;
End;

var sporigin:word;
    startptr:pointer;  { Start of the swapped area }

procedure HeapOut;
var rg:registers;
    endPtr:pointer;    { end of the program }
    startaddr:longint;
    fx:word;
Begin
  ints:=0;
  {$ifdef test}
  writeln('HeaOut in');
  {$endif}
  if swapstack and (p2i(ptr(sseg,sporigin))<p2i(heaporg))
     then startptr:=ptr(sseg,sporigin)
     else startptr:=heaporg;

  inc(words(startptr).hi,words(startptr).lo shr 4);
  words(startptr).lo:=words(startptr).lo and 15;

  len:=p2i(heapptr)-p2i(startptr);
  if usexms and (xinit((len+1023) shr 10)=0) then begin
     xwrite(startptr,len);
     xmsinuse:=true;                           { Write the heap into XMS }
     endPtr:=startptr;
  End
  else begin
     if usexms then fx:=freexms shr 10      { lets get what XMS we can get }
               else fx:=0;
     if (fx>0) and (xinit(fx)=0) then begin
        len:=longint(fx)*1024;
        startaddr:=p2i(heapptr)-len;
        words(startptr).hi:=startaddr shr 4;
        words(startptr).lo:=startaddr and 15;
        xwrite(startptr,len);
        xmsinuse:=true;
        endptr:=startptr;
     end else begin
       xmsinuse:=false;
       EndPtr:=HeapPtr;
     End;
  End;
  rg.ah:=$4a;
  rg.bx:=words(Endptr).hi-prefixseg+65;
  if rg.bx>=topmem-prefixseg then exit;   { No reduction }

  ints:=words(endptr).hi+1;
  rg.es:=prefixseg;
  MsDos(rg);
  if rg.flags and fcarry>0 then begin
     if xmsinuse then xdone;
     Runerror(250);
  End;

  move(ptr(0,0)^,ptr(ints,0)^,1024);
  {$ifdef test}
  writeln('HeaOut out');
  {$endif}

End;

Procedure HeapIn;
var rg:registers;
    done:boolean;
    i:integer;
Begin
  {$ifdef test}
  writeln('HeaIn in');
  {$endif}

  if ints>0 then
     asm
     push ds
     mov ds,ints
     xor si,si
     xor di,di
     mov es,di
     mov cx,512

     cld
     cli
     rep movsw
     sti

     pop ds
     end;

  repeat
    {$ifdef test}
    writeln('repeat');
    {$endif}
    done:=true;
    rg.ah:=$4a;
    rg.bx:=topmem-prefixseg;
    rg.es:=prefixseg;
    MsDos(rg);
    if rg.flags and fcarry>0 then begin
      done:=false;
      if rg.ax<>8 then begin
         if xmsinuse then xdone;
         Runerror(251);
      End;
      rg.ah:=$49;
      rg.es:=prefixseg+rg.bx+1;
      msdos(rg);
      if rg.flags and fcarry>0 then begin
         if xmsinuse then xdone;
         Runerror(252);
      End;
    End;
  until done;
  if xmsinuse then begin
     xread(startptr,len);
     xdone;
  End;
  {$ifdef test}
  writeln('Heapin Out');
  {$endif}
End;

var spsave:word;

var cm,pr:string128;

procedure exec(const com,par:string128);
begin
  {$ifdef test}
  writeln('exec in');
  {$endif}
  cm:=com;  { one has to copy the strings to the data segment as it is the }
  pr:=par;  { only secure place after heapout }
  spsave:=0;
  if swapstack then begin
     if sptr>2048 then asm mov spsave,sp; mov sp,2048 end;
     sporigin:=sptr+16;
  End;

  heapOut;
  if ints>0 then dos.exec(cm,pr)
            else dos.doserror:=8;
  Heapin;

  if spsave>0 then asm mov sp,spsave end;
  {$ifdef test}
  writeln('exec out');
  {$endif}
End;

var rg:registers absolute cm;

Function MaxProg:word;  { kilobytes }
begin
  {$ifdef test}
  writeln('maxprog in');
  {$endif}

  spsave:=0;
  if swapstack then begin
     if sptr>2048 then asm mov spsave,sp; mov sp,2048 end;
     sporigin:=sptr+16;
  End;

  heapOut;
  if ints>0 then begin
    rg.ah:=$48;
    rg.bx:=736 shl 6;
    msdos(rg);
    if rg.flags and fcarry=0 then runerror(254);
  End
  else rg.bx:=0;
  Heapin;

  if spsave>0 then asm mov sp,spsave end;
  maxProg:=rg.bx shr 6;
  {$ifdef test}
  writeln('maxprog out');
  {$endif}
End;

{$endif}

Function commandparams:string;
var s:string[7];
begin
  if envsize>0 then begin
    str(envsize,s);
    commandparams:=' /e:'+s;
  End
  else commandparams:='';
End;

Procedure Shell(const st:string);
begin
  swapvectors;
  exec(getenv('comspec'),CommandParams+' /c '+st);
  swapvectors;
end;

Procedure Push;
begin
  swapvectors;
  exec(getenv('comspec'),CommandParams);
  swapvectors;
end;

{$ifdef msdos}
begin
 GetXMSEntry;
{$endif}
End.

Osmo

Re:allocating memory for exec


On 11 Feb 1998, Mike Copeland wrote:

Quote
> > i have a 276 kb exe called rcomms which i call
> > using exec from my 237 kb application

> > problem being is that rcomms unexpectedly terminates
> > when i call it..though it runs fine by itself when i call it
> > from a dos command line without my app being present.

> > i have $m 5000 , 20000  65500

> > is there some sort of formala/rule of thumb to go by when
> > setting the $m?

>    Formula, no.  You have to know what your program is doing (allocating
> dynamic data, using nesting/recursion, the amount of local data declared
> in subprograms, etc.  All these affect the parameters you must set in the
> $M.

<snip>

Have a look at the book Turbo Pascal Internals. It has a chapter on how to
make a unit that could swap to disk or EMS all the RAM used by your
program leaving only a stub to reload it back in again when running an
external program. The sources are also on the disk provided. It works a
treat - obviously, don't use it if you have installed any ISR's... Then
you do not have to worry about how much RAM your program uses - you can
leave the default of using all 640Kb...

That book also has some other nice treats - like how to do pre-emptive
multitasking in your own TP programs under DOS.

Regards,
        Antony.

ssu95...@reading.ac.uk
 Author of PowerMOD/2

... There are four kinds of lies:
...   There are lies,
...     Damned lies...
...
...  And party political broadcasts.

[END]

Re:allocating memory for exec


Quote
>i have $m 5000 , 20000  65500

>is there some sort of formala/rule of thumb to go by when
>setting the $m?

would you please be as kind as to try to launch your program after having it
compiled to an exe? Since Pascal itself is Executing your program that
itself executes another prog memory is always a bit short in these cases.

Re:allocating memory for exec


Tony Curtis <ssu95...@reading.ac.uk> napisa3(a) w artykule
<Pine.SOL.3.96.980214200924.19829B-100...@suma3.reading.ac.uk>...

Quote
> On 11 Feb 1998, Mike Copeland wrote:

> > > i have a 276 kb exe called rcomms which i call
> > > using exec from my 237 kb application

> > > problem being is that rcomms unexpectedly terminates
> > > when i call it..though it runs fine by itself when i call it
> > > from a dos command line without my app being present.

> > > i have $m 5000 , 20000  65500

> > > is there some sort of formala/rule of thumb to go by when
> > > setting the $m?

> >    Formula, no.  You have to know what your program is doing
(allocating
> > dynamic data, using nesting/recursion, the amount of local data
declared
> > in subprograms, etc.  All these affect the parameters you must set in
the
> > $M.

> <snip>

> Have a look at the book Turbo Pascal Internals. It has a chapter on how
to
> make a unit that could swap to disk or EMS all the RAM used by your
> program leaving only a stub to reload it back in again when running an
> external program. The sources are also on the disk provided. It works a
> treat - obviously, don't use it if you have installed any ISR's... Then
> you do not have to worry about how much RAM your program uses - you can
> leave the default of using all 640Kb...

> That book also has some other nice treats - like how to do pre-emptive
> multitasking in your own TP programs under DOS.

> Regards,
>    Antony.

> ssu95...@reading.ac.uk
>  Author of PowerMOD/2

> ... There are four kinds of lies:
> ...   There are lies,
> ...     Damned lies...
> ...
> ...  And party political broadcasts.

> [END]

You write that sources are provided for swapping my program into XMS. Do
you know the name?
Is it work under TV?

--
Rafa3 o?y?ski
Varico, Pozna?, Poland
http://www.varico.com
e-mail:rlozyn...@varico.com

Other Threads