Re: [Chicken-users] Making stack-allocated Chicken-managed objects from C
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
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
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
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