Re: [Chicken-users] Making stack-allocated Chicken-managed objects from C

2012-03-10 Thread Felix
 I have been poking into the chicken-bind egg and I'd like to modify it
 slightly for my libraries' (Box2D, Chipmunk) heavy use of structs.
 
 Chicken-bind will generate helper utils for making C-structs inside
 Chicken. Please take a peek at
 
 http://paste.call-cc.org/paste?id=d8e38d5afb7daff73c5957e91dff21c6ee02d415
 
 My C-snipped in foreign-primitive that's doing the stack-allocation is
 heavily inspired by
 http://wiki.call-cc.org/allocating-c-structures-under-control-of-the-chicken-gc.
 However, I've been getting feedback about this approach about it not being
 completely safe because it can't guarantee the stack won't overflow. From
 what I can make out of the docs, foreign-primitive automatically does a
 minor GC and we should be safe.

As John already wrote, allocating structs on the stack are very unlikely to
cause an overflow, unless the structs are extremely large. Note that C_alloc
gets the number of words as argument, not the number of bytes.

 
 2. So let's say that we drop C_alloc for being unsafe. Could C_alloc be
 replaced with C_malloc and at least we'd get the struct/blob automatically
 garbage-collected by Chicken? Or are scheme-objects reserved for
 stack-allocated pointers?

C_malloc ist just an alias for malloc(3), the memory allocated by it
is not GC'd (it is foreign to the Scheme runtime system). Otherwise
Scheme objects may live on the stack or on the GC'd heap.

 
 3. When C-code returns a new scheme-object, does Chicken treat it like any
 other scheme-object created from within Chicken? (Along with GC and all the
 rest of it)

Yes. If the object is on the stack and remains reachable on the next
(minor) collection, it will be moved into the heap. If it is on the
heap it will be subject to normal GC and move on (major)
collections. If the object is not on the stack or the GC'd heap (when
it is foreign), it will simply be ignored by the garbage collector,
but slots containing pointers to stack- or GC'd-heap-allocated data
inside a foreign object will be invalid.

 
 4. And just for clarity, is there any difference between
 
 C_bytes *ab = C_alloc( .. size ..) ; vs.
 C_bytes ab [ .. size ... ];  ?

