From 9f6376a0c752eb965d97c400eb3bb27dbc102775 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Mon, 6 Mar 2006 16:18:52 +0000 Subject: [PATCH] * get_vnode() did not decrease the sUnusedVnodes counter when taking one node of that list. * Added a vfs_free_unused_vnodes() function that calls the low memory handler directly. * create_sem_etc() now calls the above function in case there are no semaphores available anymore; this usually frees up to 2 semaphores per node (one from the cache if there is a file cache attached, and eventually one from the file system). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16610 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/kernel/vfs.h | 1 + src/system/kernel/fs/vfs.cpp | 8 ++++++++ src/system/kernel/sem.c | 18 +++++++++++++++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/headers/private/kernel/vfs.h b/headers/private/kernel/vfs.h index 942e3ffd1e..d2c1518e15 100644 --- a/headers/private/kernel/vfs.h +++ b/headers/private/kernel/vfs.h @@ -96,6 +96,7 @@ status_t vfs_get_fs_node_from_path(mount_id mountID, const char *path, status_t vfs_stat_vnode(void *_vnode, struct stat *stat); status_t vfs_get_vnode_name(void *vnode, char *name, size_t nameSize); status_t vfs_get_cwd(mount_id *_mountID, vnode_id *_vnodeID); +void vfs_free_unused_vnodes(int32 level); /* special module convenience call */ status_t vfs_get_module_path(const char *basePath, const char *moduleName, diff --git a/src/system/kernel/fs/vfs.cpp b/src/system/kernel/fs/vfs.cpp index 1c7d7bccad..1ae241aeba 100644 --- a/src/system/kernel/fs/vfs.cpp +++ b/src/system/kernel/fs/vfs.cpp @@ -816,6 +816,7 @@ restart: if (vnode->ref_count == 0) { // this vnode has been unused before list_remove_item(&sUnusedVnodeList, vnode); + sUnusedVnodes--; } inc_vnode_ref_count(vnode); } else { @@ -2816,6 +2817,13 @@ vfs_get_cwd(mount_id *_mountID, vnode_id *_vnodeID) } +extern "C" void +vfs_free_unused_vnodes(int32 level) +{ + vnode_low_memory_handler(NULL, level); +} + + extern "C" bool vfs_can_page(void *_vnode, void *cookie) { diff --git a/src/system/kernel/sem.c b/src/system/kernel/sem.c index ff48ef16bb..2fd0e12b33 100644 --- a/src/system/kernel/sem.c +++ b/src/system/kernel/sem.c @@ -21,6 +21,8 @@ #include #include #include +#include +#include #include #include @@ -257,7 +259,21 @@ create_sem_etc(int32 count, const char *name, team_id owner) char *tempName; size_t nameLength; - if (sSemsActive == false || sUsedSems == sMaxSems) + if (sSemsActive == false) + return B_NO_MORE_SEMS; + + if (sUsedSems == sMaxSems) { + // The vnode cache may have collected lots of semaphores. + // Freeing some unused vnodes should improve our situation. + // TODO: maybe create a generic "low resources" handler, instead + // of only the specialised low memory thing? + vfs_free_unused_vnodes(B_LOW_MEMORY_WARNING); + } + if (sUsedSems == sMaxSems) { + // try again with more enthusiasm + vfs_free_unused_vnodes(B_LOW_MEMORY_CRITICAL); + } + if (sUsedSems == sMaxSems) return B_NO_MORE_SEMS; if (name == NULL)