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:
parent
c4cbde9853
commit
a8339fb5d0
4 changed files with 128 additions and 1 deletions
|
|
@ -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)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 ();
|
||||
|
|
|
|||
Loading…
Reference in a new issue