remove acquirer list for mmap regions in use, refcount is enough

This commit is contained in:
Christian Thaeter 2010-02-13 17:16:45 +01:00
parent e0939e9469
commit 3201ae5d8c
8 changed files with 57 additions and 76 deletions

View file

@ -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);
}
/*

View file

@ -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)
/**

View file

@ -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 */

View file

@ -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?
};

View file

@ -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);
}
}

View file

@ -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);

View file

@ -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
/*

View file

@ -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 ();