captive_shared_cache_map_flush(): Improved performance.
authorshort <>
Mon, 3 Nov 2003 22:13:26 +0000 (22:13 +0000)
committershort <>
Mon, 3 Nov 2003 22:13:26 +0000 (22:13 +0000)
src/libcaptive/cc/sharedcachemap.c

index f9163ee..28d2267 100644 (file)
@@ -28,6 +28,7 @@
 #include "captive/macros.h"
 #include <sys/mman.h>
 #include "reactos/ddk/obfuncs.h"
+#include <stdlib.h>
 
 
 static GHashTable *CaptiveSharedCacheMapObject_hash;
@@ -650,25 +651,34 @@ CaptiveSharedCacheMapObject_page *page;
        page->lsn_newest=0;
 }
 
-typedef struct _captive_shared_cache_map_page_write_lsn_foreach_param captive_shared_cache_map_page_write_lsn_foreach_param;
-struct _captive_shared_cache_map_page_write_lsn_foreach_param {
+typedef struct _captive_shared_cache_map_flush_lsn_sort captive_shared_cache_map_flush_lsn_sort;
+struct _captive_shared_cache_map_flush_lsn_sort {
+       gint64 lsn;
+       CaptiveSharedCacheMapObject *captive_shared_cache_map_object;
+       guint64 offset;
+       };
+
+typedef struct _captive_shared_cache_map_flush_lsn_pages_foreach_param
+               captive_shared_cache_map_flush_lsn_pages_foreach_param;
+struct _captive_shared_cache_map_flush_lsn_pages_foreach_param {
        gint64 lsn_target;
-       gint64 lsn_best;
-       CaptiveSharedCacheMapObject *captive_shared_cache_map_object_best;
-       guint64 offset_best;
+       guint lsn_pages_count;
+       captive_shared_cache_map_flush_lsn_sort *lsn_pages_pointer;     /* Not filled in if NULL */
        };
 
-static void captive_shared_cache_map_page_write_lsn_foreach(
+static void captive_shared_cache_map_flush_lsn_pages_foreach(
                CaptiveSharedCacheMapObject *captive_shared_cache_map_object,  /* key */
                CaptiveSharedCacheMapObject *captive_shared_cache_map_object_value,  /* value */
-               captive_shared_cache_map_page_write_lsn_foreach_param *param)   /* user_data */
+               captive_shared_cache_map_flush_lsn_pages_foreach_param *param)  /* user_data */
 {
 guint64 now;
 CaptiveSharedCacheMapObject_page *page;
 
+#if 0  /* acceleration */
        g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
        g_return_if_fail(captive_shared_cache_map_object==captive_shared_cache_map_object_value);
        g_return_if_fail(param!=NULL);
+#endif
 
        for (now=0;now<captive_shared_cache_map_object->AllocationSize;now+=PAGE_SIZE) {
                page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
@@ -678,47 +688,27 @@ CaptiveSharedCacheMapObject_page *page;
                        continue;
                if (!page->lsn_newest)
                        continue;
-               if (page->lsn_newest>=param->lsn_target)
+               if (page->lsn_newest>param->lsn_target)
                        continue;
-               if (param->lsn_best && page->lsn_newest>param->lsn_best)
+               param->lsn_pages_count++;
+               if (!param->lsn_pages_pointer)
                        continue;
-               param->lsn_best=page->lsn_newest;
-               param->captive_shared_cache_map_object_best=captive_shared_cache_map_object;
-               param->offset_best=now;
+               param->lsn_pages_pointer->lsn=page->lsn_newest;
+               param->lsn_pages_pointer->captive_shared_cache_map_object=captive_shared_cache_map_object;
+               param->lsn_pages_pointer->offset=now;
+               param->lsn_pages_pointer++;
                }
 }
 
-static void captive_shared_cache_map_page_write_lsn(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
-               guint64 offset)
+static int captive_shared_cache_map_flush_lsn_pages_compar
+               (const captive_shared_cache_map_flush_lsn_sort *a,const captive_shared_cache_map_flush_lsn_sort *b)
 {
-CaptiveSharedCacheMapObject_page *page;
-
-       g_return_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object));
-       g_return_if_fail(captive_shared_cache_map_object->FileObject!=NULL);
-       g_return_if_fail(offset<CAPTIVE_ROUND_UP64(captive_shared_cache_map_object->AllocationSize,PAGE_SIZE));
-       g_return_if_fail(0==CAPTIVE_ROUND_DOWN_EXCEEDING64(offset,PAGE_SIZE));
-       page=captive_shared_cache_map_object->pages+offset/PAGE_SIZE;
-       g_return_if_fail(page->data_valid);
-       g_return_if_fail(page->dirty);
-
-       if (page->lsn_newest) {
-               CaptiveSharedCacheMapObject_hash_init();
-               for (;;) {
-captive_shared_cache_map_page_write_lsn_foreach_param param;
-
-                       param.lsn_target=page->lsn_newest;
-                       param.lsn_best=0;
-                       g_hash_table_foreach(
-                                       CaptiveSharedCacheMapObject_hash,       /* hash_table */
-                                       (GHFunc)captive_shared_cache_map_page_write_lsn_foreach,        /* func */
-                                       &param);        /* user_data */
-                       if (!param.lsn_best)
-                               break;
-                       captive_shared_cache_map_page_write(param.captive_shared_cache_map_object_best,param.offset_best);
-                       }
-               }
+#if 0  /* acceleration */
+       g_return_val_if_fail(a!=NULL,0);
+       g_return_val_if_fail(b!=NULL,0);
+#endif
 