No, it is basically the same, depending on the C compiler.

 
 5. And finally, how fast is stack-allocation/C_alloc compared to
 heap-allocation/C_malloc? (I'm interested in very small structs here!)

Stack allocation is very fast, because it justs needs to bump a
register. Of course pointers to the allocated memory remain only valid
until the stack is unwound (in the next minor GC).


cheers,
felix

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


[Chicken-users] Making stack-allocated Chicken-managed objects from C

2012-03-06 Thread Kristian Lein-Mathisen
Hi guys!

I would like to get a deeper understanding of Chicken's GC and its
stack-allocation feature. I've numbered by questions, feel free to answer
just one or two of them!

I have been poking into the chicken-bind egg and I'd like to modify it
slightly for my libraries' (Box2D, Chipmunk) heavy use of structs.

Chicken-bind will generate helper utils for making C-structs inside
Chicken. Please take a peek at

http://paste.call-cc.org/paste?id=d8e38d5afb7daff73c5957e91dff21c6ee02d415

My C-snipped in foreign-primitive that's doing the stack-allocation is
heavily inspired by
http://wiki.call-cc.org/allocating-c-structures-under-control-of-the-chicken-gc.
However, I've been getting feedback about this approach about it not being
completely safe because it can't guarantee the stack won't overflow. From
what I can make out of the docs, foreign-primitive automatically does a
minor GC and we should be safe.

1. Is this method completely safe? If not, why is that the case? If not,
how can you create blobs on the stack from C safely?

2. So let's say that we drop C_alloc for being unsafe. Could C_alloc be
replaced with C_malloc and at least we'd get the struct/blob automatically
garbage-collected by Chicken? Or are scheme-objects reserved for
stack-allocated pointers?

3. When C-code returns a new scheme-object, does Chicken treat it like any
other scheme-object created from within Chicken? (Along with GC and all the
rest of it)

4. And just for clarity, is there any difference between

C_bytes *ab = C_alloc( .. size ..) ; vs.
C_bytes ab [ .. size ... ];  ?

5. And finally, how fast is stack-allocation/C_alloc compared to
heap-allocation/C_malloc? (I'm interested in very small structs here!)



And for reference, an easier approach probably goes something like this,
where the blob is created in Chicken-land:

(*define* %make-point (foreign-primitive void
 (((c-pointer (struct point)) dest) (float x) (float y))
#ENDdest-x = x;dest-y = y;C_return();END))

(define (make-point x y)
(let ((loc (location (make-blob %get struct-size somehow%
   (%make-point loc x y)
loc))


This is what I'm looking for, but I'd love to see make-blob lowered into C
so that there is less overhead in creating structs (I'm a performance
junkie).  I've looked at runtime.c's C_allocate_vector and I must admit
don't understand much!

K.
___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Making stack-allocated Chicken-managed objects from C

2012-03-06 Thread John Cowan
Kristian Lein-Mathisen scripsit:

 My C-snipped in foreign-primitive that's doing the stack-allocation is
 heavily inspired by
 http://wiki.call-cc.org/allocating-c-structures-under-control-of-the-chicken-gc.
 However, I've been getting feedback about this approach about it not being
 completely safe because it can't guarantee the stack won't overflow. 

I'm not sure that concern is reasonable.  The maximum stack size before
GC is 256K on 32-bit systems and 1M on 64-bit systems, but the actual
limit on the C stack on modern systems is many megabytes; even on 32-bit
Windows it is 1M.  So C stack overflow isn't very likely.

 1. Is this method completely safe? If not, why is that the case? If not,
 how can you create blobs on the stack from C safely?

Since the stack is a limited resource, you cannot create Really Big blobs
on it safely.  In that situation, the heap is your only recourse.

-- 
A mosquito cried out in his pain,   John Cowan
A chemist has poisoned my brain!  http://www.ccil.org/~cowan
The cause of his sorrow co...@ccil.org
Was para-dichloro-
Diphenyltrichloroethane.(aka DDT)

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users


Re: [Chicken-users] Making stack-allocated Chicken-managed objects from C

2012-03-06 Thread Jim Ursetto
On Mar 6, 2012, at 10:31 AM, Kristian Lein-Mathisen wrote:

 (define %make-point (foreign-primitive void
(((c-pointer (struct point)) dest) 
 (float x) (float y))
 #END
 dest-x = x;
 dest-y = y;
 C_return();
 END
 ))
 
 (define (make-point x y) 
 (let ((loc (location (make-blob %get struct-size somehow%
(%make-point loc x y)
 loc))


%get struct-size somehow%
 - (foreign-value sizeof(struct point) int)

Avoid the locative by using scheme-pointer instead of c-pointer.

There's no reason I can think of to use foreign-primitive there instead of 
foreign-lambda*.

Ideally wrap the blob in a define-record for safety issues (not done below,
we stick with a bare pointer as in your example).

Code:

#
struct point { float x; float y; };
#

(define %make-point (foreign-lambda* void
((scheme-pointer b) (float x) (float y))
#END
((struct point *)b)-x = x;
((struct point *)b)-y = y;
END
))

(define (make-point x y)
  (let ((b (make-blob (foreign-value sizeof(struct point) int
(%make-point b x y)
b))

(define point-y (foreign-lambda* float ((scheme-pointer b))
 return(((struct point *)b)-y);))

(print (point-y (make-point 1.5 2.5)))

___
Chicken-users mailing list
Chicken-users@nongnu.org
https://lists.nongnu.org/mailman/listinfo/chicken-users