diff --git a/src/backend/file.c b/src/backend/file.c index 4c42b9fa1..d70e88995 100644 --- a/src/backend/file.c +++ b/src/backend/file.c @@ -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); } /* diff --git a/src/backend/file.h b/src/backend/file.h index 8152523ca..820ce806d 100644 --- a/src/backend/file.h +++ b/src/backend/file.h @@ -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) /** diff --git a/src/backend/mmap.c b/src/backend/mmap.c index be3585872..dc98ea559 100644 --- a/src/backend/mmap.c +++ b/src/backend/mmap.c @@ -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 */ diff --git a/src/backend/mmap.h b/src/backend/mmap.h index 7c5712338..0e4145c74 100644 --- a/src/backend/mmap.h +++ b/src/backend/mmap.h @@ -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? }; diff --git a/src/backend/mmapcache.c b/src/backend/mmapcache.c index 0580fd1c4..1f3a79040 100644 --- a/src/backend/mmapcache.c +++ b/src/backend/mmapcache.c @@ -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); } } diff --git a/src/backend/mmapings.c b/src/backend/mmapings.c index cdf84ec63..17dbda1e9 100644 --- a/src/backend/mmapings.c +++ b/src/backend/mmapings.c @@ -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); diff --git a/src/backend/mmapings.h b/src/backend/mmapings.h index 1e21d03d3..0e4bea367 100644 --- a/src/backend/mmapings.h +++ b/src/backend/mmapings.h @@ -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 /* diff --git a/tests/backend/test-filemmap.c b/tests/backend/test-filemmap.c index 771094d47..981119af0 100644 --- a/tests/backend/test-filemmap.c +++ b/tests/backend/test-filemmap.c @@ -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 ();