posix-shm
2023-10-21
POSIX shared memory API
POSIX shared memory for Common Lisp
Common Lisp bindings and wrapper for the POSIX shared memory API.
The POSIX shared memory (or shm
) API "allows processes to communicate information by sharing a region of memory." (shm_overview(7)
).
This library provides two strata to access the POSIX shm API:
- The package
posix-shm/ffi
, a collection of slim bindings to the POSIX API. FFI Reference - The package
posix-shm
, a lispy wrapper around the FFI that integrates more closely to the features of Common Lisp, and provides a handful of utilities and macros. API Reference
Features include:
- Open, close, create, resize, change ownership of, change permissions of, and memory map to shared memory objects.
- open-shm appears more like open from the standard library.
- open-shm*, for creating anonymous shm objects.
- with-open-shm, with-mmap and similar with- macros for safely accessing resources with dynamic extent.
Installation and Usage
Install posix-shm with Quicklisp:
* (ql:quickload :posix-shm) * (use-package :posix-shm) * (defparameter +shm-size+ (* 10 (cffi:foreign-type-size :int))) +SHM-SIZE+ * (defvar *shm*) *SHM* * (setf *shm* (open-shm "/foobar-shm" :direction :io :if-does-not-exist :create :permissions '(:user-read :user-write))) #<SHM for "/foobar-shm" {10056A8F03}> * (print (shm-fd *shm*)) 4 ;; Runtime-dependent * (truncate-shm *shm* +shm-size+) * (defparameter *ptr1* (mmap-shm *shm* +shm-size+ :prot '(:write))) *PTR1* * (defparameter *ptr2* (mmap-shm *shm* +shm-size+ :prot '(:read))) *PTR2* * (dotimes (i 10) (setf (cffi:mem-aref *ptr1* :int i) (* i 10))) * (dotimes (i 10) (print (cffi:mem-aref *ptr2* :int i))) 0 10 20 30 40 50 60 70 80 90 NIL * (munmap *ptr1* +shm-size+) * (munmap *ptr2* +shm-size+) * (close-shm *shm*) T * (delete-shm "/foobar-shm")
Use with-open-shm and with-mmap to automatically close and munmap when the program leaves scope:
(with-open-shm (shm "/foobar-shm" :direction :io) (truncate-shm shm 100) (with-mmap (ptr shm 100) ;; do your thing... ))
with-open-shm-and-mmap opens a shm, truncates it, and then maps it to a pointer all in one:
(with-mmapped-shm (shm ptr ("/foobar-shm" :direction :io) (100)) ;; do your thing... )
Use open-shm* and with-open-shm* to create anonymous shm objects that are unlinked the moment they are created:
(defvar *anon-shm* (open-shm* :direction :io :permissions '(:user-all)) ;; do your thing... (close-shm *anon-shm*) (with-open-shm* (anon-shm :direction :io :permissions '(:user-all)) ;; do your thing... )
Contributing
Any comments, questions, issues, or patches are greatly appreciated! I do my main development on Sourcehut, with a mailing list and issue tracker.
Reference
Descriptions of types, classes, functions, and macros of the high-level API are in the API Reference.
Descriptions of the lower-level foreign types and bindings are in the FFI Reference.