src/MemoryMap.cpp
author Jens Alfke <jens@mooseyard.com>
Sun Sep 20 21:25:47 2009 -0700 (2009-09-20)
changeset 2 851de24ecb61
parent 0 31a43d94cc26
permissions -rw-r--r--
Added library target, changed some build settings, and fixed 64-to-32-bit conversion warnings.
     1 /*
     2  *  MemoryMap.cpp
     3  *  Ottoman
     4  *
     5  *  Created by Jens Alfke on 9/17/09.
     6  *  Copyright 2009 Jens Alfke. All rights reserved.
     7  *  BSD-Licensed: See the file "LICENSE.txt" for details.
     8  */
     9 
    10 #include "MemoryMap.h"
    11 
    12 #include <errno.h>
    13 #include <stdio.h>
    14 #include <sys/mman.h>
    15 
    16 namespace Mooseyard {
    17 
    18     MemoryMap::~MemoryMap() {
    19         for (int i=0; i<_nRegions; i++)
    20             delete _regions[i];
    21         free(_regions);
    22     }
    23 
    24     void MemoryMap::mapRegion (off_t pos, size_t length) {
    25         off_t end = pos+length;
    26         for (int i=0; i<_nRegions; i++) {
    27             Region *region = _regions[i];
    28             if (region->position() <= pos) {
    29                 if (end <= region->end())
    30                     return;     // found an existing region covering this range
    31                 else if (region->setLength((size_t)(end - region->position())))
    32                     return;     // able to grow the existing region
    33             }
    34         }
    35         
    36         // No existing region, so add a new one:
    37         Region *region = new Region(_file, pos,length);
    38         _regions = (Region**) realloc(_regions, (_nRegions+1)*sizeof(*_regions));
    39         _regions[_nRegions++] = region;
    40     }
    41 
    42     const void* MemoryMap::_at (off_t pos) const {
    43         for (int i=0; i<_nRegions; i++) {
    44             const void *ptr = _regions[i]->mappedPosition(pos);
    45             if (ptr)
    46                 return ptr;
    47         }
    48         return NULL;
    49     }
    50     
    51     const void* MemoryMap::mappedPosition (off_t pos) const {
    52         const void *result = _at(pos);
    53         if (!result)
    54             throw File::Error("No memory mapped at this position");
    55         return result;
    56     }
    57 
    58     
    59     
    60     
    61     MemoryMap::Region::Region (File* file, off_t position, size_t length)
    62     :_file(file),
    63     _position(position),
    64     _length (length),
    65     _start( (const uint8_t*) ::mmap(NULL, length, PROT_READ, MAP_PRIVATE, file->_fd, position) )
    66     {
    67         printf("File#%i: Mapped (%6llu -- %6llu) --> %p\n", file->_fd, _position, end(), _start);
    68         if (_start==NULL || _start == MAP_FAILED) {
    69             _start = NULL;
    70             throw File::Error(errno, strerror(errno));
    71         }
    72     }
    73     
    74     MemoryMap::Region::~Region() {
    75         if (_start) {
    76             printf("File#%i: Unmapped (%6llu -- %6llu) from %p\n", _file->_fd, _position, end(), _start);
    77             ::munmap((void*)_start,_length);
    78         }
    79     }
    80     
    81     bool MemoryMap::Region::setLength (size_t length) {
    82         if (length != _length) {
    83             printf("File#%i: Resiging (%6llu -- %6llu) from %lu to %lu ...", 
    84                    _file->_fd, _position, end(), _length,length);
    85             if (::mmap((void*)_start, length, PROT_READ, MAP_PRIVATE | MAP_FIXED, _file->_fd, _position) == MAP_FAILED) {
    86                 printf("failed! errno=%i\n", errno);
    87                 return false;
    88             }
    89             printf("OK\n");
    90             _length = length;
    91         }
    92         return true;
    93     }
    94     
    95     const void* MemoryMap::Region::mappedPosition (off_t pos) {
    96         if (pos >= _position && pos < end())
    97             return _start + (pos-_position);
    98         else
    99             return NULL;
   100     }
   101     
   102     
   103 }