mirror of
https://review.haiku-os.org/haiku
synced 2025-01-31 18:56:49 +01:00
block_cache: Use an object_cache for the cache_notifications.
cache_listeners are (following packagefs changes) the second-most allocated object during the boot process, with 20799 on a *minimum* image. Since they are used so extensively in BFS I/O, making them object_cached for both performance and memory reasons seems to make a lot of sense. Change-Id: I6ef6c3e811c0c4189fea45ee7920131796c9e7c8 Reviewed-on: https://review.haiku-os.org/c/1577 Reviewed-by: Adrien Destugues <pulkomandy@gmail.com> Reviewed-by: Stephan Aßmus <superstippi@gmx.de>
This commit is contained in:
parent
7a2f744859
commit
0e6ece91c8
54
src/system/kernel/cache/block_cache.cpp
vendored
54
src/system/kernel/cache/block_cache.cpp
vendored
@ -114,6 +114,9 @@ typedef DoublyLinkedList<cached_block,
|
||||
&cached_block::link> > block_list;
|
||||
|
||||
struct cache_notification : DoublyLinkedListLinkImpl<cache_notification> {
|
||||
static inline void* operator new(size_t size);
|
||||
static inline void operator delete(void* block);
|
||||
|
||||
int32 transaction_id;
|
||||
int32 events_pending;
|
||||
int32 events;
|
||||
@ -124,6 +127,38 @@ struct cache_notification : DoublyLinkedListLinkImpl<cache_notification> {
|
||||
|
||||
typedef DoublyLinkedList<cache_notification> NotificationList;
|
||||
|
||||
static object_cache* sCacheNotificationCache;
|
||||
|
||||
struct cache_listener;
|
||||
typedef DoublyLinkedListLink<cache_listener> listener_link;
|
||||
|
||||
struct cache_listener : cache_notification {
|
||||
listener_link link;
|
||||
};
|
||||
|
||||
typedef DoublyLinkedList<cache_listener,
|
||||
DoublyLinkedListMemberGetLink<cache_listener,
|
||||
&cache_listener::link> > ListenerList;
|
||||
|
||||
void*
|
||||
cache_notification::operator new(size_t size)
|
||||
{
|
||||
// We can't really know whether something is a cache_notification or a
|
||||
// cache_listener at runtime, so we just use one object_cache for both
|
||||
// with the size set to that of the (slightly larger) cache_listener.
|
||||
// In practice, the vast majority of cache_notifications are really
|
||||
// cache_listeners, so this is a more than acceptable trade-off.
|
||||
ASSERT(size <= sizeof(cache_listener));
|
||||
return object_cache_alloc(sCacheNotificationCache, 0);
|
||||
}
|
||||
|
||||
void
|
||||
cache_notification::operator delete(void* block)
|
||||
{
|
||||
object_cache_free(sCacheNotificationCache, block, 0);
|
||||
}
|
||||
|
||||
|
||||
struct BlockHash {
|
||||
typedef off_t KeyType;
|
||||
typedef cached_block ValueType;
|
||||
@ -219,18 +254,6 @@ private:
|
||||
cached_block* _GetUnusedBlock();
|
||||
};
|
||||
|
||||
struct cache_listener;
|
||||
typedef DoublyLinkedListLink<cache_listener> listener_link;
|
||||
|
||||
struct cache_listener : cache_notification {
|
||||
listener_link link;
|
||||
};
|
||||
|
||||
typedef DoublyLinkedList<cache_listener,
|
||||
DoublyLinkedListMemberGetLink<cache_listener,
|
||||
&cache_listener::link> > ListenerList;
|
||||
|
||||
|
||||
struct cache_transaction {
|
||||
cache_transaction();
|
||||
|
||||
@ -963,7 +986,7 @@ add_transaction_listener(block_cache* cache, cache_transaction* transaction,
|
||||
}
|
||||
}
|
||||
|
||||
cache_listener* listener = new(std::nothrow) cache_listener;
|
||||
cache_listener* listener = new cache_listener;
|
||||
if (listener == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
@ -2662,6 +2685,11 @@ block_cache_init(void)
|
||||
if (sBlockCache == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
sCacheNotificationCache = create_object_cache("cache notifications",
|
||||
sizeof(cache_listener), 8, NULL, NULL, NULL);
|
||||
if (sCacheNotificationCache == NULL)
|
||||
return B_NO_MEMORY;
|
||||
|
||||
new (&sCaches) DoublyLinkedList<block_cache>;
|
||||
// manually call constructor
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user