remove acquirer list for mmap regions in use, refcount is enough
This commit is contained in:
parent
e0939e9469
commit
3201ae5d8c
8 changed files with 57 additions and 76 deletions
|
|
@ -157,18 +157,18 @@ lumiera_file_mmapings (LumieraFile self)
|
|||
|
||||
|
||||
LumieraMMap
|
||||
lumiera_file_mmap_acquire (LumieraFile self, LList acquirer, off_t start, size_t size)
|
||||
lumiera_file_mmap_acquire (LumieraFile self, off_t start, size_t size)
|
||||
{
|
||||
TRACE (file_dbg);
|
||||
return lumiera_mmapings_mmap_acquire (lumiera_file_mmapings (self), self, acquirer, start, size);
|
||||
return lumiera_mmapings_mmap_acquire (lumiera_file_mmapings (self), self, start, size);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
lumiera_file_release_mmap (LumieraFile self, LList acquirer, LumieraMMap map)
|
||||
lumiera_file_release_mmap (LumieraFile self, LumieraMMap map)
|
||||
{
|
||||
TRACE (file_dbg);
|
||||
lumiera_mmapings_release_mmap (lumiera_file_mmapings (self), acquirer, map);
|
||||
lumiera_mmapings_release_mmap (lumiera_file_mmapings (self), map);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -150,24 +150,22 @@ lumiera_file_handle_release (LumieraFile self);
|
|||
/**
|
||||
* acquire a mmap which covers the given range
|
||||
* @param self file from where the mmap shall be acquired
|
||||
* @param acquirer list node of the new owner which will registered in the mmap
|
||||
* @param start begin of the required range
|
||||
* @param size requested size
|
||||
* @return MMap object covering the requested range or NULL on error
|
||||
* note: the chunksize for the file must be set prior accessing mmaps
|
||||
*/
|
||||
LumieraMMap
|
||||
lumiera_file_mmap_acquire (LumieraFile self, LList acquirer, off_t start, size_t size);
|
||||
lumiera_file_mmap_acquire (LumieraFile self, off_t start, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* release a previously acquired MMap object
|
||||
* @param self file to which the map belongs
|
||||
* @param acquirer holding node, used on require
|
||||
* @param map object to be released
|
||||
*/
|
||||
void
|
||||
lumiera_file_release_mmap (LumieraFile self, LList acquirer, LumieraMMap map);
|
||||
lumiera_file_release_mmap (LumieraFile self, LumieraMMap map);
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -177,18 +175,17 @@ lumiera_file_release_mmap (LumieraFile self, LList acquirer, LumieraMMap map);
|
|||
* @param size the length of the requested block
|
||||
* @param addr name of a void* variable pointing to the requested memory
|
||||
*/
|
||||
#define LUMIERA_FILE_MMAP_SECTION(file, start, size, addr) \
|
||||
for (LLIST_AUTO(user_##__LINE__); user_##__LINE__.next; user_##__LINE__.next = NULL) \
|
||||
for (LumieraMMap map_##__LINE__ = \
|
||||
lumiera_file_mmap_acquire (file, &user_##__LINE__, start, size); \
|
||||
map_##__LINE__; \
|
||||
({ \
|
||||
lumiera_file_release_mmap (file, &user_##__LINE__, map_##__LINE__); \
|
||||
map_##__LINE__ = NULL; \
|
||||
})) \
|
||||
for (void* addr = lumiera_mmap_address (map_##__LINE__, start); \
|
||||
addr; \
|
||||
addr = NULL)
|
||||
#define LUMIERA_FILE_MMAP_SECTION(file, start, size, addr) \
|
||||
for (LumieraMMap map_##__LINE__ = \
|
||||
lumiera_file_mmap_acquire (file, start, size); \
|
||||
map_##__LINE__; \
|
||||
({ \
|
||||
lumiera_file_release_mmap (file, map_##__LINE__); \
|
||||
map_##__LINE__ = NULL; \
|
||||
})) \
|
||||
for (void* addr = lumiera_mmap_address (map_##__LINE__, start); \
|
||||
addr; \
|
||||
addr = NULL)
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -192,7 +192,7 @@ lumiera_mmap_init (LumieraMMap self, LumieraFile file, off_t start, size_t size)
|
|||
self->size = length;
|
||||
self->address = addr;
|
||||
self->refmap = lumiera_calloc ((length-1)/chunksize+1, sizeof (unsigned short));
|
||||
self->refcnt = 1;
|
||||
self->refcnt = 0;
|
||||
lumiera_mmapcache_announce (lumiera_mcache, self);
|
||||
|
||||
lumiera_file_handle_release (file);
|
||||
|
|
@ -228,6 +228,7 @@ lumiera_mmap_delete (LumieraMMap self)
|
|||
TRACE (mmap_dbg);
|
||||
if (self)
|
||||
{
|
||||
REQUIRE (!self->refcnt);
|
||||
lumiera_mmapcache_forget (lumiera_mcache, self);
|
||||
|
||||
/* The matching mappings->lock must be hold or being irrelevant (mappings destructor) here, we can't asset this from here, good luck */
|
||||
|
|
|
|||
|
|
@ -52,7 +52,7 @@ typedef lumiera_mmap* LumieraMMap;
|
|||
*/
|
||||
struct lumiera_mmap_struct
|
||||
{
|
||||
/** used for the mrucache when checked in the cache OR for attaching owners when checked out **/
|
||||
/** used for the mrucache when checked in the cache **/
|
||||
llist cachenode;
|
||||
|
||||
/** all mmaps of a filedescriptor are chained in this list, used to find ranges **/
|
||||
|
|
@ -63,10 +63,10 @@ struct lumiera_mmap_struct
|
|||
void* address;
|
||||
|
||||
/** accumulated references, this is 0 when checked into the cache **/
|
||||
unsigned long refcnt;
|
||||
long refcnt;
|
||||
|
||||
/** array with refcounters per chunk **/
|
||||
unsigned short* refmap; // TODO flexible array?
|
||||
short* refmap; // TODO flexible array?
|
||||
};
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -137,12 +137,12 @@ LumieraMMap
|
|||
lumiera_mmapcache_checkout (LumieraMMapcache self, LumieraMMap handle)
|
||||
{
|
||||
TRACE (mmapcache_dbg);
|
||||
REQUIRE (handle->refcnt == 0);
|
||||
|
||||
LUMIERA_MUTEX_SECTION (mutex_sync, &self->lock)
|
||||
{
|
||||
TODO ("cached stats");
|
||||
lumiera_mrucache_checkout (&self->cache, &handle->cachenode);
|
||||
++handle->refcnt;
|
||||
}
|
||||
|
||||
return handle;
|
||||
|
|
@ -153,11 +153,11 @@ void
|
|||
lumiera_mmapcache_checkin (LumieraMMapcache self, LumieraMMap handle)
|
||||
{
|
||||
TRACE (mmapcache_dbg);
|
||||
REQUIRE (handle->refcnt == 0);
|
||||
|
||||
LUMIERA_MUTEX_SECTION (mutex_sync, &self->lock)
|
||||
{
|
||||
TODO ("cached stats");
|
||||
--handle->refcnt;
|
||||
lumiera_mrucache_checkin (&self->cache, &handle->cachenode);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -87,7 +87,7 @@ lumiera_mmapings_delete (LumieraMMapings self)
|
|||
|
||||
|
||||
LumieraMMap
|
||||
lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, LList acquirer, off_t start, size_t size)
|
||||
lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, off_t start, size_t size)
|
||||
{
|
||||
TRACE (mmapings_dbg);
|
||||
|
||||
|
|
@ -96,8 +96,6 @@ lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, LList acq
|
|||
if (self)
|
||||
LUMIERA_MUTEX_SECTION (mutex_sync, &self->lock)
|
||||
{
|
||||
REQUIRE (llist_is_empty (acquirer));
|
||||
|
||||
/* find first matching mmap, crude way */
|
||||
LLIST_FOREACH (&self->mmaps, node)
|
||||
{
|
||||
|
|
@ -130,22 +128,25 @@ lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, LList acq
|
|||
TODO ("sort search list?");
|
||||
}
|
||||
|
||||
llist_insert_head (&ret->cachenode, acquirer);
|
||||
}
|
||||
++ret->refcnt;
|
||||
|
||||
PLANNED ("use refmap for finer grained refcounting");
|
||||
|
||||
ENSURE (llist_is_empty(&ret->cachenode));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
void
|
||||
lumiera_mmapings_release_mmap (LumieraMMapings self, LList acquirer, LumieraMMap map)
|
||||
lumiera_mmapings_release_mmap (LumieraMMapings self, LumieraMMap map)
|
||||
{
|
||||
TRACE (mmapings_dbg);
|
||||
|
||||
if (self)
|
||||
LUMIERA_MUTEX_SECTION (mutex_sync, &self->lock)
|
||||
{
|
||||
llist_unlink (acquirer);
|
||||
if (llist_is_empty (&map->cachenode))
|
||||
if (!--map->refcnt)
|
||||
{
|
||||
TRACE (mmapcache_dbg, "checkin");
|
||||
lumiera_mmapcache_checkin (lumiera_mcache, map);
|
||||
|
|
|
|||
|
|
@ -86,16 +86,17 @@ lumiera_mmapings_new (LumieraFile file, size_t chunksize);
|
|||
void
|
||||
lumiera_mmapings_delete (LumieraMMapings self);
|
||||
|
||||
|
||||
/**
|
||||
* acquire a mmap which covers the given range
|
||||
* @param self mmapings where to search
|
||||
* @param acquirer list node of the new owner which will registered in the mmap
|
||||
* @param start begin of the required range
|
||||
* @param size requested size
|
||||
* @return MMap object covering the requested range or NULL on error
|
||||
*/
|
||||
LumieraMMap
|
||||
lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, LList acquirer, off_t start, size_t size);
|
||||
lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, off_t start, size_t size);
|
||||
|
||||
|
||||
/**
|
||||
* release a previously acquired MMap object
|
||||
|
|
@ -104,7 +105,10 @@ lumiera_mmapings_mmap_acquire (LumieraMMapings self, LumieraFile file, LList acq
|
|||
* @param map object to be released
|
||||
*/
|
||||
void
|
||||
lumiera_mmapings_release_mmap (LumieraMMapings self, LList acquirer, LumieraMMap map);
|
||||
lumiera_mmapings_release_mmap (LumieraMMapings self, LumieraMMap map);
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -131,11 +131,8 @@ TEST ("mmap_forget_releasing")
|
|||
|
||||
LumieraMMapings mmaps = lumiera_file_mmapings (file);
|
||||
|
||||
llist user;
|
||||
llist_init (&user);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, &user, 0, 100);
|
||||
|
||||
(void) map; //lumiera_mmapings_release_mmap (mmaps, &user, mmap);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
|
|
@ -153,11 +150,9 @@ TEST ("mmap_simple")
|
|||
|
||||
LumieraMMapings mmaps = lumiera_file_mmapings (file);
|
||||
|
||||
llist user;
|
||||
llist_init (&user);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, &user, 0, 100);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
|
||||
lumiera_mmapings_release_mmap (mmaps, &user, map);
|
||||
lumiera_mmapings_release_mmap (mmaps, map);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
|
||||
|
|
@ -180,19 +175,15 @@ TEST ("mmap_checkout_twice")
|
|||
|
||||
LumieraMMapings mmaps = lumiera_file_mmapings (file);
|
||||
|
||||
llist user;
|
||||
llist_init (&user);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, &user, 0, 100);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
|
||||
llist user2;
|
||||
llist_init (&user2);
|
||||
LumieraMMap map2 = lumiera_mmapings_mmap_acquire (mmaps, file, &user2, 0, 100);
|
||||
LumieraMMap map2 = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
|
||||
ENSURE (map->address == map2->address);
|
||||
|
||||
lumiera_mmapings_release_mmap (mmaps, &user, map);
|
||||
lumiera_mmapings_release_mmap (mmaps, map);
|
||||
|
||||
lumiera_mmapings_release_mmap (mmaps, &user2, map2);
|
||||
lumiera_mmapings_release_mmap (mmaps, map2);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
|
||||
|
|
@ -215,15 +206,11 @@ TEST ("mmap_checkout_again")
|
|||
|
||||
LumieraMMapings mmaps = lumiera_file_mmapings (file);
|
||||
|
||||
llist user;
|
||||
llist_init (&user);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, &user, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, &user, map);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, map);
|
||||
|
||||
llist user2;
|
||||
llist_init (&user2);
|
||||
LumieraMMap map2 = lumiera_mmapings_mmap_acquire (mmaps, file, &user2, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, &user2, map2);
|
||||
LumieraMMap map2 = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, map2);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
|
||||
|
|
@ -247,11 +234,8 @@ TEST ("mmap_grow_existing_file")
|
|||
|
||||
LumieraMMapings mmaps = lumiera_file_mmapings (file);
|
||||
|
||||
llist user;
|
||||
llist_init (&user);
|
||||
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, &user, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, &user, map);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, map);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
|
||||
|
|
@ -274,11 +258,8 @@ TEST ("mmap_readonly_file")
|
|||
|
||||
LumieraMMapings mmaps = lumiera_file_mmapings (file);
|
||||
|
||||
llist user;
|
||||
llist_init (&user);
|
||||
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, &user, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, &user, map);
|
||||
LumieraMMap map = lumiera_mmapings_mmap_acquire (mmaps, file, 0, 100);
|
||||
lumiera_mmapings_release_mmap (mmaps, map);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
|
||||
|
|
@ -299,16 +280,13 @@ TEST ("file_access")
|
|||
LumieraFile file = lumiera_file_new (",tmp-filemmap", LUMIERA_FILE_RECREATE);
|
||||
lumiera_file_chunksize_set (file, 4096);
|
||||
|
||||
llist user;
|
||||
llist_init (&user);
|
||||
|
||||
LumieraMMap map = lumiera_file_mmap_acquire (file, &user, 10, 100);
|
||||
LumieraMMap map = lumiera_file_mmap_acquire (file, 10, 100);
|
||||
|
||||
char* addr = lumiera_mmap_address (map, 20);
|
||||
|
||||
strcpy (addr, "test");
|
||||
|
||||
lumiera_file_release_mmap (file, &user, map);
|
||||
lumiera_file_release_mmap (file, map);
|
||||
|
||||
lumiera_file_delete (file);
|
||||
lumiera_backend_destroy ();
|
||||
|
|
|
|||
Loading…
Reference in a new issue