GEOS SDK TechDocs
|
|
6 System Services
|
6.2 Virtual Memory
GEOS uses all RAM available to the system, even expanded and extended memory. Memory is managed by the kernel and is accessed in the segmented scheme implemented by the 8086 processor. (The protected mode of the more advanced processors is not supported in the Version 2.0 system software but is expected to be in future releases.)
The GEOS Memory Manager is sophisticated. It uses dynamic allocation and access of blocks on a global heap to provide high performance, optimized to run very efficiently even on systems with only 640 K.
GEOS maintains control of all the memory, objects, and other entities in the system through the Handle Table . The Handle Table is a section of memory set aside for kernel use, and it contains a number of entries, each 16 bytes that can contain various information about many different items in the system. These entries are accessed by handles , 16-bit offsets into the Handle Table. Applications and libraries may use handles but may not access the contents of a handle table entry. The data structure is opaque to all but the kernel.
Handles are used for many different things. They can reference threads, memory blocks, VM blocks, or files; they can represent data structures such as timers, queues, semaphores, or events (messages); and they can be used by the kernel for optimization (such as when several words of data are passed with a message).
Through the Preferences application, a user can set the number of handles in the Handle Table. However, the size of the table does not change during a single execution of GEOS. Applications and libraries may allocate handles dynamically for most of the above-mentioned purposes (e.g. memory and file reference).
A certain amount of memory is set aside for the file system (DOS, typically), the GEOS kernel (approximately 64 K), and any TSRs the user may have running on his system. Above this is the GEOS handle table. All RAM left (up to 1 megabyte) after these requirements are satisfied is used for the global heap (RAM over 1 megabyte is used as preferred swap space). The global heap is the space available to all the applications running in the system.
Applications allocate dynamic blocks of memory on the heap. Blocks may be of arbitrary size between 16 bytes and 64 K. Each block is designated a handle, an offset into the handle table where information about the block (such as size and location) is stored. Because blocks may be shuffled in the heap by the Memory Manager, applications must use handles as indirect references to the blocks; applications should not save pointers to specific locations in memory.
GEOS uses four basic types of blocks:
The GEOS kernel provides several routines to allocate memory. Some memory is allocated automatically, such as memory for code resources as they are loaded in. Other memory, however, must be allocated as it is needed during execution--for example, as the user types more and more text into a word processor. There are three basic ways to allocate memory on the heap:
MemAlloc()
This routine allocates a new block on the heap for an application's use.
MemReAlloc()
This routine reallocates a given block; this is useful for adding memory to a block already allocated.
malloc()
Although use of
malloc()
may help in porting previous C code to GEOS, it is discouraged. The
malloc()
routine will allocate small amounts of memory within a fixed resource. Extensive use of
malloc()
leads to large, fixed blocks on the heap, degrading system performance.
When an application is done with a memory block, it can free the block with the routine
MemFree()
. This will allow the Memory Manager to free up that memory space and re-use the block's handle if required.
If a block is allocated as fixed, an application can use a far pointer to access any byte within the block. However, because fixed blocks are not always allocated in the same portion of memory each time an application is loaded, applications should not save pointers as state information.
Non-fixed blocks, however, can not be accessed by far pointers without locking them into their position in memory.
MemLock()
will take a block's handle and lock the block, thereby assuring that the Memory Manager will not move it in the middle of an access.
MemLock()
provides its caller with a far pointer to the block. When access to the block is finished, the thread that locked the block must call
MemUnlock()
, which marks the block as unlocked so it may once again be moved or swapped.
GEOS SDK TechDocs
|
|
6 System Services
|
6.2 Virtual Memory