[comp.os.os2.programmer] Large data areas

cur022%cluster@ukc.ac.uk (Bob Eager) (12/14/90)

I have a program that currently runs under MS-DOS. It is a large code, large
data model; around 100K of code and 300K of data. It allocates the data area
using a large malloc call (I forget the function name) during initialisation.

I would like to port this program to OS/2 1.2/1.3. The fact that OS/2 runs in
protected mode means that it is difficult to have any data area greater than
64K in size unless you do a lot of work. The DosAlloc call and friends will
give you memory, but if you want more than 64K then the program has to be
aware of the 64K boundaries and apply the segment/selector increment obtainable
from the system. All of these problems are confirmed by the fact that I can't
see any C library function for getting large data areas (I can't see how it
could be done).

This is a tough one; does the net have any ideas? I have Zortech C/C++ 2.1
and I also have Microsoft C version 6. I don't mind which I use.....
-------------------------+-------------------------------------------------
Bob Eager                | University of Kent at Canterbury
                         | +44 227 764000 ext 7589
-------------------------+-------------------------------------------------

rommel@lan.informatik.tu-muenchen.dbp.de (Kai-Uwe Rommel) (12/17/90)

In article <21520.2768d47d@cluster@ukc.ac.uk> cur022%cluster@ukc.ac.uk (Bob Eager) writes:
>protected mode means that it is difficult to have any data area greater than
>64K in size unless you do a lot of work. The DosAlloc call and friends will
>give you memory, but if you want more than 64K then the program has to be
>aware of the 64K boundaries and apply the segment/selector increment obtainable
>from the system. All of these problems are confirmed by the fact that I can't
>see any C library function for getting large data areas (I can't see how it
>could be done).
>
>This is a tough one; does the net have any ideas? I have Zortech C/C++ 2.1
>and I also have Microsoft C version 6. I don't mind which I use.....

If you have MS C 6.0, you can use halloc() and hfree() together with
your pointers declared as _huge (please see manual for more detailed
description). It works fine. I used this to get GNU diff running to diff
two files of ~800k each (giving a total memory usage of about 3MB).
Don't forget to use warning level 3.

Kai Uwe Rommel

--
/* Kai Uwe Rommel, Munich ----- rommel@lan.informatik.tu-muenchen.dbp.de */

DOS ... is still a real mode only non-reentrant interrupt
handler, and always will be.                -Russell Williams (MS)

db3l@ibm.com (David Bolen) (12/18/90)

In article <21520.2768d47d@cluster@ukc.ac.uk> cur022%cluster@ukc.ac.uk (Bob Eager) writes:

>I have a program that currently runs under MS-DOS. It is a large code, large
>data model; around 100K of code and 300K of data. It allocates the data area
>using a large malloc call (I forget the function name) during initialisation.

Is that 300K of data all one piece?  If so, I would expect that the program
must be doing a halloc() (huge alloc) function call to get anything bigger
than 64K in one chunk.  Or are you handling the 64K crossovers manually?

>I would like to port this program to OS/2 1.2/1.3. The fact that OS/2 runs in
>protected mode means that it is difficult to have any data area greater than
>64K in size unless you do a lot of work. 

Huh?  It's certainly no harder than under DOS, and because of the larger 
memory space available, I think it's much better.  Although you do still have
to worry about crossing each 64K border, OS/2 provides support for both
allocating the memory (DosAllocHuge), and for determining how to update the
segment value when crossing a 64K border (DosGetHugeShift).

>                                          The DosAlloc call and friends will
>give you memory, but if you want more than 64K then the program has to be
>aware of the 64K boundaries and apply the segment/selector increment
>obtainable from the system. 

True - but you have to do the same sort of thing under DOS.  You can't just
continually increment a pointer through more than 64K under DOS - you have to
either adjust the segment after each operation, or when you hit the 64K
boundary, or the offset value will wrap back to the beginning of the segment.
In fact, things are normally a bit more efficient under OS/2 when using C
compilers, since instead of normalizing pointers after every operation, they
only have to worry about cases where the pointer overflows into the next (or
underflows into the previous) segment.  Not having analyzed the compiler
output I can't be sure, but I expect an OS/2 program compares the pointer
after each arithmetic operation, but only adjusts it occasionally, rather
than under DOS where the pointer is actually normalized after each operation.

>All of these problems are confirmed by the fact that I can't
>see any C library function for getting large data areas (I can't see how it
>could be done).
>
>This is a tough one; does the net have any ideas? I have Zortech C/C++ 2.1
>and I also have Microsoft C version 6. I don't mind which I use.....

I'm not sure about Zortech, but if you have a version supporting OS/2
development it must have support similar to MSC 6 (as does 5.1).  For example,
in MSC 6, it's easy - just use halloc() to allocate as much memory as you
want (well, OS/2 will only support 16MB), and then just access it as you
would any other memory allocated in your C program.

You will need to remember to declare your pointer variables that access
the memory with the modifier "huge", but you should have already been doing
that under DOS (unless you were handling the large memory yourself and
not letting the C compiler do it).

If you had been doing it yourself under DOS, then all you need to do is
to call DosGetHugeShift when your program starts to determine what to shift
the segment by each time you cross a 64K boundary.  Then, use DosAllocHuge
or the C function halloc to allocate the memory.  When crossing a border,
adjust the segment of your pointer using the value DosGetHugeShift returned,
and everything will be fine.  Since you've got to be doing something similar
under DOS, this shouldn't be too much of a change to your code.

Although you still need to worry about 64K boundaries (since OS/2 1.x is
still really a 286 system - OS/2 2.0 will get rid of this stuff), I think
OS/2 is easier to use for large memory allocation, especially since you
can now ask for several megabytes if you wish in a single allocation.

--
-- David
--
/-----------------------------------------------------------------------\
 \                             David Bolen                             /
  |    Laboratory Automation, IBM Thomas J. Watson Research Center    |
 /              P.O. Box 218, Yorktown Heights, NY  10598              \
| - - - - - - - - - - - -  M i t h r a n d i r  - - - - - - - - - - - - |
| Internet : db3l@ibm.com                    | Bitnet : db3l@yktvmv     |
| Usenet   : uunet!bywater!arnor!larios!db3l | Phone  : (914) 945-1940  |
\-----------------------------------------------------------------------/