From: Raymond Toy
Subject: Allocating large alien objects in CMU Lisp
Date: 
Message-ID: <4n91c2522e.fsf@rtp.ericsson.se>
A while back, I posted an article/query about how to allocate large
alien objects in CMU Lisp.  This is just a note to say what I've
discovered.

There is an upper limit because of the architecture of CMU Lisp. By
default it mmaps some memory near the 8 MB mark, so you can't malloc
more than about 8 MB. 

For what I wanted to do, I've come up with a work around.  I wanted to
work with 1-D simple-array's of single- and double-floats and wanted
to pass them to some alien functions.  Here is how I do it now, by
directly accessing the Lisp storage for the 1-D array.

VECTOR-DATA-ADDRESS returns the physical address of where the actual
data of a vector is stored.  The result is an (unsigned-byte 32).  To
get this address to an alien function, simply use something like 

	(system:int-sap (vector-data-address vec))

This returns a system area pointer that can then be immediately used
as is as an alien pointer.

For more details, get the LaTeX version of the CMU documentation.  The
info version is out-of-date, and leaves some things out that CMU can
actually do, like finalization and weak pointers.

I hope this helps some one out there.

Ray


(defun vector-data-address (vec)
  "Return the physical address of where the actual data of the vector
VEC is stored.

  VEC - must be a specialized array type in CMU Lisp.  This currently means
        VEC is a simple-array of one dimension of one of the following types:

                  double-float
                  single-float
                  (unsigned-byte 32)
                  (unsigned-byte 16)
                  (unsigned-byte  8)
                  (unsigned-byte  4)
                  (unsigned-byte  2)

Returns
  1   - physical address (unsigned-byte 32)"
  (declare (type (or (simple-array double-float (*))
		     (simple-array single-float (*))
		     (simple-array (unsigned-byte 32) (*))
		     (simple-array (unsigned-byte 16) (*))
		     (simple-array (unsigned-byte  8) (*))
		     (simple-array (unsigned-byte  4) (*))
		     (simple-array (unsigned-byte  2) (*))
		     )
		 vec))
  (let ((base-address (the (unsigned-byte 32)
			(logandc1 7 (kernel:get-lisp-obj-address vec)))))
    (declare (type (unsigned-byte 32) base-address))
    ;; For simple vectors, memory is laid out like this:
    ;;
    ;;   byte offset    Value
    ;;        0         type code (should be 70 for double-float vector)
    ;;        4         4 * number of elements in vector
    ;;        8         1st element of vector
    ;;       12         2nd element of vector
    ;;      ...         ...
    ;;
    
    (the (unsigned-byte 32) (+ 8 base-address))))