# Features & API Reference ## Features ### Core Operations - **File-backed memory mapping** - Map files directly into memory for fast random access - **Positional read/write** - Read and write at specific offsets without seeking - **Synchronization** - Flush changes to disk with sync (blocking) or async modes - **File resize** - Truncate or extend files with automatic remapping ### Access Modes - `read` - Read-only access - `write` - Write-only access - `read_write` - Full access (default) ### Mapping Options - `shared` - Changes are visible to other processes and written to file (default) - `private` - Copy-on-write; changes are private to this process - `lock` - Lock pages in memory to prevent swapping - `populate` - Prefault pages on mapping (Linux only) - `nocache` - Disable page caching (macOS only) - `create` - Create file if it doesn't exist - `truncate` - Truncate existing file ### Memory Advice (madvise) Provide hints to the kernel about access patterns: - `normal` - No special treatment - `random` - Expect random access pattern - `sequential` - Expect sequential access pattern - `willneed` - Will need these pages soon - `dontneed` - Won't need these pages soon ## Platform Support | Feature | Linux | macOS | FreeBSD | OpenBSD | |---------|-------|-------|---------|---------| | Basic mmap | Yes | Yes | Yes | Yes | | MAP_POPULATE | Yes | No | No | No | | MAP_NOCACHE | No | Yes | No | No | | mlock | Yes | Yes | Yes | Yes | | madvise | Yes | Yes | Yes | Yes | | fallocate | Yes | ftruncate | posix_fallocate | ftruncate | ## API Reference ### open/2, open/3 ```erlang {ok, Handle} = iommap:open(Path, Options). {ok, Handle} = iommap:open(Path, Mode, Options). ``` Opens a file for memory-mapped access. **Arguments:** - `Path` - File path (string or binary) - `Mode` - Access mode: `read`, `write`, or `read_write` - `Options` - List of options (see Mapping Options above) **Returns:** - `{ok, Handle}` on success - `{error, Reason}` on failure ### close/1 ```erlang ok = iommap:close(Handle). ``` Closes the mapping and file descriptor. The handle becomes invalid after this call. ### pread/3 ```erlang {ok, Binary} = iommap:pread(Handle, Offset, Length). ``` Reads `Length` bytes starting at `Offset`. Returns a copy of the data. **Arguments:** - `Handle` - Memory map handle - `Offset` - Byte offset to start reading - `Length` - Number of bytes to read **Returns:** - `{ok, Binary}` containing the requested data - `{error, out_of_bounds}` if range exceeds file size - `{error, sigbus}` if memory access fault occurred ### pwrite/3 ```erlang ok = iommap:pwrite(Handle, Offset, Data). ``` Writes `Data` (binary or iolist) at `Offset`. **Arguments:** - `Handle` - Memory map handle - `Offset` - Byte offset to start writing - `Data` - Binary or iolist to write **Returns:** - `ok` on success - `{error, out_of_bounds}` if range exceeds file size - `{error, sigbus}` if memory access fault occurred ### sync/1, sync/2 ```erlang ok = iommap:sync(Handle). ok = iommap:sync(Handle, Mode). ``` Flushes changes to disk. **Arguments:** - `Handle` - Memory map handle - `Mode` - `sync` (blocking, default) or `async` (non-blocking) ### truncate/2 ```erlang ok = iommap:truncate(Handle, NewSize). ``` Resizes the file and remaps the memory region. Existing data beyond `NewSize` is lost. **Arguments:** - `Handle` - Memory map handle - `NewSize` - New file size in bytes ### advise/4 ```erlang ok = iommap:advise(Handle, Offset, Length, Hint). ``` Provides access pattern hints to the kernel for optimization. **Arguments:** - `Handle` - Memory map handle - `Offset` - Start of region - `Length` - Length of region (0 for entire file) - `Hint` - `normal`, `random`, `sequential`, `willneed`, or `dontneed` ### position/1 ```erlang {ok, Size} = iommap:position(Handle). ``` Returns the current size of the mapped region. ## Thread Safety The NIF uses pthread read-write locks to ensure thread safety: - Multiple concurrent reads are allowed - Writes are exclusive - Handle validity is checked under the lock ## Error Handling Errors are returned as `{error, Reason}` tuples: | Reason | Description | |--------|-------------| | `badarg` | Invalid arguments | | `enomem` | Out of memory | | `enoent` | File not found | | `eacces` | Permission denied | | `closed` | Handle already closed | | `out_of_bounds` | Offset/length exceeds file size | | `sigbus` | Memory access fault (file truncated externally) | ## SIGBUS Protection The NIF installs a SIGBUS handler to protect against crashes when the underlying file is truncated externally while the mapping exists. If a SIGBUS occurs during read/write, `{error, sigbus}` is returned instead of crashing the VM.