source: trunk/abcl/patches/cffi-shareable-vectors.patch

Last change on this file was 15289, checked in by Mark Evenson, 4 years ago

ci: use patched version CFFI that implements MAKE-SHAREABLE-BYTE-VECTOR

Uses
<https://github.com/armedbear/cffi/tree/abcl/easye-shareable-byte-vector-20200530a>.

File size: 4.1 KB
  • src/cffi-abcl.lisp

    # HG changeset patch
    # Parent  a5ee931fc9a61275240863749f20d0fe360cb78d
    abcl: implement MAKE-SHAREABLE-BYTE-VECTOR
    
    ABCL is able create and share malloc()d memory for byte vectors with
    EXTENSION:MAKE-NIOBUFFER-VECTOR in
    <https://github.com/armedbear/abcl/pull/197> ff. patch to
    abcl-1.6.2-dev for the upcoming abcl-1.7.0 release.  Conditionalize
    code on presence of an CL:FBOUNDP EXTENSION:MAKE-NIOBUFFER-VECTOR
    symbol.
    
    Retain the old behavior of copying memory for
    WITH-POINTER-TO-VECTOR-DATA when passed a non-shareable byte vector.
    
    diff -r a5ee931fc9a6 src/cffi-abcl.lisp
    a b  
    6969   #:native-namestring
    7070   #:%mem-ref
    7171   #:%mem-set
    72    ;; #:make-shareable-byte-vector
    73    ;; #:with-pointer-to-vector-data
    7472   #:%foreign-symbol-pointer
    7573   #:%defcallback
    7674   #:%callback
     
    291289    (:pointer "getPointer")
    292290    ((:short :unsigned-short) "getShort")))
    293291
     292;;; HACK for now: keep track of all the pointers to malloc()'d memory
     293;;; hashed by the shareable byte vectors we allocate.
     294(defvar *static-vector-pointer*
     295  (make-hash-table :weakness :value))
     296
     297#+#.(uiop:symbol-test-to-feature-expression :make-niobuffer-vector :ext)
     298(defun make-shareable-vector (length &key (element-type '(unsigned-byte 8)))
     299  "Use memory on the heap for storing a vector of LENGTH with ELEMENT-TYPE
     300
     301Returns the allocated vector as the first value, and the pointer to
     302the heap memory as the second.
     303
     304Only works for 8, 16, 32 bit bytes.
     305"
     306  (let* ((type
     307           (first element-type))
     308         (bits-per-byte
     309           (second element-type))
     310         (bytes-per-element  ;; ehh, not going to work well for element type not of size 8, 16, or 32
     311           (ceiling bits-per-byte 8)))
     312    (unless (subtypep element-type
     313                      '(or (unsigned-byte 8) (unsigned-byte 16) (unsigned-byte 32)))
     314      (signal 'type-error :datum element-type
     315                          :expected-type '(or
     316                                           (unsigned-byte 8)
     317                                           (unsigned-byte 16)
     318                                           (unsigned-byte 32))))
     319    (let* ((bytes
     320             (* length bytes-per-element))
     321           (heap-pointer
     322             (jss:new "com.sun.jna.Memory" bytes))
     323           (bytebuffer
     324             (#"getByteBuffer" heap-pointer 0 bytes))
     325           (static-vector
     326             (ext:make-niobuffer-vector bytebuffer :element-type element-type)))
     327      (setf (gethash static-vector *static-vector-pointer*)
     328            heap-pointer)
     329      (values
     330       static-vector
     331       heap-pointer))))
     332
    294333(defun make-shareable-byte-vector (size)
    295334  "Create a Lisp vector of SIZE bytes can passed to
    296335WITH-POINTER-TO-VECTOR-DATA."
    297   (make-array size :element-type '(unsigned-byte 8)))
     336  (if (fboundp (uiop:find-symbol* :make-niobuffer-vector :ext nil))
     337      (make-shareable-vector size :element-type '(unsigned-byte 8)) ;; abcl-1.6.2-dev, upcoming abcl-1.7.0
     338      (make-array size :element-type '(unsigned-byte 8))))
    298339
    299340(let ((method (jmethod "com.sun.jna.Pointer"
    300341                       (jna-setter :char) "long" (jna-setter-arg-type :char))))
     
    314355
    315356(defmacro with-pointer-to-vector-data ((ptr-var vector) &body body)
    316357  "Bind PTR-VAR to a foreign pointer to the data in VECTOR."
    317   (let ((vector-sym (gensym "VECTOR")))
    318     `(let ((,vector-sym ,vector))
    319        (with-foreign-pointer (,ptr-var (length ,vector-sym))
    320          (copy-to-foreign-vector ,vector-sym ,ptr-var)
    321          (unwind-protect
    322               (progn ,@body)
    323            (copy-from-foreign-vector ,vector-sym ,ptr-var))))))
     358  (let ((vector-sym (gensym "VECTOR"))
     359        (heap-pointer (gethash vector *static-vector-pointer*)))
     360    (if heap-pointer
     361        `(let ((,ptr-var ,heap-pointer))
     362           (progn ,@body))
     363        `(let ((,vector-sym ,vector))
     364           (with-foreign-pointer (,ptr-var (length ,vector-sym))
     365             (copy-to-foreign-vector ,vector-sym ,ptr-var)
     366             (unwind-protect
     367                  (progn ,@body)
     368               (copy-from-foreign-vector ,vector-sym ,ptr-var)))))))
    324369
    325370;;;# Dereferencing
    326371
Note: See TracBrowser for help on using the repository browser.