MAINSAIL System-Specific User's Guides, Chapter 3

previous   next   top   complete contents   complete index   framed top   this page unframed


3. CONF, MAINSAIL Configurator

The MAINSAIL configuration MODULE, CONF, is described in Chapter 6 of the MAINSAIL Utilities User's Guide. In addition to the target-independent commands described therein, all UNIX versions of CONF provide the following additional command:

CONF Command Meaning
UNIXBITS Set UNIX-specific attributes.

3.1. UNIXBITS

This command is used to identify the UNIX flavor to the MAINSAIL runtime system. The standard configuration file automatically defines the value of this parameter correctly for the current version of MAINSAIL on the host system. Unless otherwise specified, this value must be used. If an incorrect UNIXBITS value is given, MAINSAIL may not run at all.

If you maintain your own configuration files, you should obtain the UNIXBITS value from the standard configuration file rather than specifying it in your own file.

3.1.1. Platform-Independent UNIXBITS Bit: $useMalloc

On most platforms, MAINSAIL uses sbrk instead of malloc for memory allocation. However, some C packages that you might link with your bootstrap are incompatible with sbrk and require the use of malloc throughout the program, including when memory is allocated by MAINSAIL.

If you link your bootstrap with a C package that requires that MAINSAIL use malloc, you can set the UNIXBITS bit 'H20 ($useMalloc) when you run CONF; i.e., issue the command:

UNIXBITS =! 'H20

This will force MAINSAIL to use malloc rather than sbrk on those platforms where sbrk is the default.

It is not recommended that you set the $useMalloc bit unless you have to; XIDAK's experience is that allocating with sbrk results in better performance. Furthermore, you may need to adjust the MINSIZETOALLOCATE CONF parameter as described in Section 3.5.

3.2. Flavor-Specific CONF Commands

3.2.1. MAXFOREIGNMEMORYSIZE

MAINSAIL normally requests memory from UNIX by calling either sbrk or malloc. On the RAIX platform and on the HPPA platform, operating system version 9.05 and later, not all of the memory potentially available to a process can be allocated by sbrk or malloc, but the memory can be allocated by other system functions. When all the memory available to sbrk or malloc has been allocated, MAINSAIL will call the other system functions to request memory. However, some MAINSAIL bootstraps are linked with foreign code, which typically requests memory by calling malloc. If MAINSAIL and foreign code both allocate large amounts of memory with malloc and/or sbrk (which typically allocate memory from the same pool), then once the memory available to malloc has all been allocated, the foreign code would be unable to allocate more memory, and the program would probably be unable to continue execution. Since MAINSAIL can request memory in other ways, it avoids calling sbrk or malloc when the amount of memory left to be allocated by sbrk or malloc is less than a user-specified threshold. This unallocated memory is reserved for use by calls to malloc from foreign code.

The MAXFOREIGNMEMORYSIZE command specifies the amount of memory to be reserved for foreign requests. When the amount of memory remaining to be allocated by sbrk or malloc is less than this number of bytes, MAINSAIL will request memory by calling the other system memory allocation functions instead of sbrk or malloc.

This issue is only a consideration for programs that use more than 256 Mb on AIX or more than 1 Gb on HPPA.

See Section B.3.4 for more details about memory allocation and the use of MAXFOREIGNMEMORYSIZE on AIX.

See Section B.3.1 for more details about memory allocation and the use of MAXFOREIGNMEMORYSIZE on HPPA.

3.2.2. FOREIGNSTACKSIZE

Some platforms maintain a separate C stack for foreign calls for each coroutine. By default, this stack is the same size as the MAINSAIL stack for the coroutine. You can change the default by specifying a value for the CONF parameter FOREIGNSTACKSIZE.

The parameter to FOREIGNSTACKSIZE is the default number of storage units to allocate for the C stack for each coroutine. Usually, this value is ignored for the initial coroutine, which uses the initial C stack allocated by the operating system.

FOREIGNSTACKSIZE is available only for platforms that allocate a separate C stack for each coroutine; those platforms are HPPA and HPPA64.

3.3. OS Memory Pool

The OS memory pool, as specified by the CONF command OSMEMORYPOOLSIZE, is implemented for UNIX. The specified amount of memory is first allocated with malloc, then deallocated, to provide a pool of memory to be used by C library and FLI procedures that allocate memory using malloc. On most platforms, this avoids unused static pages in MAINSAIL's memory map.

3.4. General Use

