mmap (BPX1MMP, BPX4MMP) — Map pages of memory

Function

The mmap callable service establishes a mapping between a process's address space and a HFS file.

Requirements

Operation Environment
Authorization: Supervisor state or problem state, PSW Key 2 or PSW Key 8
Dispatchable unit mode: Task
Cross memory mode: PASN = HASN
AMODE (BPX1MMP): 31-bit
AMODE (BPX4MMP): 64-bit
ASC mode: Primary address space control (ASC) mode
Interrupt status: Enabled for interrupts
Locks: Unlocked
Control parameters: All parameters must be addressable by the caller and in the primary address space.

Format

CALL BPX1MMP,(Map_address,
              Map_length,
              Protect_options,
              Map_type,
              File_descriptor,
              File_offset,
              Return_value,
              Return_code,
              Reason_code)
AMODE 64 callers need an additional parameter, Returned_map_address:
CALL BPX4MMP,(Map_address,
              Map_length,
              Protect_options,
              Map_type,
              File_descriptor,
              File_offset,
              Returned_map_address
              Return_value,
              Return_code,
              Reason_code)

Parameters

Map_address
Supplied parameter
Type:
Address
Length:
Fullword (doubleword)

The name of a fullword (doubleword) field that contains zero, or the address of an area within the address space at which the system is to attempt to map the requested file.

If the value of map_address is zero, the system has complete freedom in selecting the location within the address space at which the requested file is mapped.

If the value of map_address is not zero, the value that is specified is taken to be a suggestion of an address near which the mapping is to be placed. For non-MAP_FIXED requests, the system attempts to create the mapping at the address specified by map_address. The address is truncated to the nearest page boundary when a map type of MAP_SHARED or MAP_PRIVATE is specified, and to the nearest segment or megabyte boundary when a map type of MAP_MEGA is specified. If it is unsuccessful, it proceeds as if a map_address value of zero were specified.

For MAP_FIXED requests, the value of map_address must be a multiple of the page size when MAP_PRIVATE or MAP_SHARED is specified, and a multiple of the segment size when MAP_MEGA is specified. (If MAP_MEGA is specified, the value that is specified in map_address must be equal to zero or equal to or greater than 16 megabytes, or the request is failed with EINVAL.) The MAP_FIXED request fails with an EINVAL if any portion of the requested range is already in use for any reason (including a previous mapping).

The map_address supplied by the caller cannot be above the 31-bit addressability bar (X'7FFFFFFF'), or the request will fail (EINVAL).

Map_length
Supplied parameter
Type:
Integer
Length:
Fullword (doubleword)

The name of a fullword (doublword) field that contains the size (in bytes) of the memory mapping that is to be created. The length that is specified must be less than or equal to the size of the file, and must not cause the address space REGION to be exceeded. Mapping operations are performed over whole pages, or whole segments when MAP_MEGA is specified. If the length is not a multiple of the page size or segment size, the entire trailing portion of the page or segment (up to the end of the file) is also mapped into the user storage. The trailing portion of the page or segment in which an end of file occurs contains binary zeros.

Protect_options
Supplied parameter
Type:
Integer
Length:
Fullword

The name of the fullword that contains the value of the memory access protection flags. The protect_options parameter indicates whether read, write, execute, or some combination of accesses are permitted to the mapped data. It can be set to either PROT_NONE, or a combination (using, for example, an inclusive OR) of one or more of the other access protection flags. The constant values for these flags are defined in the BPXYCONS macro. (See BPXYCONS — Constants used by services.) For MAP_MEGA mappings, the value that is specified for protect_options has a global effect on all current maps to the same file-offset range. For example, if PROT_READ is specified, all active maps have their protection for the same file-offset range changed to a protection of read.

