I very much appreciate all the time you took to help me with this...It is an awesome system..and I learned alot. Quick ?...I noticed when I ran this:
(defcfun ("cv_create_Mat" create-mat) (%cv-mat :garbage-collect t))
a million times to bench mark it it was actually 4 times slower than my original code....I really do need this all to be fast code, since computer vision can benefit from the speed. Also I noticed when I ran the (create-mat) function 1,000,000 times my ram went up a tiny bit and didn't go down..Is that normal for finalizers. When I use with-* macros or manual MM I don't get an increase in ram on my system. I would like to include finalizers in my library but is there any way to overcome these obstacles to make that happen...Again the time you took to help me on this is much appreciated. :)You really helped me to understand.
On Sunday, April 20, 2014 8:14 AM, Willem Rein Oudshoorn woudshoo@xs4all.nl wrote:
Joeish W joeish80829@yahoo.com writes:
Thanks for your replies to my question, I was planning to go the trivial-garbage route and someone from CFFI-DEVEL kindly gave me this code to do GC automatically using my mat and del-mat functions
(defstruct (cvmatrix (:constructor %make-cvmatrix)) (sap (mat) :type sb-sys:system-area-pointer :read-only t))
(defun make-cvmatrix () (let* ((matrix (%make-cvmatrix)) (sap (cvmatrix-sap matrix))) (tg:finalize matrix (lambda (x) (del-mat sap))) matrix))
When I run the make-cvmatrix function to create a matrix it outputs a struct instead of a pointer like i needed. ...
You really do not want to return a pointer. For (at least) two reasons:
1 - It will make it much harder to use the functions in lisp because you do need to remember what they point to.
2 - It prevents automatic garbage collection of the underlying C objects.
However, if you really want to use direct C-pointers, the code is not ok, see below:
... I changed the last line of the make-cvmatrix function to be "sap" as below:
(tg:finalize matrix (lambda (x) (del-mat sap))) sap))
...and it appears to run poorly with only major variations in my ram levels which i suppose is just a result of lisps GC in process. Since I'm new to GC w/ trivial-garbage, I was hoping someone can verify first that the change to sap was an ok move.
No this change is NOT ok. Remember the tg:finalize will make sure that the code
(del-mat sap)
is called when 'matrix' is garbage collector.
In the first version, the function returned matrix and as long as matrix is alive, the del-mat is not callled.
In the second version, you do not return 'matrix' and as soon as the sap is returned, the 'matrix' is eligible for garbage collection and therefore you will get random crashes because the '(del-mat sap)' will be called while you are still using the returned SAP.
NOTE: The original code is WRONG, the lambda in 'tg:finalize' should NOT take any arguments so the original line should read
(tg:finalize matrix (lambda () (del-mat-sap)))
I was hoping someone could edit my code so I have a good example of Lisp GC with TG to work from and if I write a defcfun for this C wrapper :
Ok, here is some code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Tell CFFI of the existence of the 'Mat' C-type. ;;; ;;; This can be used as: ;;; ;;; - %cv-mat -- Which will not enable garbage collection of the C-mat. ;;; - (%cv-mat :garbage-collect t) -- Which will enable garbage collection.
(define-foreign-type cv-mat () ((garbage-collect :reader garbage-collect :initform nil :initarg :garbage-collect)) (:actual-type :pointer) (:simple-parser %cv-mat))
;;; Define the Lisp object corresponding to the 'Mat' C-Type
(defclass cv-matrix () ((c-pointer :reader c-pointer :initarg :c-pointer)))
;;; Translation between C pointers to the lisp cv-matrix
(defmethod translate-to-foreign ((lisp-value cv-matrix) (c-type cv-mat)) (c-pointer lisp-value))
(defmethod translate-from-foreign (c-pointer (c-type cv-mat)) (let ((matrix (make-instance 'cv-matrix :c-pointer c-pointer))) (when (garbage-collect c-type) (tg:finalize matrix (lambda () (del-mat c-pointer)))) matrix))
;;; C functions
(defcfun ("cv_delete_Mat" del-mat) :void (ptr %cv-mat))
(defcfun ("cv_create_Mat" create-mat) (%cv-mat :garbage-collect t))
(defcfun ("cv_create_Mat_typed" create-mat-typed) (%cv-mat :garbage-collect t) (rows :int) (cols :int) (type :int)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(defcfun ("cv_create_Mat_typed" mat-typed) (:pointer mat) "MAT constructor with a row, column and type parameter." (rows :int) (cols :int) (type :int))
show me where the rows cols type params get placed in an edited finalizer/constructor above..I would definately appreciate greatly:), concrete examples using the code I posted.
I do no understand what you mean here.
Wim Oudshoorn
Cffi-devel mailing list Cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel