add mmaping of exact blocks

namely file headers needs to be accessed unaligned and exactly as given,
this adds mmap functions to create mmap objects to do this.
This commit is contained in:
Christian Thaeter 2010-03-05 20:53:17 +01:00
parent c4cbde9853
commit a8339fb5d0
4 changed files with 128 additions and 1 deletions

View file

@ -214,6 +214,70 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size)
return NULL;
}
LumieraMMap
lumiera_mmap_init_exact (LumieraMMap self, LumieraFile file, off_t start, size_t size)
{
TRACE (mmap_dbg);
REQUIRE (self);
REQUIRE (file);
REQUIRE (start >= 0);
REQUIRE (size);
LumieraFiledescriptor descriptor = file->descriptor;
int fd = lumiera_file_handle_acquire (file);
TRACE (mmap_dbg, "got fd %d", fd);
if (fd == -1)
goto efile;
if ((off_t)(start + size) > descriptor->stat.st_size)
{
/* request past the end */
if ((descriptor->flags & O_ACCMODE) == O_RDWR)
{
/* extend file (writable) */
if (ftruncate (fd, start+size) == -1)
{
LUMIERA_ERROR_SET (mmap, ERRNO, lumiera_filedescriptor_name (file->descriptor));
goto etruncate;
};
descriptor->stat.st_size = descriptor->realsize = start+size;
}
}
TODO ("use resourcecllector here");
void* addr = mmap (NULL,
size,
(descriptor->flags & O_ACCMODE) == O_RDONLY ? PROT_READ : PROT_READ|PROT_WRITE,
MAP_SHARED,
fd,
start);
INFO_IF (addr==(void*)-1, mmap_dbg, "mmap failed %s", strerror (errno));
ENSURE (errno == 0 || errno == ENOMEM, "unexpected mmap error %s", strerror (errno));
llist_init (&self->cachenode);
llist_init (&self->searchnode);
self->start = start;
self->size = size;
self->address = addr;
self->refmap = NULL;
self->refcnt = 1;
lumiera_mmapcache_announce (self);
lumiera_file_handle_release (file);
return self;
etruncate:
efile:
lumiera_file_handle_release (file);
return NULL;
}
LumieraMMap
lumiera_mmap_new (LumieraFile file, off_t start, size_t size)
{
@ -231,6 +295,23 @@ lumiera_mmap_new (LumieraFile file, off_t start, size_t size)
}
LumieraMMap
lumiera_mmap_new_exact (LumieraFile file, off_t start, size_t size)
{
TRACE (mmap_dbg);
LumieraMMap self = lumiera_mmapcache_mmap_acquire ();
if (lumiera_mmap_init_exact (self, file, start, size))
return self;
else
{
lumiera_free (self);
return NULL;
}
}
void
lumiera_mmap_delete (LumieraMMap self)
{

View file

@ -69,14 +69,37 @@ struct lumiera_mmap_struct
short* refmap; // TODO flexible array?
};
/**
* Initialize a MMap object.
* The mmap objects are aligned and shifted by the chunksize and bias defined for the file
* @param self the mmap object to be initialized
* @param file file from which to map
* @param start offset in file which must be part of the mmaped region
* @param size minimum size after start to map
* @return self on success or NULL on error
*/
LumieraMMap
lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size);
/**
* Initialize a MMap object.
* Maps exactly the given range
* @param self the mmap object to be initialized
* @param file file from which to map
* @param start offset in file which must be part of the mmaped region
* @param size minimum size after start to map
* @return self on success or NULL on error
*/
LumieraMMap
lumiera_mmap_init_exact (LumieraMMap self, LumieraFile file, off_t start, size_t size);
LumieraMMap
lumiera_mmap_new (LumieraFile file, off_t start, size_t size);
LumieraMMap
lumiera_mmap_new_exact (LumieraFile file, off_t start, size_t size);
/**
* Translate a 'external' offset to a address in memory

View file

@ -40,6 +40,10 @@ TEST "accessing file" file_access <<END
return: 0
END
TEST "exact mmap" exact_mmap <<END
return: 0
END
TEST "mmaped secion" mmap_section <<END
return: 0
END

View file

@ -294,6 +294,25 @@ TEST (file_access)
TEST (exact_mmap)
{
lumiera_backend_init ();
LumieraFile file = lumiera_file_new (",tmp-filemmap", LUMIERA_FILE_RECREATE);
LumieraMMap map = lumiera_mmap_new_exact (file, 0, 6);
char* addr = lumiera_mmap_address (map, 1);
strcpy (addr, "test");
lumiera_mmap_delete (map);
lumiera_file_delete (file);
lumiera_backend_destroy ();
}
TEST (mmap_section)
{
lumiera_backend_init ();