The default CONF parameters are normally kept in a standard configuration file on the MAINSAIL directory. Table B–1 in Appendix B gives the name of the standard configuration file for each available UNIX flavor. UNIX systemwide changes should always be made to this file. The CONF SAVE and RESTORE commands can be used to make personal configuration files.

The output of CONF under UNIX is an assembly language file. This file must be assembled and linked to make a UNIX executable file. Section B.3 in Appendix B shows how to run CONF to make an executable MAINSAIL bootstrap from the output of CONF for each available UNIX flavor.

UNIX CONF appends .s to the output file name if it does not already end in .s.

3.5. Memory Fragmentation Problems on SUN4, SOLRS, and PSOLRS and in Any Program That Calls Foreign Language Code: Use Large MINSIZETOALLOCATE If Allocating Large Dynamic Objects

To allocate its memory on UNIX, MAINSAIL uses sbrk if at all possible rather than malloc. The disadvantage of using malloc is that with each block of memory requested, malloc typically allocates a small hidden record for its own bookkeeping. The details (and even the existence) of the hidden records vary from version to version of malloc, but each hidden record is usually adjacent to its corresponding block of memory. Thus, in many implementations, no two blocks of memory allocated by malloc are ever truly contiguous; they are always separated by at least one of malloc's hidden records. These hidden records prevent MAINSAIL from combining adjacent free blocks of memory allocated by separate calls to malloc into larger free blocks, because doing so would clobber the hidden records. Also, some versions of malloc do not coalesce adjacent free blocks of memory, in which case it does no good for MAINSAIL to return its free blocks by calling free.

No such restrictions apply to blocks of memory allocated by sbrk because there are no hidden records between the blocks.

MAINSAIL can normally coalesce its free memory by shoving its accessible dynamic data and code to one end of memory, letting the free space “bubble up” to the other end, but malloc's hidden records prevent free blocks from being coalesced unless they were allocated by the same call to malloc. Thus, any time MAINSAIL needs space for a block of contiguous memory that is larger than any of the blocks of memory allocated so far by malloc, it must always allocate new memory from the operating system, regardless of how much free space there might already be in its virtual memory. MAINSAIL tries to minimize the extent to which this sort of waste occurs by allocating large blocks of memory (by default, at least 1 Mb) on systems where malloc is used. The minimum amount of memory requested in each call to the operating system is governed by the CONF parameter MINSIZETOALLOCATE.

The fact that MAINSAIL asks for memory in large blocks while foreign code tends to call malloc for each data object (record, array, etc.), coupled with the fact that not all versions of malloc coalesce their free space, means that MAINSAIL's memory requests are rarely satisfied by reusing free space that had been originally allocated (and returned) by foreign code, regardless of how much such free space might be available.

MAINSAIL currently uses sbrk on all UNIX platforms except the Suns, where it must use malloc. On Sun platforms (including Solaris, but excluding SunOS versions before 4.1 on SUN4), the standard version of malloc is incompatible with sbrk. A program that mixes calls to the two functions will sometimes fail in bizarre, irreproducible ways. This incompatibility was introduced with SunOS release 4 when malloc was rewritten to speed it up. The incompatibility is documented by Sun; they do not consider it a bug. Since most MAINSAIL applications contain at least some C code, and since many C library functions contain hidden calls to malloc, this means that MAINSAIL cannot use sbrk on the Suns.

On non-Sun platforms, malloc and sbrk can be combined with no problems. On these platforms, malloc itself typically calls sbrk when it cannot satisfy a request from its own free lists, so there is usually no conflict in the way the two functions allocate new memory.

However, even on non-Sun platforms, “foreign” space can appear in MAINSAIL's address space if, e.g., foreign code calls malloc or sbrk between two calls to sbrk made by MAINSAIL. Foreign space in the middle of MAINSAIL's address space causes the same memory fragmentation problems as malloc's hidden records (described above).

Consequently, on the platforms SUN4 (SunOS versions 4.1 and later), SOLRS, and PSOLRS, and on any platform when linking with foreign code that might call malloc, you should specify a large MINSIZETOALLOCATE value to CONF when building any bootstrap that runs MAINSAIL programs that allocate large dynamic objects. Otherwise, memory fragmentation may make it impossible to allocate the objects. MINSIZETOALLOCATE should be specified at least as large as the largest dynamic object you will allocate, and even larger values often result in improved performance.


previous   next   top   complete contents   complete index   framed top   this page unframed

MAINSAIL System-Specific User's Guides, Chapter 3