-       captive_shared_cache_map_page_write(captive_shared_cache_map_object,offset);
+       return (a->lsn>b->lsn)-(b->lsn>a->lsn);
 }
 
 guint64 captive_shared_cache_map_flush(CaptiveSharedCacheMapObject *captive_shared_cache_map_object,
@@ -726,6 +716,11 @@ guint64 captive_shared_cache_map_flush(CaptiveSharedCacheMapObject *captive_shar
 {
 guint64 flushed;
 guint64 now;
+gint lsn_target;
+captive_shared_cache_map_flush_lsn_pages_foreach_param lsn_pages_foreach_param;
+captive_shared_cache_map_flush_lsn_sort *lsn_pages_pointer;
+const captive_shared_cache_map_flush_lsn_sort *lsn_page;
+guint lsn_pages_count;
 
        g_return_val_if_fail(CAPTIVE_SHARED_CACHE_MAP_IS_OBJECT(captive_shared_cache_map_object),0);
        g_return_val_if_fail(start<=end,0);
@@ -735,21 +730,75 @@ guint64 now;
        start=CAPTIVE_ROUND_DOWN64(start,PAGE_SIZE);
        end=CAPTIVE_ROUND_UP64(end,PAGE_SIZE);
 
+       lsn_target=0;
+       for (now=start;now<end;now+=PAGE_SIZE) {
+CaptiveSharedCacheMapObject_page *page;
+
+               page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
+               if (!page->data_valid)
+                       continue;
+               if (!page->dirty)
+                       continue;
+               if (!page->lsn_newest)
+                       continue;
+               if (!lsn_target || lsn_target<page->lsn_newest)
+                       lsn_target=page->lsn_newest;
+               }
+
+       lsn_pages_foreach_param.lsn_target=lsn_target;
+       lsn_pages_foreach_param.lsn_pages_count=0;
+       lsn_pages_foreach_param.lsn_pages_pointer=NULL; /* Not yet filling */
+       g_hash_table_foreach(
+                       CaptiveSharedCacheMapObject_hash,       /* hash_table */
+                       (GHFunc)captive_shared_cache_map_flush_lsn_pages_foreach,       /* func */
+                       &lsn_pages_foreach_param);      /* user_data */
+
+       lsn_pages_count=lsn_pages_foreach_param.lsn_pages_count;
+       captive_newn(lsn_pages_pointer,lsn_pages_count);
+       g_assert(lsn_pages_foreach_param.lsn_target==lsn_target);
+       lsn_pages_foreach_param.lsn_pages_count=0;
+       lsn_pages_foreach_param.lsn_pages_pointer=lsn_pages_pointer;
+       g_hash_table_foreach(
+                       CaptiveSharedCacheMapObject_hash,       /* hash_table */
+                       (GHFunc)captive_shared_cache_map_flush_lsn_pages_foreach,       /* func */
+                       &lsn_pages_foreach_param);      /* user_data */
+
+       g_assert(lsn_pages_foreach_param.lsn_target==lsn_target);
+       g_assert(lsn_pages_foreach_param.lsn_pages_count==lsn_pages_count);
+       g_assert(lsn_pages_foreach_param.lsn_pages_pointer==lsn_pages_pointer+lsn_pages_count);
+
+       qsort(lsn_pages_pointer,lsn_pages_count,sizeof(*lsn_pages_pointer),
+                       (int (*)(const void *,const void *))captive_shared_cache_map_flush_lsn_pages_compar);
+
        flushed=0;
+
+       for (lsn_page=lsn_pages_pointer;lsn_page<lsn_pages_pointer+lsn_pages_count;lsn_page++) {
+               captive_shared_cache_map_page_write(lsn_page->captive_shared_cache_map_object,lsn_page->offset);
+               flushed+=PAGE_SIZE;
+               }
+
+       g_free(lsn_pages_pointer);
+
        for (now=start;now<end;now+=PAGE_SIZE) {
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
+CaptiveSharedCacheMapObject_page *page;
+
+               page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
+               if (!page->data_valid)
                        continue;
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty)
+               if (!page->dirty)
                        continue;
-               captive_shared_cache_map_page_write_lsn(captive_shared_cache_map_object,now);
+               captive_shared_cache_map_page_write(captive_shared_cache_map_object,now);
                flushed+=PAGE_SIZE;
                }
 
        /* We were calling W32 code - recheck our task completion. */
        for (now=start;now<end;now+=PAGE_SIZE) {
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
+CaptiveSharedCacheMapObject_page *page;
+
+               page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
+               if (!page->data_valid)
                        continue;
-               g_assert(!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty);
+               g_assert(!page->dirty);
                }
 
        return flushed;
@@ -767,9 +816,12 @@ guint64 now;
        g_return_if_fail(dirty_foundp!=NULL);
 
        for (now=0;now<captive_shared_cache_map_object->AllocationSize;now+=PAGE_SIZE) {
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].data_valid)
+CaptiveSharedCacheMapObject_page *page;
+
+               page=captive_shared_cache_map_object->pages+now/PAGE_SIZE;
+               if (!page->data_valid)
                        continue;
-               if (!captive_shared_cache_map_object->pages[now/PAGE_SIZE].dirty)
+               if (!page->dirty)
                        continue;
                *dirty_foundp=TRUE;     /* FIXME: stop the traversal. */
                break;