BrainDump
  Home arrow BrainDump arrow Using mmap() for Advanced File I/O
Dev Shed Forums  
Administration  
AJAX  
Apache  
BrainDump  
DHTML  
Flash  
Java  
JavaScript  
Multimedia  
MySQL  
Oracle  
Perl  
PHP  
Practices  
Python  
Reviews  
Security  
Smartphone Development  
Style-Sheets  
Web Services  
XML  
Zend  
Zope  
Mobile Linux  
App Generation ROI  
IBM® developerWorks  
Forums Sitemap  
E-Commerce Hosting  
Linux Web Hosting  
Managed Hosting  
Small Business Hosting  
VPS Hosting  
Weekly Newsletter

 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid  
Request Media Kit
Contact Us  
Site Map  
Privacy Policy  
Support  
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
BRAINDUMP

Using mmap() for Advanced File I/O
By: O'Reilly Media
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: starstarstarstarstar / 2
    2008-12-18


    Table of Contents:
  • Using mmap() for Advanced File I/O
  • Resizing a Mapping
  • Changing the Protection of a Mapping
  • Synchronizing a File with a Mapping
  • Giving Advice on a Mapping

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      error-file:tidyout.log Del.ici.ous error-file:tidyout.log Digg
      error-file:tidyout.log Blink error-file:tidyout.log Simpy
      error-file:tidyout.log Google error-file:tidyout.log Spurl
      error-file:tidyout.log Y! MyWeb error-file:tidyout.log Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article

     
     
    ADVERTISEMENT


    Using mmap() for Advanced File I/O
    ( Page 1 of 5 )

    In this fourth part of a seven-part series on Linux I/O file system calls, you will learn how to use mmap(). It is excerpted from chapter four of the book Linux System Programming: Talking Directly to the Kernel and C Library, written by Robert Love (O'Reilly, 2007; ISBN: 0596009585). Copyright © 2007 O'Reilly Media, Inc. All rights reserved. Used with permission from the publisher. Available from booksellers or direct from O'Reilly Media.

    Mapping Example

    Let’s consider a simple example program that uses mmap() to print a file chosen by the user to standard out:

      #include <stdio.h>
      #include <sys/types.h>
      #include <sys/stat.h>
      #include <fcntl.h>
      #include <unistd.h>
      #include <sys/mman.h>

      int main (int argc, char *argv[])
      {
             
    struct stat sb;
             
    off_t len;
             
    char *p;
             
    int fd;

              if (argc < 2) {
                     
    fprintf (stderr, "usage:
    %s <file>\n", argv[0]);
                     
    return 1;
             
    }

              fd = open (argv[1], O_RDONLY);
             
    if (fd == -1) {
                     
    perror ("open");
                     
    return 1;
             
    }

              if (fstat (fd, &sb) == -1) {
                     
    perror ("fstat");
                     
    return 1;
             
    }

              if (!S_ISREG (sb.st_mode)) {
                      fprintf (stderr, "%s is not a file\n", argv[1]);
                      return 1;
             
    }

              p = mmap (0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0);
             
    if (p == MAP_FAILED) {
                      perror ("mmap");
                      return 1;
             
    }

              if (close (fd) == -1) {
                      perror ("close");
                      return 1;
             
    }

              for (len = 0; len < sb.st_size; len++)
                      putchar (p[len]);

              if (munmap (p, sb.st_size) == -1) {
                      perror ("munmap");
                      return 1;
             
    }

              return 0;
      }

    The only unfamiliar system call in this example should be fstat() , which we will cover in Chapter 7. All you need to know at this point is that fstat() returns infor mation about a given file. The S_ISREG() macro can check some of this information, so that we can ensure that the given file is a regular file (as opposed to a device file or a directory) before we map it. The behavior of nonregular files when mapped depends on the backing device. Some device files are mmap-able; other nonregular files are not mmap-able, and will set errno to EACCESS .

    The rest of the example should be straightforward. The program is passed a filename as an argument. It opens the file, ensures it is a regular file, maps it, closes it, prints the file byte-by-byte to standard out, and then unmaps the file from memory.

    Advantages of mmap()

    Manipulating files via mmap() has a handful of advantages over the standard read() and write() system calls. Among them are:

    1. Reading from and writing to a memory-mapped file avoids the extraneous copy that occurs when using the read() or write() system calls, where the data must be copied to and from a user-space buffer.
    2. Aside from any potential page faults, reading from and writing to a memory-mapped file does not incur any system call or context switch overhead. It is as simple as accessing memory.
    3. When multiple processes map the same object into memory, the data is shared among all the processes. Read-only and shared writable mappings are shared in their entirety; private writable mappings have their not-yet-COW (copy-on-write) pages shared.
    4. Seeking around the mapping involves trivial pointer manipulations. There is no need for the lseek() system call.

    For these reasons, mmap() is a smart choice for many applications.

    Disadvantages of mmap()

    There are a few points to keep in mind when using mmap():

    1. Memory mappings are always an integer number of pages in size. Thus, the difference between the size of the backing file and an integer number of pages is “wasted” as slack space. For small files, a significant percentage of the mapping may be wasted. For example, with 4 KB pages, a 7 byte mapping wastes 4,089 bytes.
    2. The memory mappings must fit into the process’ address space. With a 32-bit address space, a very large number of various-sized mappings can result in fragmentation of the address space, making it hard to find large free contiguous regions. This problem, of course, is much less apparent with a 64-bit address space.
    3. There is overhead in creating and maintaining the memory mappings and associated data structures inside the kernel. This overhead is generally obviated by the elimination of the double copy mentioned in the previous section, particularly for larger and frequently accessed files.

    For these reasons, the benefits of mmap() are most greatly realized when the mapped file is large (and thus any wasted space is a small percentage of the total mapping), or when the total size of the mapped file is evenly divisible by the page size (and thus there is no wasted space).



     
     
    >>> More BrainDump Articles          >>> More By O'Reilly Media
     

       

    BRAINDUMP ARTICLES

    - Demystifying SELinux on Kernel 2.6
    - Yahoo and Microsoft Create Ad Partnership
    - The Advantages of Obscure Open Source Browse...
    - Dell Announces CSI-style Digital Forensics S...
    - Milepost GCC Speeds Open-Source Development
    - Learn These 10 Programming Languages
    - Tomcat Capacity Planning
    - Internal and External Performance Tuning wit...
    - Tomcat Benchmark Procedure
    - Benchmarking Tomcat Performance
    - Tomcat Performance Tuning
    - Wubi: Windows-based Ubuntu Installer
    - Configuring and Optimizing Your I/O Scheduler
    - Linux I/O Schedulers
    - Advising the Linux Kernel on File I/O





    © 2003-2009 by Developer Shed. All rights reserved. DS Cluster 5 Hosted by Hostway
    Stay green...Green IT