From 186857529ef189e9f3f44b567e07e75a9be38b9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 1 Aug 2005 14:24:58 +0000 Subject: [PATCH] cache_prefetch() now comes in two flavours: one with a direct vnode pointer, the other one with usual device/inode ID pair. Both versions now accept an offset/size pair to specify the region of the file to be prefetched - this may be turned into a file_vec_io array later on. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13866 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/file_cache.h | 3 +- src/system/kernel/cache/file_cache.cpp | 40 +++++++++++++++----------- 2 files changed, 26 insertions(+), 17 deletions(-) diff --git a/headers/private/kernel/file_cache.h b/headers/private/kernel/file_cache.h index 4e8918fb87..1ec48f613a 100644 --- a/headers/private/kernel/file_cache.h +++ b/headers/private/kernel/file_cache.h @@ -42,7 +42,8 @@ extern void cache_node_opened(void *vnode, int32 fdType, vm_cache_ref *cache, extern void cache_node_closed(void *vnode, int32 fdType, vm_cache_ref *cache, mount_id mountID, vnode_id vnodeID); extern void cache_node_launched(size_t argCount, char * const *args); -extern void cache_prefetch(mount_id mountID, vnode_id vnodeID); +extern void cache_prefetch_vnode(void *vnode, off_t offset, size_t size); +extern void cache_prefetch(mount_id mountID, vnode_id vnodeID, off_t offset, size_t size); extern status_t file_cache_init(void); extern vm_store *vm_create_vnode_store(void *vnode); diff --git a/src/system/kernel/cache/file_cache.cpp b/src/system/kernel/cache/file_cache.cpp index cafea72132..ff1c2f9ffb 100644 --- a/src/system/kernel/cache/file_cache.cpp +++ b/src/system/kernel/cache/file_cache.cpp @@ -611,21 +611,9 @@ file_cache_control(const char *subsystem, uint32 function, void *buffer, size_t extern "C" void -cache_prefetch(mount_id mountID, vnode_id vnodeID) +cache_prefetch_vnode(void *vnode, off_t offset, size_t size) { vm_cache_ref *cache; - void *vnode; - - // ToDo: schedule prefetch - // ToDo: maybe get 1) access type (random/sequential), 2) file vecs which blocks to prefetch - // for now, we just prefetch the first 64 kB - - TRACE(("cache_prefetch(vnode %ld:%Ld)\n", mountID, vnodeID)); - - // get the vnode for the object, this also grabs a ref to it - if (vfs_get_vnode(mountID, vnodeID, &vnode) != B_OK) - return; - if (vfs_get_vnode_cache(vnode, &cache) != B_OK) { vfs_vnode_release_ref(vnode); return; @@ -634,17 +622,20 @@ cache_prefetch(mount_id mountID, vnode_id vnodeID) file_cache_ref *ref = (struct file_cache_ref *)((vnode_store *)cache->cache->store)->file_cache_ref; off_t fileSize = cache->cache->virtual_size; - size_t size = 65536; if (size > fileSize) size = fileSize; + // we never fetch more than 4 MB at once + if (size > 4 * 1024 * 1024) + size = 4 * 1024 * 1024; + size_t bytesLeft = size, lastLeft = size; - off_t lastOffset = 0; + off_t lastOffset = offset; size_t lastSize = 0; mutex_lock(&cache->lock); - for (off_t offset = 0; bytesLeft > 0; offset += B_PAGE_SIZE) { + for (; bytesLeft > 0; offset += B_PAGE_SIZE) { // check if this page is already in memory addr_t virtualAddress; restart: @@ -677,6 +668,23 @@ cache_prefetch(mount_id mountID, vnode_id vnodeID) out: mutex_unlock(&cache->lock); +} + + +extern "C" void +cache_prefetch(mount_id mountID, vnode_id vnodeID, off_t offset, size_t size) +{ + void *vnode; + + // ToDo: schedule prefetch + + TRACE(("cache_prefetch(vnode %ld:%Ld)\n", mountID, vnodeID)); + + // get the vnode for the object, this also grabs a ref to it + if (vfs_get_vnode(mountID, vnodeID, &vnode) != B_OK) + return; + + cache_prefetch_vnode(vnode, offset, size); vfs_vnode_release_ref(vnode); }