Constant Description
PROT_READ Mapped data can be read. The file descriptor must have been previously opened with at least read access.
PROT_WRITE Mapped data can be written and read. To select the PROT_WRITE option, if a map_type of MAP_SHARED is specified, the file descriptor must have been previously opened with Read/Write access. If MAP_PRIVATE is specified, the file descriptor only needs to have been opened with read access.
PROT_EXEC Mapped data can be executed. This option is treated as if PROT_READ has been specified.
PROT_NONE Mapped data cannot be accessed.
Map_type
Supplied parameter
Type:
Integer
Length:
Fullword
The name of the fullword that contains the mapping type. The constant values for map_type are defined in the BPXYCONS macro.
Constant Description
MAP_SHARED All changes to the mapped data are shared. Modifications to the mapped data are visible to all other processes that map the same file-offset range.
MAP_PRIVATE All changes to the mapped data are private. Modifications to the mapped data are visible only to the calling process, and do not change the underlying file. To use this option, the hardware must provide the suppression-on-protection support.
MAP_MEGA All changes to the mapped data are shared. Modifications to the mapped data are visible to all other processes that map the same file-offset range. The protection attributes of file-offset ranges are common among all active maps. Changes to the protection option of a file-offset range are global, and immediately affect all active maps.
MAP_FIXED The mapping must be placed at exactly the location specified by the map_address parameter.
You must specify MAP_SHARED, MAP_PRIVATE, or MAP_MEGA, but you cannot specify more than one. MAP_FIXED is optional when any of the other map options is specified. To specify both MAP_FIXED and MAP_SHARED, for example, use a map_type value equal to the inclusive OR of these two constants.
File_descriptor
Supplied parameter
Type:
Integer
Length:
Fullword

The name of a fullword that contains the file descriptor of an open file that is to be mapped to process storage. The file descriptor is returned by open (BPX1OPN, BPX4OPN) — Open a file. You can only specify the file descriptor of a regular file.

For a MAP_MEGA mapping, if this is the first map to the file that is represented by the specified file descriptor, the protect_options that can be specified for this file by this map request (and by all future map or mprotect requests, by this or any other process mapping to the same file) are determined by whether the file was opened for read or for read and write. If the file was opened for read but not write, only PROT_READ, PROT_EXEC, or PROT_NONE are allowed. If the file was opened for write, any of the protection options are accepted. Once PROT_WRITE is allowed for a file, all map requests must provide a file descriptor that was opened for write, or the map request is failed.

File_offset
Supplied parameter
Type:
Integer
Length:
Doubleword

The name of a doubleword that defines which part of the file is to be mapped. It contains the offset into the file at which the map_length is to begin. The value of file_offset must be a multiple of the page size when MAP_PRIVATE or MAP_SHARED is specified, and a multiple of the segment size when MAP_MEGA is specified. The offset plus the map_length must fall within the current size of the file.

Returned_map_address
Returned parameter (BPX4MMP only)
Type:
Address
Length:
Doubleword

The name of a doubleword in which the mmap service returns the 64-bit address where the mapping was placed, if the request is successful.

Return_value
Returned parameter
Type:
Address
Length:
Fullword

The name of a fullword in which the mmap service returns the 31-bit address at which the mapping was placed, if the request is successful; or -1, if it is not successful. In AMODE 64, if mmap is successful, 0 is returned in this field and the 64-bit address is returned in the Returned_map_address parameter.

Upon successful completion, the mmap service has established a mapping between the process's address space, at an address returned in the Return_value parameter, for map_length bytes, to the file that is represented by the file_descriptor, at the specified file_offset, for a length of map_length bytes. The specified access protections and mapping type are set for the mapped range.

Return_code
Returned parameter
Type:
Integer
Length:
Fullword

The name of a fullword in which the mmap service stores the return code. The mmap service returns Return_code only if Return_value is -1. See z/OS UNIX System Services Messages and Codes for a complete list of possible return code values.

The mmap service can return one of the following values in the Return_code parameter:
Return_code Explanation
EACCES One of the following conditions occurred:
  • The file descriptor is not open for read, regardless of the protection specified. (JRRFileNoRead)
  • The file descriptor is not open for write, and PROT_WRITE was specified for a MAP_SHARED type mapping. (JRWFileRDOnly)
  • A MAP_MEGA request specified PROT_WRITE, but the first active map to a file was done with a file descriptor that was not open for write. (JRWFileMapRDonly)
