guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

mmap in guile -- guile memory management question


From: Daniel Ridge
Subject: mmap in guile -- guile memory management question
Date: Sun, 12 Nov 2006 18:02:11 -0500

Hi,

I use mmap in guile via a very simple C module and I have a piece of complicated Guile hackery that I would like to simplify. I'm hoping someone will embarrass me with 3 rational lines to solve my problem.

My problem is that I don't know how to manufacture a new Guile string with a pre-existing pointer (returned by mmap) and a length that I specify. Instead, I grab a string from Guile and whack its contents and length with my own and then put back a reasonable value in a guardian at GC time.

This isn't as inconvenient as it sounds -- I keep the guardian around to call munmap at GC time anyway.

Any ideas?

Regards,
        Dan Ridge

------ The hacky code ------

static SCM the_guardian;

SCM
guile_mmap_file_wrapper(SCM filename)
{
  ...
  void *addr;
  void *freeaddr;
  SCM scm_retval;
  ...

  ...
  addr=mmap(...);
  ...

  // guile actually does an allocation for null length strings
  scm_retval=gh_str2scm(NULL,0);
  freeaddr=SCM_CHARS(scm_retval);
  SCM_SET_CELL_WORD_1(scm_retval,addr);
  SCM_SET_STRING_LENGTH(scm_retval,size);
  // go free Scheme's string
  scm_must_free(freeaddr);

  // a special guardian to clean up mmaped strings
  gh_call1(the_guardian,scm_retval);
  return scm_retval;
}

static SCM
post_gc_mmap_reaper() {
  SCM cursor;

  while((cursor=gh_call0(the_guardian)) != SCM_BOOL_F) {
    munmap(SCM_CHARS(cursor),SCM_STRING_LENGTH(cursor));
    SCM_SET_STRING_LENGTH(cursor,0);
    // whip up a fake string to satisfy scheme's reaper
    SCM_SET_CELL_WORD_1(cursor,scm_must_malloc(0,"bogus"));
  }

  return SCM_BOOL_T;
}

void
mmap_init(void)
{
  the_guardian=scm_make_guardian(SCM_BOOL_T);
  scm_gc_protect_object(the_guardian);

scm_add_hook_x(gh_eval_str("after-gc-hook"),gh_new_procedure("post- gc-mmap-reaper",post_gc_mmap_reaper,0,0,0),SCM_BOOL_T);

  gh_new_procedure("mmap-file",guile_mmap_file_wrapper,1,0,0);
  gh_eval_str("(define-public mmap-file mmap-file)");
}


Regards,
        Dan Ridge




reply via email to

[Prev in Thread] Current Thread [Next in Thread]