unofficial mirror of guile-user@gnu.org 
 help / color / mirror / Atom feed
* Proper way of making a single-pointer smob
@ 2013-05-29  6:16 Sun Yijiang
  2013-05-29 13:48 ` Panicz Maciej Godek
  2013-05-29 14:02 ` Mike Gran
  0 siblings, 2 replies; 7+ messages in thread
From: Sun Yijiang @ 2013-05-29  6:16 UTC (permalink / raw)
  To: guile-user

Hi guys,

I'm using a very simple smob which only carries a pointer in the
immediate word.  It works fine, but what worries me is that the free
function seems never called.   Am I doing anything wrong?  What's the
standard way of making such kind of smob?

C++ code listed below:

--------------------------------------
static scm_t_bits model_smob_t;

static SCM make_model() {
    return scm_new_smob(model_smob_t, (scm_t_bits)(new MyModel()));
}

static size_t free_model(SCM smob) {
    cout << "free_model" << endl;
    void* ptr = (void*)SCM_SMOB_DATA(smob);
    delete (MyModel*)ptr;
}

...

model_smob_t = scm_make_smob_type("model", 0);  // shall I use zero here?
scm_set_smob_free(type, free_model);

...

--------------------------------------

Regards,
Sun Yijiang



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Proper way of making a single-pointer smob
  2013-05-29  6:16 Proper way of making a single-pointer smob Sun Yijiang
@ 2013-05-29 13:48 ` Panicz Maciej Godek
  2013-05-29 14:02 ` Mike Gran
  1 sibling, 0 replies; 7+ messages in thread
From: Panicz Maciej Godek @ 2013-05-29 13:48 UTC (permalink / raw)
  To: Sun Yijiang; +Cc: guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1127 bytes --]

2013/5/29 Sun Yijiang <sunyijiang@gmail.com>