EAGAIN The caller is not running in either PSW Key 2 or PSW Key 8. (JRUnsupportedKey)
EBADF One of the following conditions occurred:
  • The file specified by the file_descriptor parameter does not represent a standard file. (JRNotStdFile)
  • The file specified by the file_descriptor parameter is not a valid open file descriptor. (JRs belong to fstat() or w_ioctl())
EINVAL One of the following conditions occurred:
  • MAP_FIXED was specified, and the requested range was not available. The range could be previously allocated, or it could be outside the address space region. (JRAddressNotAvailable)
  • MAP_FIXED was specified, and the value of the map_address parameter is not a multiple of the page size. (JRNotPage)
  • The value of the file_offset parameter is not a multiple of the page size. (JRNotPage)
  • The value specified in the map_type parameter is incorrect. (JRMmapBadType)
  • The value specified in the protect_options parameter is incorrect. PROT_NONE cannot be specified in combination with any other options. (JROptNotSupp)
  • The file was extended and subsequently mapped beyond the original EOF point while an existing memory map containing the original EOF point was outstanding. (JRMmapOverEof)
  • The file_offset value must be zero or larger. (JRNegativeValueInvalid)
  • An attempt was made to map a file that is already mapped, but with a different specification of MAP_MEGA. At any point in time, a file may be mapped with or without the MAP_MEGA option, but not both with and without the MAP_MEGA option.
  • The file was already mapped by another process into a storage key that does not match the PSW key of the caller. (JrKeyMismatch)
  • In 64-bit mode, an address greater than 31 bit addr was passed in map_address (JrAddressNotAvailable).
  • In 64-bit mode, a length greater than X'7FFFFFFFF' was passed in map_length (JrInvParmLength).
EMFILE The number of mapped regions would exceed a system limit:
  • The system-wide limit on the amount of memory consumed by memory-mapped areas was exceeded. (JRMmapStgExceeded)
  • The per-process limit on the number of outstanding memory-mapped areas was exceeded. This limit is the same as the limit on the number of files a process can have open at any given time. (JRProcMaxMmap)
ENODEV The file descriptor refers to a file for which mmap is not supported (for example, a terminal). (JRNotSupportedForFileType)
ENOMEM One of the following conditions occurred:
  • MAP_FIXED was specified, and the requested range (map_address, map_address + map_length) exceeds that allowed for the address space of a process. (JRAddressNotAvailable)
  • There is insufficient room in the address space to effect the mapping. (JRNoUserStorage)
  • There is insufficient shared storage available in the system to satisfy this request. (JRShrStgStorage)
ENOSYS MAP_PRIVATE was specified, but the required suppression-on-protection hardware support was not available. (JRHardware)
ENXIO The addresses in the range (file_offset, file_offset + map_length) are not valid for the specified file descriptor. (JRMmapFileAddress)
Reason_code
Returned parameter
Type:
Integer
Length:
Fullword

The name of a fullword in which the mmap service stores the reason code. The mmap service returns Reason_code only if Return_value is -1. Reason_code further qualifies the Return_code value. For the reason codes, see z/OS UNIX System Services Messages and Codes.

