Ingres CL ME
From Ingres Community Wiki
|
Ingres Compatability Library |
Compatibility Library Specification - ME
Abstract
This is the specification of the ME facility provided by the compatibility library.
Revision: 1.21, 11-Feb-1998
Document History
- Revision 1.21, 11-Feb-1998
- Added Mefilllng() (11-feb-1998)
- Added MEcopylng() (28-jan-1998)
- Revision 1.2, 25-Mar-1997
- Formatted in HTML format.
- Note that ME_INGRES_THREAD_ALLOC is obsolete.
- Revision 1.1, 29-Jul-94
- ME tag type should be u_i2 (10-Jan-92)
- MEtfree (0) is illegal (15-may-92).
- MEsmdestroy behaviour on delete with clients attached is undefined. (29-may-92, 5-jun-92, 19-jun-92).
- Note MEcopy must work with one kind of overlap (26-mar-93).
- MEtfree may safely be handed a tag with no memory attached (30-apr-93).
- MEgettag & MEfreetag , GL functions for management of memory tags approved. (23-jul-93).
- Revision 1.0, last modified 29-Aug-91.
- Changed intended uses to note that MEreqmem is not to be used by DBMS client code.
- Add substantial introductory material on the page allocation system.
- Note reentrancy problems.
- Changed session to be process to avoid confusion with CS sessions that are threads.
- Added example for ME_ALIGN_MACRO formerly in <compat.h> spec.
- Fixed MEget_pages definition; there is no LOCATION *id;
- Fixed MEshow_pages definition, there is no key, and the called the user arg_list is a PTR *.
Specification
Introduction
The ME module provides memory manipulation facilities. This includes copy, compare, allocation, release, and shared memory services.
Library
CL and GL
Dynamic Memory Allocation
There are two paradigms for memory allocation, the stream model using MEreqmem , etc., and a page model using MEget_pages . Client code may intermix the two when MEadvise has been called with either ME_INGRES_ALLOC. Page based allocation does not work when MEadvise has been called with or was defaulted to ME_USER_ALLOC.
Stream Allocation
The calls to MEreqmem and MEreqlng may cause a request to the OS to increase the size of the process. The calls to MEfree and MEtfree may cause a request to the OS to decrease the size of the process. The blocks of memory returned by the routines MEreqmem , MEreqlng will always return memory aligned for the most restrictive datatype supported by the machine.
The ME module satisfies the client's dynamic memory requests from a single pool of memory. The tag abstraction allows the client code to logically associate separate allocations and thereby free them with a single call to MEtfree . The following restriction exists for tags:
- Ingres FE client code reserves all tags above 100. This means that any code which is linked with the Ingres FEs is restricted to tags between 1 and 99, inclusive.
- Tags may be allocated and freed with the recently added GL functions MEgettag and MEfreetag .
Page Allocation
ME also provides page based allocation and deallocation of process-private or shared memory. The allocation unit is a ME_MPAGESIZE page, and all allocation and deallocation requests are in units of pages. Deallocation of pages need not exactly match allocation of pages (ex. if MEget_pages() returns pages 1,2, and 3; it is ok for the client to issue a MEfree_pages() call for any contiguous subset of these pages - 1, 2, 3, 1-2, 2-3, 1-3). It is also acceptable to issue a single MEfree_pages() call which frees pages allocated by multiple MEget_pages() calls.
Shared memory regions are also available when MEadvise has been called with ME_INGRES_ALLOC. Current clients of shared memory consist of the UNIX logging and locking systems, the UNIX DBMS server slave processes, and the DBMS buffer pool.
Intended Uses
All ME facilities are intended for general use, except that the MEreqmem family should not be used by DBMS code, which should use MEgetpages exclusively.
Assumptions
The following assumptions apply to the ME routines:
Memory allocated through MEreqmem and MEreqlng make use of the same buffer pool, and memory freed using ME[t]free will return to the same pool regardless of which routine was used for allocation. The above assumption implies that the routine underlying MEreqmem and MEreqlng must properly handle allocation of a number of bytes that exceeds the ability to specify using an i4.
Tag 0 should be used for all memory allocations for which a specific tag is not required; the client can free all such memory allocated through MEreqmem and MEreqlng by a call of MEtfree(0) .
The normal usage of the ME page requests will be relatively infrequent requests for large numbers of pages. Memory in general will be available back to the system at process termination time, and in normal operation, memory usage will be LIFO in nature (this allows optimization on UNIX where only sbrk() can be used to free memory back to the OS). Client code must not be dependent on this operation but an implementation may be optimized for it.
Clients of the shared memory subsystem should assume that the shared memory resource is limited, and is not available at all on some systems. Mainline designs based on the use of shared memory must include alternate methods of performing the same task; possibly at some cost in performance (ie. the DBMS can not assume that there is only one buffer manager per installation--though it can take advantage of this optimization).
The number of different shared memory segments that can be attached per process is system dependent. For this reason users of the shared memory subsystem should assume a very limited number of shared memory segments can be created, and should optimize use based on this. Clients should allocate a single shared memory segment, and then split the segment into smaller pieces for their use.
Product designs which utilize shared memory are expected to fully specify how the segments are installed and deinstalled (this should include what happens should the installing process call MEsmdestroy() , or abnormally terminate, while associated processes are attached.) Installation and cleanup procedures are likely to be OS specific, much like the overall install scripts.
Concepts
ME is provides a memory page management abstraction. On some systems this is not simple. On systems such as UNIX this can be accomplished by maintaining either a map of what memory is allocated and what memory is meerly present or by keeping a list of free but present pages. Allocation attempts would first search for sufficient pages being present but not yet allocated and if that fails then the system would be called to extend the memory region. Requests to free pages just mark the pages as not allocated and then check if pages can be returned to the system. On Sun UNIX, the system pages memory in 8K byte pages so a bit map of allocated pages was chosen to avoid virtual memory faults that might occur if free pages were chained together (a 2K byte bitmap can represent 128M bytes of memory.) If pages were smaller, this might not be a good choice.
Identification of shared memory segments however is abstracted to files in a file system. (This may be what the OS recommends--Mapped files.) If the OS doesn't prefer a file name to identify shared memory, these ME routines can be written to use a file to store whatever identification might be needed to get to the shared memory segment. The fact that the file contains a shared memory id is local to ME as these files are not intended for use by any other code. On UNIX, mmap(2) provides the right abstraction, but System V shared memory may have to be used. System V provides a useful function named ftok(3) which takes an existing file and computes a number to identify a shared memory segment so the file name abstraction is not too bad. Because of these issues we have chosen to use the LOCATION CL abstraction to identify shared memory.
Another shared memory issue is whether portions of mapped shared memory can be unmapped. Many systems have an all-or-nothing attitude about shared memory (the page map abstraction mentioned above handles this.)
Other shared memory issues are not so easily abstracted; especially when one contemplates configuring shared memory segments into unrelated user processes. This functionality is not addressed by the current interface.
Malloc emulation library
Programs wanting to use the strategies of the Ingres allocator (which is generally more space efficient than malloc/free) must call MEadvise(ME_INGRES_ALLOC) before any allocation takes place. They must link with a library containing versions of the malloc() family written in terms of MEreqmem() to prevent allocator corruption. (On many systems, default libraries call malloc() and free() unexpectedly). This emulator library is not delivered to customers.
Header File <me.h>
The header file <me.h> must be included before using any of the functions provided. It also defines the following.
Constants
ME_MPAGESIZE
The size of allocation units when using the page based allocators.
ME_ALIGN_MACRO( p, size ) - align pointer to size boundary
Increments the pointer to alignment suitable for use with an object of the specified size. This is the preferred method for cutting up a buffer while making sure that derived pointers are usable.
The input pointer should be a PTR type. The returned PTR value should be cast into the appropriate type as needed.
The size argument should be the size of a scaler type, or the size of the most restrictive scaler type in a structure to which a pointer is desired.
Inputs:
| p | the pointer to round to a suitably aligned value. |
| size | The size to which the pointer should be rounded. |
Outputs:
| None |
Returns:
| A PTR value of adequate alignment. |
Definition:
PTR
MEALIGN_MACRO( p, size )
PTR p;
i4 size;
Example:
The macro is for doing things like dividing a buffer up into smaller objects, which must be correctly aligned for the types really being used. The size argument should be that of the largest integral type to be referred to by the pointer.
/* some structure */
typedef struct
{
i4 a;
double d;
} s;
/* an adequately aligned local buffer of sufficient size */
ALIGN_RESTRICT buf[ BUFSIZ / sizeof(ALIGN_RESTRICT) ];
/* filled in pointers to adequately aligned storage */
s *sp;
float *fp;
double *dp;
i4 *np;
PTR gp;
/* must be char * for arithmetic */
char *bp = (char *)buf;
/* take a i4 pointer */
np = (i4 *)ME_ALIGN_MACRO( bp, sizeof( *np ) );
bp = np + sizeof(*np);
/* grab a double pointer */
dp = (double *)ME_ALIGN_MACRO( bp, sizeof( *dp ) );
bp = np + sizeof(*dp);
/* grab a float pointer */
fp = (float *)ME_ALIGN_MACRO( bp, sizeof( *fp ) );
bp = np + sizeof(*fp);
/* grab a struct ptr aligned to element, not struct size */
sp = (s *)ME_ALIGN_MACRO( bp, sizeof(double) );
bp = sp + sizeof( *sp );
/* grab a properly aligned generic pointer. You don't
have a clue how much to bump the buf pointer until
you know how much space you are using */
gp = (PTR)ME_ALIGN_MACRO( bp, sizeof(ALIGN_RESTRICT) );
MECOPY_CONST_MACRO - Copy block inline, size known at compilation time
This routine copies nbytes bytes from source to dest. The source and destination memory segments may not overlap.
This macro is expected to be optimized for small moves where the number of bytes is known at compile time, particularly with sizeof derived types. It is the preferred way of picking values out of questionably aligned buffers and putting them into aligned local storage.
Because it is a macro, the arguments may be evaluated multiple times.
Inputs:
| source | pointer to the memory to copy |
| nbytes | Constant number of bytes to copy |
Outputs:
| dest | pointer to the memory to be written. |
Returns:
| None |
Definition:
VOID MECOPY_CONST_MACRO( source, nbytes, dest ) PTR source; u_i2 nbytes; PTR dest;
MECOPY_VAR_MACRO - Copy block inline, size known at runtime
This macro copies nbytes bytes from source to dest. The source and destination memory segments may not overlap.
This macro is expected to be optimized for small moves where the number of bytes is not known at compile time. It is the preferred way of moving small things around in extrememly high traffic routines. It is likely to be faster than MEcopy, but slower than MECOPY_CONST_MACRO if the size is known at compile time.
The macro may produce a surprisingly large amount of code. Overuse will result in bloated programs.
Because it is a macro, the arguments may be evaluated multiple times.
Inputs:
| source | pointer to the memory to copy |
| nbytes | number of bytes to copy |
Outputs:
| dest | pointer to the memory to be written. |
Returns:
| None |
Definition:
VOID MECOPY_CONST_MACRO( source, nbytes, dest ) PTR source; u_i2 nbytes; PTR dest;
Executable Interface
The following functions are provided.
MEadvise - Control allocator behavior
Sets the operation of the allocator (MEreqmem, etc.). The flags argument may have the values ME_USER_ALLOC or ME_INGRES_ALLOC. If (flags & ME_INGRES_ALLOC) != 0, the allocator will do what we think is best. If (flags & ME_INGRES_ALLOC) == 0, the ME allocator will work on top of whatever malloc() and free() are linked into the executable.
If MEadvise is not called, ME_USER_ALLOC is assumed. This lets user EQUEL programs use the system malloc and free without competition from the OpenIngres allocator used by the forms system.
Programs wanting to use the strategies of the Ingres allocator (which is generally more space efficient than malloc/free) must call MEadvise(ME_INGRES_ALLOC) before any allocation takes place. They must link with a library containing versions of the malloc() family written in terms of MEreqmem() to prevent allocator corruption. (On many systems, default libraries call malloc() and free() unexpectedly). This emulator library is not delivered to customers.
MEadvise() fails if it is called more than once, or after an allocation has taken place.
To flag link errors, the emulator routines should print an error and exit if called without a previous call of ME_INGRES_ALLOC.
Inputs:
| flags | ||
| ME_USER_ALLOC | [default] use the normal system provided allocator to obtain memory. | |
| ME_INGRES_ALLOC | Use an INGRES-specific allocator to obtain memory. May not work in user programs. Requires linking with an allocator emulator. | |
| ME_INGRES_THREAD_ALLOC | Obsolete. Use ME_INGRES_ALLOC for threaded server. |
Outputs:
| None |
Returns:
| OK | if advice was accepted, otherwise system specific error status. |
Definition:
STATUS MEadvise ( flags ) i4 flags;
MEcmp - Compare blocks of memory
Compare two blocks of memory bytewise, with lowest address being most significant. This routine returns <0 if a < b, 0 if a == b, >0 if a > b. If nbytes is zero, 0 is returned. If either pointer is zero, behavior is unspecified.
Inputs:
| a | the first block of memory to compare |
| b | the second block of memory |
| n_bytes | the number of bytes to compare. |
Outputs:
| None |
Returns:
| "< 0" | if a < b. |
| "0" | if a == b |
| "> 0" | if a > b. |
Definition:
i4 MEcmp(a, b, nbytes) PTR a; PTR b; u_i2 nbytes;
MEcopy - Copy block of memory
Copy nbytes bytes from source to dest. Since copying begins with the address given by source, dest and source can overlay only if dest is a lower address than source.
Inputs:
| source | pointer to the memory to copy |
| nbytes | number of bytes to copy |
Outputs:
| dest | pointer to the memory to be written. |
Returns:
| None |
Definition:
VOID MEcopy(source, nbytes, dest) PTR source; u_i2 nbytes; PTR dest;
MEcopylng - Copy long block of memory
Copy nbytes bytes from source to dest. Since copying begins with the address given by source, dest and source can overlay only if dest is a lower address than source.
nbytes is an i4, allowing larger copies than MEcopy.
Inputs:
| source | pointer to the memory to copy |
| nbytes | number of bytes to copy |
Outputs:
| dest | pointer to the memory to be written. |
Returns:
| None |
Definition:
VOID MEcopylng(source, nbytes, dest) PTR source; i4 nbytes; PTR dest;
MEfill - Fill bytes of memory
Fill nbytes bytes starting at mem with unsigned char val. CLIENT's NOTE: If you have a piece of memory that is larger than 65537, then multiple calls to MEfill will be necessary. (Or you must use Mefillling.)
Inputs:
| nbytes | The number of bytes to fill |
| val | The value to put in memory. |
Outputs:
| mem | pointer to the memory to write. |
Returns:
| None |
Definition:
VOID MEfill(nbytes, val, mem) u_i2 nbytes; unsigned char val; PTR mem;
MEfilllng - Fill long block of memory
Fill nbytes bytes starting at mem with unsigned char val.
nbytes is an i4, allowing operations on larger blocks than MEfill.
Inputs:
| nbytes | The number of bytes to fill |
| val | The value to put in memory. |
Outputs:
| mem | pointer to the memory to write. |
Returns:
| None |
Definition:
VOID MEfilllng(nbytes, val, mem) I4 nbytes; unsigned char val; PTR mem;
MEfree - free allocated memory
Frees the block of memory pointed to by block. Block must have been returned by a call on MEreqmem or MEreqlng .
Also see:
MEtfree to free multiple objects.
Re-entrancy:
Callers of this routine must not lock the csib.cs_mem_sem provided to CSinitiate. It may be used internally, and holding it would cause a deadlock.
Inputs:
| block | pointer to memory obtained from MEreqmem or MEreqlng to release for use. |
Outputs:
| None |
Returns:
| OK | if operation succeeded, otherwise system specific error status. |
Definition:
STATUS MEfree(block) PTR block;
MEfreetag - Release an ME tag
This GL function will release a tag back to ME for re-use. The memory associated with this tag must already be freed when this is called. MEfreetag will not free the memory for the client.
Inputs:
| tag | tag to free |
Outputs:
| None |
Returns:
| OK | Success |
| other | something prevented release of the tag. |
Re-entrancy:
| Protected by an MU semaphore. |
Exceptions:
| none |
Side Effects:
| May allocate memory. |
Definition:
STATUS MEfreetag (u_i2 tag)
MEfree_pages - free allocated pages of memory
If possible, return pages to OS. The memory to be freed must have been allocated using the MEget_pages() call. Memory to be freed need not be exact extent allocated by a MEget_pages() call (for example one MEfree_pages() call can be used to free memory allocated by two MEget_pages() calls assuming the memory was contiguous; or one could free half of the memory allocated by a single MEfree_pages() call.)
Note: The memory might not be freed immediately. On Unix, memory must be contiguous and freed in LIFO order. Thus the memory will not returned to the OS until all memory above it is also freed.
Shared Memory Note: Shared memory often must be released in an all-or-nothing manner so again the actual release may be postponed.
Inputs:
| address | address of the 1st allocated block of memory to be freed. |
| num_of_pages | number of pages to be freed. |
Outputs:
| err_code | system dependent error code. |
Returns:
| OK | Free operation succeeded. |
| ME_BAD_PARAM | Parameter is invalid |
| ME_NOT_ALLOCATED | Pages to be freed were not allocated |
| ME_OUT_OF_MEM | should never happen (OS doesn't want memory back) |
| ME_BAD_ADVISE | call was made during ME_USER_ALLOC. |
Definition:
STATUS MEfree_pages(address, num_of_pages, err_code) PTR address; i4 num_of_pages; CL_ERR_DESC *err_code;
MEgettag - Get an unused ME tag
This GL function Gets a currently unused ME tag for memory allocation. For compatibility with functions which use hardcoded tag numbers, all returned tag numbers will be >= 100.
Inputs:
| none |
Outputs:
| none |
Returns:
| ME tag, values > 0 are successful, a value of 0 means it was unable to allocate a tag |
Reentrancy:
| Internal data structures protected with MU semaphores. |
Exceptions:
| none |
Side Effects:
| None. |
Definition:
u_i2 MEgettag (void)
MEget_pages - add (possibly shared) memory to the client
This routine adds pages to the virtual address space of the requesting program. This routine is intended to be used by the dbms server for all dynamic memory allocation. It adds pages which are ME_MPAGESIZE bytes in length, and are guaranteed to be aligned on ME_MPAGESIZE byte boundaries.
Implementors of the ME module can assume that MEget_pages will be the exclusive allocator of memory when MEadvise(ME_INGRES_ALLOC) .
This routine allocates some number of pages. The memory allocated here is considered to be long-term memory (on the order of process or server length of time). All memory returned by this service is page (ME_MPAGESIZE bytes) aligned, and the unit of measuring of this memory is pages (i.e. requests come in for number of pages, not number of bytes). Note that this page size must be variable from environment to environment. This is necessary to adjust for environmental performance differences in paging activity.
When allocating shared memory, even more restrictive conditions may apply, e.g.,
- The allocation size being greater
- The alignment boundaries are further apart
- Only specific regions of the address space can support shared segments.
The various restrictions on shared memory are derived from a machine's hardware architecture and the operating system's allocation primitives. Because these restrictions are so varied, MEget_pages is not allowed during MEadvise(ME_USER_ALLOC) .
Attaching to a shared segment is performed by a flag setting of either ME_MSHARED_MASK or ME_SSHARED_MASK and ~ME_CREATE_MASK. When attaching to a shared segment the pages argument is ignored.
When creating or attaching to shared memory segments, a key parameter must be specified which uniquely identifies this shared segment within the current Ingres installation. The key parameter is a character string that must follow the Ingres file naming conventions: prefix.suffix where prefix is at most 8 characters and suffix is at most 3. All characters must be printable. ME may use this key to create a file to identify the shared memory segment, although this is up to the particular implementation of ME.
Reentrancy:
This routine may not be reentrant. When running in a threaded environment, it may need to be protected with the csib.cs_mem_sem provided to CSinitiate. This same semaphore may be needed to protect all calls to MEget_pages , MEfree_pages, and MEprot_pages.
Also see:
Inputs:
| flag | flag specifying special operations on allocated memory. (advisorys) Can be or'ed together. | |
| ME_NO_MASK | None of the other flags apply. | |
| ME_MZERO_MASK | zero the memory before returning | |
| ME_MERASE_MASK | erase the memory (DoD) ...on systems where applicable | |
| ME_IO_MASK | Memory used for I/O | |
| ME_SPARSE_MASK | Memory used `sparsely' so should be paged in small chunks if applicable | |
| ME_LOCKED_MASK | Memory should be locked down to inhibit paging -- i.e. buffer caches. | |
| ME_SSHARED_MASK | Memory shared across processes on a single machine | |
| ME_MSHARED_MASK | Memory shared with other processors. | |
| ME_CREATE_MASK | If shared memory doesn't yet exist then it may be created. (Usually, specified with ME_MZERO_MASK) If the shared memory already exists it is an error to create it. | |
| ME_NOTPERM_MASK | Create temporary shared memory segment rather than a permanent one (on systems where this is supported). | |
| pages | ME_SSHARED_MASK&~ME_CREATE_MASK, the pages argument is ignored. | |
| key | A character string identifier for the shared memory segment. This argument is only required with shared memory operations - when not needed, use NULL.
The key identifier should be a character string that follows the Ingres file naming conventions: 8 characters max prefix name and 3 characters max suffix. |
Outputs:
| memory | Upon success the address of the allocated memory. |
| allocated_pages | Number pages of shared memory returned. Normally, this will always match the pages input parameter. If attaching to an existing shared memory segment, this will give the actual size of the attached segment. |
| err_code | System specific error information. |
Returns:
| OK | If all went well. Otherwise, set to: |
| ME_OUT_OF_MEM | Could not allocate required amount of memory. |
| ME_BAD_PARAM | Illegal parameter passed to routine (pages <= 0, ...) |
| ME_ILLEGAL_USAGE | Combii4ion of attributes is invalid |
| ME_BAD_ADVISE | call was made during ME_USER_ALLOC. |
| ME_ALREADY_EXISTS | shared memory identifier already exists |
| ME_NO_SUCH_SEGMENT | specified shared memory segment does not exist |
| ME_NO_SHARED | system can not support shared memory |
Definition:
STATUS MEget_pages (flag, pages, key, memory, allocated_pages, err_code) i4 flag; i4 pages; char *key; PTR *memory; i4 *allocated_pages; CL_SYS_ERR *err_code;
MEmove - copy/move bytes with padding
Move from source of length slen to dest of length dlen. Pad end of dest with padchar if dlen > slen, else truncate to dlen.
Inputs:
| slen | length of the source memory to copy |
| source | pointer to the source memory |
| padchar | value to fill if slen < dlen. |
| dlen | length of memory to write. |
Outputs:
| dest | pointer to memory that will be written |
Returns:
| None |
Definition:
VOID MEmove(slen, source, padchar, dlen, dest) u_i2 slen; PTR source; char padchar; u_i2 dlen; PTR dest;
MEprot_pages - set protection attributes on a page range
For host Operating Systems which support it, modify access attributes on a page range. Possible uses of this routine include stack overflow warning, facility and/or thread verification traces of valid memory use, protection from dynamically linked user code in Ingres proprietary processes, ...
Mainline (user accessible) functionality can not depend on this interface; improved error handling, enhanced debugging capabilities, etc. are the intended clients. Clients are not expected to ifdef use of this interface.
Setting attributes on a shared segment only affects the client that calls MEprot_pages.
Re-entrancy:
This routine may not be reentrant. When running in a threaded environment, it may need to be protected with the csib.cs_mem_sem provided to CSinitiate. This same semaphore may be needed to protect all calls to MEget_pages , MEfree_pages, and MEprot_pages.
Also see:
Inputs:
| addr | start address of page range | |
| pages | number of pages in range | |
| protection | protections requested: | |
| ME_PROT_READ | allow read access. | |
| ME_PROT_WRITE | allow write access. | |
| ME_PROT_EXECUTE | allow execute access. |
Outputs:
| None |
Returns:
| OK | Protections could be set. |
| ME_NOT_ALLOCATED | Pages are not allocated. |
| ME_NOT_SUPPORTED | OS can not comply with request |
| ME_BAD_ADVISE | call was made during ME_USER_ALLOC. |
Side Effects:
| Memory accesses which violate set permissions will generate OS specific exceptions. |
Definition:
STATUS MEprot_pages(addr, pages, protection) PTR addr; i4 pages; i4 protection;
MEreqlng - Allocate memory of specified size
Returns a pointer to a block of memory of size bytes. A tag must be specified, although that tag may be 0 as a default value. If the clear parameter is TRUE, then the allocated memory is zeroed. The fourth parameter may be NULL, in which case no detailed status information is returned. Returns NULL if an error occurs. This routine is like MEreqmem , except that the amount of memory allocated may be a larger number of bytes than can fit in a u_i4.
Ingres FE client code reserves all tags above 100. This means that any code which is linked with the Ingres FEs is restricted to tags between 1 and 99, inclusive. (Tags may be allocated and freed with the recently added GL functions MEgettag and MEfreetag .)
Re-entrancy:
Callers of this routine must not lock the csib.cs_mem_sem provided to CSinitiate. It may be used internally, and holding it would cause a deadlock.
Also see:
Inputs:
| tag | id associated with the allocated region of memory. |
| size | Amount of memory to allocate. |
| clear | Specify whether to zero out the allocated memory. |
Outputs:
| Status | If not NULL, the referenced location will be set to one of: | |
| OK | all went well. | |
| ME_NO_ALLOC, | ||
| ME_GONE, | ||
| ME_00_PTR, | ||
| ME_CORRUPTED, | ||
| ME_TOO_BIG. |
Returns:
| Pointer to the allocated region of memory, or NULL on error. |
Definition:
PTR MEreqlng (tag, size, clear, status) u_i4 tag; u_i4 size; bool clear; STATUS *status;
MEreqmem - allocate memory of specified size
Returns a pointer to a block of memory of size bytes. A tag must be specified, although that tag may be 0 as a default value. If the clear parameter is TRUE, then the allocated memory is zeroed. The fourth parameter may be NULL, in which case no detailed status information is returned. Returns NULL if an error occurs. This routine is like MEreqlng, except that the amount of memory allocated is limited to the number of bytes than can fit in a u_i4.
Ingres FE client code reserves all tags above 100. This means that any code which is linked with the Ingres FEs is restricted to tags between 1 and 99, inclusive.
Re-entrancy:
Callers of this routine must not lock the csib.cs_mem_sem provided to CSinitiate. It may be used internally, and holding it would cause a deadlock.
Also see:
Inputs:
| tag | id associated with the allocated region of memory. |
| size | Amount of memory to allocate. |
| clear | Specify whether to zero out the allocated memory. |
Outputs:
| Status | If not NULL, the referenced location will be set to one of: | |
| OK | all went well. | |
| ME_NO_ALLOC, | ||
| ME_GONE, | ||
| ME_00_PTR, | ||
| ME_CORRUPTED, | ||
| ME_TOO_BIG. |
Returns:
| Pointer to the allocated region of memory, or NULL on error. |
Definition:
PTR MEreqmem(tag, size, clear, status) u_i4 tag; u_i4 size; bool clear; STATUS *status;
MEshow_pages - show system's allocated shared memory segments
This routine is used by clients of the shared memory allocation routines to show what shared memory segments are currently allocated by the system.
This routine takes a function parameter - func - that will be called once for each existing shared memory segment allocated by Ingres in the current installation.
The client specified function must have the following definition:
STATUS func(arg_list, key, err_code) PTR *arg_list; Pointer to argument list. char *key; Shared segment key. CL_SYS_ERR *err_code; Pointer to operating system error codes (if applicable).
The following return values from the routine func have special meaning to MEshow_pages :
| OK | If zero is returned from func then MEshow_pages will continue normally, calling func with the next shared memory segment. |
| ENDFILE | If ENDFILE is returned from func then MEshow_pages will stop processing and return OK to the caller.
If func returns any other value, MEshow_pages will stop processing and return that STATUS value to its caller. Additionally, the system specific err_code value returned by func will be returned to the MEshow_pages caller. |
Re-entrancy:
Callers of this routine must not lock the csib.cs_mem_sem provided to CSinitiate. It may be used internally, and holding it would cause a deadlock.
Inputs:
| func | Function to call with each shared segment. |
| arg_list | Optional pointer to argument list to pass to function. |
Outputs:
| err_code | System specific error information. |
Returns:
| OK | if operation succeeded, otherwise system specific error status, or a non-ENDFILE status value returned by the called function. |
| ME_NO_PERM | No permission to show shared memory segment. |
| ME_BAD_PARAM | Bad function argument. |
| ME_NO_SHARED | No shared memory in this CL. |
Definition:
STATUS MEshow_pages (func, arg_list, err_code) STATUS (*func)(); PTR *arg_list; CL_SYS_ERR *err_code;
MEsize - Return allocated size of a block
Return in size the number of (usable) bytes in block of memory whose address is stored in block which must have been allocated by MEreqmem or MEreqlng .
Re-entrancy:
Callers of this routine must not lock the csib.cs_ mem_sem provided to CSinitiate. It may be used internally, and holding it would cause a deadlock.
Inputs:
| block | pointer to memory previously allocated by MEreqmem or MEreqlng . |
Outputs:
| size | pointer to a i4 filled in with the size of the block. |
Returns:
| OK | if operation succeeded, otherwise system specific error status. |
Definition:
STATUS MEsize(block, size) PTR block; i4 *size;
MEsmdestroy - destroy a shared memory segment
Remove the shared memory segment specified by shared memory identifier key from the system and destroy any system data structure associated with it.
Note: The shared memory pages are not necessarily removed from processes which have the segment mapped. It is up to the clients to detach the segment via MEfree_pages prior to destroying it.
Protection Note: This routine can only be executed by a user running with the same effective privileges as the user who created the shared memory segment.
Re-entrancy:
Callers of this routine must not lock the csib.cs_mem_sem provided to CSinitiate. It may be used internally, and holding it would cause a deadlock.
Inputs:
| key | Shared memory key which was previously used in a successful MEget_pages call (not necessarily a call in this process). |
Outputs:
| err_code | System specific error information. |
Returns:
| OK | if operation succeeded, otherwise system specific error status. |
| ME_NO_PERM | No permission to destroy shared memory segment. |
| ME_NO_SUCH_SEGMENT | indicated shared memory segment does not exist. |
| ME_NO_SHARED | No shared memory in this CL. |
| ME_BAD_ADVICE | call was made during ME_USER_ALLOC |
Definition:
STATUS MEsmdestroy( char key, CL_SYS_ERR err_code );
MEtfree - free tagged allocated memory
Frees all memory allocated by calls to MEreqmem or MEreqlng with the same value of tag.
Re-entrancy:
Callers of this routine must not lock the csib.cs_mem_sem provided to CSinitiate. It may be used internally, and holding it would cause a deadlock.
Inputs:
| tag | blocks allocated with this tag value should be released. |
Outputs:
| None |
Returns:
| OK | if operation succeeded, otherwise system specific error status. |
Definition:
STATUS MEtfree ( u_i2 tag );
|
Ingres Compatability Library |
