discuss-gnuradio
[Top][All Lists]
Advanced

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

RE: [Discuss-gnuradio] binary installergnuradio-2.5cvs.win32.exeforwindo


From: Beck, Andrew Thomas - BECAT001
Subject: RE: [Discuss-gnuradio] binary installergnuradio-2.5cvs.win32.exeforwindows
Date: Fri, 12 Aug 2005 17:24:34 +0930

I've always had a test failure for gr_vmcircbuf_mmap_tmpfile_factory, but
never worried about it. Looking at it further, I think there was a similar
logic error there also. That is, it was reallocating the same addresses over
and over. Also, when allocating the second address within the loop, it wasn't
specifying the desired contiguous address range. This must have been an error.
Anyway, I've re-worked it in a similar vane to my createmapping mods. Since
I'm not at all familiar with these function calls, can somebody check this
before I submit a patch. My new version follows.

cheers,
andrew



gr_vmcircbuf_mmap_tmpfile::gr_vmcircbuf_mmap_tmpfile (int size)
  : gr_vmcircbuf (size)
{
#if !defined(HAVE_MMAP)
  fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: mmap or mkstemp is not available\n");
  throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
#else

  if (size <= 0 || (size % gr_pagesize ()) != 0){
    fprintf (stderr, "gr_vmcircbuf_mmap_tmpfile: invalid size = %d\n", size);
    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
  }

  int   seg_fd = -1;
  char  seg_name[1024];
 
  static int s_seg_counter = 0;


  // open a temporary file that we'll map in a bit later
  while (1){
    snprintf (seg_name, sizeof (seg_name),
              "%s/gnuradio-%d-%d-XXXXXX", gr_tmp_path (), getpid (), s_seg_counter);
    s_seg_counter++;

    seg_fd = open (seg_name, O_RDWR | O_CREAT | O_EXCL, 0600);
    if (seg_fd == -1){
      if (errno == EEXIST)      // File already exists (shouldn't happen).  Try again
        continue;

      char msg[1024];
      snprintf (msg, sizeof (msg),
                "gr_vmcircbuf_mmap_tmpfile: open [%s]", seg_name);
      perror (msg);
      throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
    }
    break;
  }

  if (unlink (seg_name) == -1){
    perror ("gr_vmcircbuf_mmap_tmpfile: unlink");
    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
  }

  // We've got a valid file descriptor to a tmp file.
  // Now set it's length to 2x what we really want and mmap it in.

  if (ftruncate (seg_fd, (off_t) 2 * size) == -1){
#ifndef WIN32
    close (seg_fd);                                             // cleanup
    perror ("gr_vmcircbuf_mmap_tmpfile: ftruncate (1)");
    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
#endif
  }

  void *first_copy = mmap (0, 2 * size,
                           PROT_READ | PROT_WRITE, MAP_SHARED,
                           seg_fd, (off_t) 0);

  if (first_copy == MAP_FAILED){
    close (seg_fd);                                             // cleanup
    perror ("gr_vmcircbuf_mmap_tmpfile: mmap (1)");
    throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
  }

    int i = 0;
    void *second_copy = NULL;
   
    while (i++ < 8 && ((char *) first_copy + size) != (char *)second_copy)
    {
        // unmap the 2nd half
        if (munmap ((char *) first_copy + size, size) == -1)
        {
            close (seg_fd);                                             // cleanup
            perror ("gr_vmcircbuf_mmap_tmpfile: munmap (1)");
            throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
        }

        // map the first half into the now available hole where the
        // second half used to be.

        second_copy = mmap ((char *) first_copy + size, size,
            PROT_READ | PROT_WRITE, MAP_SHARED,
                            seg_fd, (off_t) 0);

        if (second_copy == MAP_FAILED){
            close (seg_fd);                                             // cleanup
            perror ("gr_vmcircbuf_mmap_tmpfile: mmap (2)");
            throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
        }
 
#ifdef DEBUG
        fprintf (stderr,"gr_vmcircbuf_mmap_tmpfile: contiguous? mmap %p %p\n",
                                first_copy, second_copy, i);
#endif                                 

        if (((char *) first_copy + size) != (char *)second_copy)
        {
            if (munmap (first_copy, size) == -1)
            {
                close (seg_fd);                                         // cleanup
                perror ("gr_vmcircbuf_mmap_tmpfile: munmap (1)");
                throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
            }
       
            first_copy = second_copy;
        }
    }

 
    if (((char *) first_copy + size) != (char *)second_copy)
    {
        munmap (first_copy, size);
        munmap (second_copy, size);
        close (seg_fd);                                            // cleanup
        fprintf (stderr,"gr_vmcircbuf_mmap_tmpfile: non contiguous mmap %p %p\n",
                            first_copy, second_copy);
        throw std::runtime_error ("gr_vmcircbuf_mmap_tmpfile");
    }


    close (seg_fd);     // fd no longer needed.  The mapping is retained.

    // Now remember the important stuff

    d_base = (char *) first_copy;
    d_size = size;
#endif
}


reply via email to

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