> Hi guys,
>
> I'm using a very simple smob which only carries a pointer in the
> immediate word.  It works fine, but what worries me is that the free
> function seems never called.   Am I doing anything wrong?  What's the
> standard way of making such kind of smob?
>
> C++ code listed below:
>
> --------------------------------------
> static scm_t_bits model_smob_t;
>
> static SCM make_model() {
>     return scm_new_smob(model_smob_t, (scm_t_bits)(new MyModel()));
> }
>
> static size_t free_model(SCM smob) {
>     cout << "free_model" << endl;
>     void* ptr = (void*)SCM_SMOB_DATA(smob);
>     delete (MyModel*)ptr;
> }
>
> ...
>
> model_smob_t = scm_make_smob_type("model", 0);  // shall I use zero here?
> scm_set_smob_free(type, free_model);
>
> ...
>
>
I bet you meant scm_set_smob_free(model_smob_t, free_model).
In scm_make_smob_type you should use sizeof(void *) instead of 0 (at leats
that's what works for me)
If you still don't get any messages, try replacing cout with cerr, or at
least flush the buffer.
You can also try to invoke (gc) manually.

Regards,
M.

[-- Attachment #2: Type: text/html, Size: 1877 bytes --]

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Proper way of making a single-pointer smob
  2013-05-29  6:16 Proper way of making a single-pointer smob Sun Yijiang
  2013-05-29 13:48 ` Panicz Maciej Godek
@ 2013-05-29 14:02 ` Mike Gran
  2013-05-29 21:57   ` Ludovic Courtès
  2013-05-31  3:08   ` Sun Yijiang
  1 sibling, 2 replies; 7+ messages in thread
From: Mike Gran @ 2013-05-29 14:02 UTC (permalink / raw)
  To: Sun Yijiang, guile-user@gnu.org

>Hi guys,


>I'm using a very simple smob which only carries a pointer in the
>immediate word.  It works fine, but what worries me is that the free
>function seems never called.   Am I doing anything wrong?  What's the
>standard way of making such kind of smob?


What you are doing is mostly right, except for this.


> model_smob_t = scm_make_smob_type("model", 0);  // shall I use zero here?

Your "0" should be sizeof(MyModel*)

But that's not the problem.

The problem is either
1. You still have a pointer to the smob somewhere.  You need to make
 sure that there are no pointers anywhere to the smob.
2. The garbage collector isn't being run.  Maybe you never allocate
enough memory to cause the gc to run.  You can fix this by adding
a "scm_gc()" call just before you program exits to force a garbage
collection.
3. Some versions of Guile have a bug where the last smob defined
in your program is never freed, even if you've cleared out the
pointers and called scm_gc.

-Mike



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Proper way of making a single-pointer smob
  2013-05-29 14:02 ` Mike Gran
@ 2013-05-29 21:57   ` Ludovic Courtès
  2013-05-30  7:10     ` Mike Gran
  2013-05-31  3:08   ` Sun Yijiang
  1 sibling, 1 reply; 7+ messages in thread
From: Ludovic Courtès @ 2013-05-29 21:57 UTC (permalink / raw)
  To: guile-user

Mike Gran <spk121@yahoo.com> skribis:

> 3. Some versions of Guile have a bug where the last smob defined
> in your program is never freed, even if you've cleared out the
> pointers and called scm_gc.

What is this?  I’d be happy to read more details.  :-)

Ludo’.




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Proper way of making a single-pointer smob
  2013-05-29 21:57   ` Ludovic Courtès
@ 2013-05-30  7:10     ` Mike Gran
  2013-05-30 11:56       ` Ludovic Courtès
  0 siblings, 1 reply; 7+ messages in thread
From: Mike Gran @ 2013-05-30  7:10 UTC (permalink / raw)
  To: Ludovic Courtès, guile-user@gnu.org

[-- Attachment #1: Type: text/plain, Size: 1084 bytes --]

> Mike Gran <spk121@yahoo.com> skribis:


>> 3. Some versions of Guile have a bug where the last smob defined
>> in your program is never freed, even if you've cleared out the
>> pointers and called scm_gc.

> What is this?  I’d be happy to read more details.  :-)

To be more specific, if you want to make sure the GC frees every smob,
you should call scm_gc before the program ends.

But, if you place the scm_gc call inside of a function
designated by C's atexit() function, instead of, say, at the end of 
main(), it may not free all the SMOBs.  I never investigated why.
I assumed it was a race.

So, it is probably not really a Guile bug, but, rather, that calling
scm_gc from within atexit() is a bad idea.

The program below gives me the following output in Guile 2.0.9

Allocating #1
Allocating #2
Allocating #3
Allocating #4
Allocating #5
Allocating #6
Allocating #7
Allocating #8
Allocating #9
Allocating #10
Freeing #5
Freeing #6
Freeing #3
Freeing #4
Freeing #2
Freeing #1
gc at exit
Freeing #9
Freeing #7
Freeing #8

-Mike

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #2: tmp.cc --]
[-- Type: text/x-c++src; name="tmp.cc", Size: 955 bytes --]

#include <libguile.h>
#include <stdio.h>

#define SIZE (1000000 * sizeof(int))
static scm_t_bits model_smob_t;

static size_t free_model(SCM smob)
{
    int* ptr = (int *)SCM_SMOB_DATA(smob);
    printf("Freeing #%d\n", *ptr);
    fflush(stdout);
    scm_gc_free (ptr, SIZE, "int array");
    ptr = NULL;
    return 0;
}

void func(void)
{
    printf("gc at exit\n");
    fflush(stdout);
    scm_gc();
}

int main (int argc, char ** argv)
{
    SCM s;

    atexit(func);
    scm_init_guile();
    
    model_smob_t = scm_make_smob_type("model", sizeof(int *));
    scm_set_smob_free(model_smob_t, free_model);
    for (int i = 1; i <= 10; i ++)
    {
        printf("Allocating #%d\n", i);
        int *ptr = (int *) scm_gc_malloc (SIZE, "int array");
        *ptr = i;
        SCM_NEWSMOB(s, model_smob_t, (scm_t_bits) ptr);
        s = SCM_BOOL_F;
    }
    
    // printf("gc at end of main\n");
    // fflush(stdout);
    //scm_gc();
    return 0;
}


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Proper way of making a single-pointer smob
  2013-05-30  7:10     ` Mike Gran
@ 2013-05-30 11:56       ` Ludovic Courtès
  0 siblings, 0 replies; 7+ messages in thread
From: Ludovic Courtès @ 2013-05-30 11:56 UTC (permalink / raw)
  To: Mike Gran; +Cc: guile-user@gnu.org

Mike Gran <spk121@yahoo.com> skribis:

> So, it is probably not really a Guile bug, but, rather, that calling
> scm_gc from within atexit() is a bad idea.

Oh, OK.  In general, I wouldn’t make any strong assumption as to
when/whether a SMOB free function will be called.

Ludo’.



^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Proper way of making a single-pointer smob
  2013-05-29 14:02 ` Mike Gran
  2013-05-29 21:57   ` Ludovic Courtès
@ 2013-05-31  3:08   ` Sun Yijiang
  1 sibling, 0 replies; 7+ messages in thread
From: Sun Yijiang @ 2013-05-31  3:08 UTC (permalink / raw)
  To: Mike Gran; +Cc: guile-user@gnu.org

Thank you guys, I got it through.

Best,
Yijiang

2013/5/29 Mike Gran <spk121@yahoo.com>:
>>Hi guys,
>
>
>>I'm using a very simple smob which only carries a pointer in the
>>immediate word.  It works fine, but what worries me is that the free
>>function seems never called.   Am I doing anything wrong?  What's the
>>standard way of making such kind of smob?
>
>
> What you are doing is mostly right, except for this.
>
>
>> model_smob_t = scm_make_smob_type("model", 0);  // shall I use zero here?
>
> Your "0" should be sizeof(MyModel*)
>
> But that's not the problem.
>
> The problem is either
> 1. You still have a pointer to the smob somewhere.  You need to make
>  sure that there are no pointers anywhere to the smob.
> 2. The garbage collector isn't being run.  Maybe you never allocate
> enough memory to cause the gc to run.  You can fix this by adding
> a "scm_gc()" call just before you program exits to force a garbage
> collection.
> 3. Some versions of Guile have a bug where the last smob defined
> in your program is never freed, even if you've cleared out the
> pointers and called scm_gc.
>
> -Mike



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2013-05-31  3:08 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-05-29  6:16 Proper way of making a single-pointer smob Sun Yijiang
2013-05-29 13:48 ` Panicz Maciej Godek
2013-05-29 14:02 ` Mike Gran
2013-05-29 21:57   ` Ludovic Courtès
2013-05-30  7:10     ` Mike Gran
2013-05-30 11:56       ` Ludovic Courtès
2013-05-31  3:08   ` Sun Yijiang

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).