Porting GAP to a new operating system should not be very difficult. However, GAP expects some features from the operating system and the compiler and porting GAP to a system or with a compiler that do not have those features may prove very difficult.
The design of GAP makes it quite portable. GAP consists of a small kernel written in the programming language C and a large library written in the programming language provided by the GAP kernel, which is also called GAP.
Once the kernel has been ported, the library poses no additional problem, because all those functions only need the kernel to work, they need no additional support from the environment.
The kernel itself is separated into a large part that is largely operating system and compiler independent, and one file that contains all the operating system and compiler dependent functions. Usually only this file must be modified to port GAP to a new operating system.
Now lets take a look at the minimal support that GAP needs from the operating system and the machine.
First of all you need enough filespace. The kernel sources and the object files need between 3.5 MByte and 4 MByte, depending on the size of object files produced by your compiler. The library takes up an additional 4.8 MBytes, and the online documentation also needs 4 MByte. So you need about 13 MByte of available filespace, for example on a harddisk.
Next you need enough main memory in your computer. The size of the GAP kernel varies between different machine, with as little as 300 KByte (compiled with GNU C on an Atari ST) and as much as 600 KByte (compiled with UNIX cc on a HP 9000/800). Add to that the fact the library of functions that GAP loads takes up another 1.5 MByte. So it is clear that at least 4 MByte of main memory are required to do any serious work with GAP.
Note that this implies that there is no point in trying to port GAP to plain MS-DOS running on IBM PCs and compatibles. The version of GAP for IBM PC compatibles that we provide runs on machines with the Intel 80386, Intel 80486, Pentium or Pentium Pro processor under extended DOS in protected 32 bit mode. (This is also necessary, because, as mentioned below, GAP wants to view its memory as a large flat address space.)
Next lets turn to the requirements for the C compiler and its library.
As was already mentioned, the GAP kernel is written in the C language. We have tried to use as few features of the C language as possible. GAP has been compiled without problems with compilers that adhere to the old definition from Kernighan and Ritchie, and with compilers that adhere to the new definition from the ANSI-C standard.
However, it is probably necessary that the compiler has a default integer
size of 32 bits, i.e.,
sizeof(int) should be 4 not 2. It may be
possible to fix all the places where 32 bit
ints are assumed, but we
assume that it will be easier to get a 32 bit compiler. In particular, it
is not possible to run GAP version 3 on machines with 64 bit integers
or 64 bit pointers. This will be corrected in version 4.
The most critical aspect probably is that the GAP kernel needs a flat address space. There are especially two systems where this is a problem.
The first is MS-DOS with its segments. As was already mentioned above, we circumvent this by using an extended DOS in protected 32 bit mode on PC compatibles with an Intel 386 or Intel 486 processor.
The other system is the Macintosh. On the Macintosh the operating system wants to deal out the memory only in small chunks, and also wants programs to allow it to move those chunks to the disk temporarily. This is because Apple wanted to support programs that used quite some memory on its initial Macs, which had only 512 KByte of memory, without true virtual memory support. Thus they forced the application programs to simulate virtual memory. GAP does not do this. Probably the best way to deal with that is to allocate as much memory as one can get in one large chunk, while leaving enough memory free for the operating system, and to lock this chunk in memory. Such behaviour is considered uncooperative, but it is the best GAP can do without a major rewrite.
The two points mentioned above are necessary, because most parts of
GAP depend on those features. All other dependencies on the operating
system or compiler should be separated in one special file which is
system file. When you port GAP to a new operating
system, you probably have to create a new
system file. You should
however look through the
system.c file that we supply and take as much
code from them as possible. Currently
system.c supports Berkeley UNIX,
System V UNIX, IBM PC compatibles under MS-DOS with the DJGPP compiler,
and the Atari ST under TOS with the GNU C compiler.
system file contains the following functions.
First file input and output. The functions used by the three system
files mentioned above are
are pretty standard, and in fact are in the ANSI C standard library. The
only thing that may be necessary is to make sure that files are opened in
text mode. However, the most important transformation applied in text
mode seems to be to replace the end of line sequence newline-return,
used in some operating systems, with a single newline, used in C.
However, since GAP treats newline and return both as whitespaces
even this is not absolutely necessary.
Second you need character oriented input from the keyboard and to the screen. This is not absolutely necessary, you can use the line oriented input and output described above. However, if you want the history and the command line editing, GAP must be able to read every single character as the user types it without echo, and also must be able to put single characters to the screen. Reading characters unblocked and without echo is very system dependent.
Third you need a way to detect if the user typed ctr-
C to interrupt
an ongoing computation in GAP. Again this is not absolutely
necessary, you can do without. However if you want to be able to
interrupt computations, GAP must be able to receive the interrupt.
This can be done in two ways. Under UNIX you can catch the signal that
is generated if the user types ctr-
SIGINT). Under other
operating systems that do not support such signals you can poll the input
stream at regular intervals and simply look for ctr-
Fourth you need a way to find out how long GAP has been running. Again this is not absolutely necessary. You can simply always return 0, fooling GAP into thinking that it is extremely fast. However if you want timing statistics, GAP must be able to find out how much CPU time it has spent.
The last and most important function is the function to allocate memory
for GAP. GAP assumes that it can allocate the initial workspace
with the function
SyGetmem and expand this workspace on demand with
further calls to
SyGetmem. The memory allocated by consecutive calls
SyGetmem must be adjacent, because GAP wants to manage a single
large block of memory. Usually this can be done with the C library
sbrk. If this does not work, you can define a large static
array in the
system file and return this on the first call to
SyGetmem and return 0 on subsequent calls to indicate that this array
cannot dynamically be expanded.
Previous Up Top