Usage notes

  1. The mmap service supports only regular files. Any other type of file is not processed.
  2. The mmap resources are maintained at a process level. This means that the termination of the thread that invoked the mmap service does not cause the associated mapping to be removed. The mmap resources are freed when the process ends.
  3. The mmap service adds an extra reference to the file that is associated with the specified file descriptor that is not removed by a subsequent close on that file descriptor. This reference is removed when there are no more mappings to the file. The access level (read/write) that was established when the file was opened is enforced for the life of the memory-mapped area, independent of subsequent activity that occurs upon that file descriptor.
  4. The storage that is allocated by the mmap service is allocated in fetch-protected key 2 or 8 storage, depending on the key of the caller mapping the file for the first time. It is allocated with memory that can have both virtual addresses and real addresses above the 16-MB line. The storage cannot be freed by an unauthorized user. The allocated storage comes out of the user region.
  5. Specifying a target Map_address can have a negative impact on the address space. For example, specifying a Map_address at the top of the private area, below the 16MB line, could prevent system code from successfully obtaining below-the-line storage.
  6. All tasks and SRBs within the address space that issued the mmap request can access the memory allocated by the mmap service, but only threads within the process that created the mmap area are permitted to invoke any subsequent memory map services against that mmap instance. The protection level that is established by this process is enforced for all accesses that are made to that range within the address space.
  7. All memory-mapped areas, along with their mapping types and mprotect established access levels, are propagated to the child process during fork processing. The user is responsible for serialization across multiple threads.
  8. If MAP_PRIVATE is specified, the initial write reference to the memory-mapped region creates a private copy of the memory-mapped page, and redirects the mapping to the copy. Note that the copy is not created until the first write. Until the first write, updates that are made to that region by other processes that are mapped by MAP_SHARED with the same file-offset range are visible.
  9. Applications that use the MAP_PRIVATE support may need to be aware of page boundaries when updates are performed, because an update to a single byte causes an entire page to no longer receive updates that are made by other processes mapped with the same file-offset range.
  10. To serialize access to a file-offset range that is being accessed by multiple processes, you can use lockf, fcntl, or semaphores. Serialization should be obtained when the incore copy of the data is being updated, or when the file is being updated using msync.
  11. If a sparse file is memory-mapped, accessing a page that has never been written to in the file causes a page of binary zeros to be generated.
  12. The mmap service allows access to HFS files through address space manipulation, instead of through the read/write services. After the file is mapped, the process can access it by using the data at the address to which the file was mapped.
    The following code sample illustrates how an existing program might be changed to use the mmap service:
     fd = open(...)
     lseek(fd, file_offset)
     read(fd, buffer, length)
    
     /* ...(use data in buffer) ... */
    
    becomes
    
     fd = open(...)
     address = mmap (0, length, PROT_READ, MAP_PRIVATE, fd, file_offset)
    
     /* ...(use data at address) ... */
  13. Constants used for this callable service are defined in the BPXYCONS macro. See BPXYCONS — Constants used by services.
  14. The mmap service is not enabled to map storage above the 2-gigabyte addressing range. It is enabled only to be called from a 64-bit program with a 64-bit parameter list.

Related services

Characteristics and restrictions

  1. The MAP_PRIVATE support requires the suppression-on-protection hardware feature.
  2. The same file-offset range can be mapped multiple times within a given address space (to different virtual addresses), each with unique protection levels. A memory-mapped file-offset range can partially or fully overlap other existing mapped file-offset ranges. This support also holds true across multiple processes.
  3. The mmap service can never be used to extend or truncate the size of a file. If a page is updated beyond the EOF mark of the original memory-mapped file, the portion beyond the EOF mark is not written to the file.
  4. A file that is memory-mapped can be appended by another process while the memory map is active; no overlays will occur. However, the newly created area cannot be mapped across the original EOF point, unless either the EOF point falls on a 4K boundary, or the original memory mapping is unmapped.
  5. When a given file-offset is memory-mapped, unpredictable results will occur if the file is truncated to a point which resides within the memory mapped range. These results may include the abnormal termination of the task that is accessing the memory-mapped area.
  6. If other processes modify the contents of the file that is using the write service while mapped ranges are active for that file-offset, results will be unpredictable, unless specific serialization actions are taken by the user. See msync (BPX1MSY, BPX4MSY) — Synchronize memory with physical storage for details.
  7. There is a limit on the number of active memory maps that a process can have outstanding at any given time. The system administrator defines this limit by specifying the maximum number of files a process can have open. Even though a single value is set that limits both files and mmaps, the two limits are enforced independently of one another.
  8. Memory maps with the MAP_MEGA option use storage in units of megabytes. Extensive use of MAP_MEGA on very small files, or on small ranges of larger files, can be wasteful. MAP_MEGA is best used on large files.
  9. Memory maps of very large files by several processes can realize substantial savings of system common area usage when you use the MAP_MEGA option.

Examples

For an example using this callable service, see BPX1MMP (mmap) example.