#include "captive/macros.h"
#include <sys/mman.h>
#include "reactos/ddk/obfuncs.h"
+#include <stdlib.h>
static GHashTable *CaptiveSharedCacheMapObject_hash;
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;
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 */
- ¶m); /* 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,
{
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);
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;
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;