USING MEMORY ARRAYS By: Peter Stadick Cargill,Inc P.O Box AR Reserve,LA 70084 (504) 536-4111 Last Edit: 30-AUG-1989 17:45:31 This is a short description of how to use the memory array (MARRAY) package written for OMSI Pascal. It is intended to be used by people with a fair amount of experience with OMSI Pascal. You need to know a little about APR mapping to take full advantage of the software but the package is easy to use since only four procedures are called. The basic reason this was written was as Tom Cruse puts it in Top Gun, "I feel the need for speed!". Package Features: 1. Can create very large arrays with very fast access. Array elements can be of any type but must all be the same size. 2. The array elements are packed into a shared dynamic region on byte boundries to save memory. 3. Elements can be accessed by either a buffer or a pointer into the mapped shared region. Pointer access is very fast because the data is not copied into a buffer. 4. Remapping is done only when nessecary. 5. You can create multiple arrays from the same program and access them all thru the same APR. 6. Once an array shared region has been created it is shareable by other tasks simply by calling it with the same name. How to use the package: The package only has four callable routines: MINIT, MOPEN, MPUT and MGET. I will explain the purpose of each of these routines below. MINIT - The routine MINIT is called only once at the beginning of the program. It initailizes the APR_USE_BLOCK to zeros. This block keeps track of what array in mapped to what APR at a particular point in time. This is used when multiple arrays are used but you still need to call this routine even if you are only using one array. MOPEN - The routine MOPEN is called to open a new array or attach to an existing region. It is called once for each array you want to create. Below is a list of what each parameter is for: M_ARRAY - is the variable declared in your global VAR declarations that contains the array parameters used by the package. You should NEVER modify anything in the variable. APR_USE_BLOCK - This is the same variable you included in the MINIT routine. REGION_NAME - This is the 6 character region name. If this name matches an already existing region then a new region is not created but the array is attached to the already existing region. If you share regions make sure the element sizes and number of elements match between both arrays. MAX_ELEMENTS - Is the maximum number of elements in the array. This must be a non zero positive integer. i.e. 1 thru 32767. ELEMENT_SIZE - Is the size of each element in bytes. Range is 1 thru 8192. BUFFER_ADDRESS - Is the address of the buffer or pointer where data is to be placed or read from. You can obtain this thru the loophole function. POINTER_IN_USE - Boolean parameter the you set true if the buffer address given is a address to a pointer. ID_SPACE_USE - Boolean parameter the you set true if you the task is going to be built I and D space and you want the region to map only D space. ERROR_CODE - If negitive then an error was encountered. Otherwise set to 1. See section on error codes for more detail. MPUT - This routine takes data from the buffer and places it in the specificed element number. An explaination of each parameter is below: M_ARRAY - The same variable as called with by the open statement. ELEMENT_NUMBER - The element number in the array where the data is to be written. ERROR_CODE - Error status of MPUT operation. Note: MPUT is only useful if you are using buffered data. If you are using pointers the routine does nothing since any change to the data is directly written to the shared region. MGET - This routine retreives data from the array and places in a buffer or adjusts the pointer value. You just need to specify the element number. An explaination of each parameter is below: M_ARRAY - The same variable as called with by the open statement. ELEMENT_NUMBER - The element number in the array where the data is to be read from. ERROR_CODE - Error status of MGET operation. What you need to declare as global variables. Three things need to appear in you global variable declarations, the APR_use_block, M_array_block and your buffer or pointer. You must declare only one APR_use_block for the task. You must declare one M_array_block for each array you are going to open. You can share buffers between arrays if you want and the type works out but in general you will want to delcare one buffer for each array you open. Look at the test/example program MTEST.PAS fom ideas on how this is to be done. MTEST creates three arrays and maps them thru one APR. Error Codes - All kinds of things can go wrong but usually don't. It those rare cases an error is encountered here is an explaination of the methodoligy of the error codes: If error code = 1 then no error was encountered. The other error codes are broken into ranges to give you an idea of what statement in the routine caused the error. Below is a list of ranges and what directive caused the error. Range -1 thru -199 - CRRG (Create region) -201 thru -399 - ATRG (Attach region) -401 thru -599 - CRAW (Create address window) -601 thru -799 - MAP (Map window) -1000 - Invalid APR -1001 - Invalid element size -1002 - Invalid number of elements -1003 - Element number out of range Hints, Tricks and Possible Problems: Using record types in the array - A problem can develop when using record types that contain fields the need to be word aligned and you are using pointers. Since the program packs things on byte boundries it is possible to misalign things if the record is an odd number of bytes long. To solve this problem always make sure the record is a even number of bytes long. Sharing memory arrays - If you plan to share two arrays make sure both arrays are declared with the same number of maximum elements and same element size. If this is not followed strange things will happen to your data. The region will not be deallocated until both programs (or more) accessing the data exit. Also, please realize the program does not provide any means of element locking. You need to do this yourself via event flags or semiphores. Pointers - If you use the pointer option to access data please realise that you are directly modifing the data in the shared region. There is no buffering. This can really cause a problem if you plan on coping data from one array to another array and using only one APR. You need to copy the data to a temporary variable before you can copy to the other array.