2009-12-02 19:55:59 +00:00
|
|
|
/*
|
2010-05-01 20:41:57 +00:00
|
|
|
* Copyright 2009-2010, Ingo Weinhold, ingo_weinhold@gmx.de.
|
2009-12-02 19:55:59 +00:00
|
|
|
* Copyright 2002-2009, Axel Dörfler, axeld@pinc-software.de.
|
|
|
|
* Distributed under the terms of the MIT License.
|
|
|
|
*
|
|
|
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
|
|
|
* Distributed under the terms of the NewOS License.
|
|
|
|
*/
|
|
|
|
#ifndef _KERNEL_VM_VM_AREA_H
|
|
|
|
#define _KERNEL_VM_VM_AREA_H
|
|
|
|
|
|
|
|
|
2010-05-01 20:41:57 +00:00
|
|
|
#include <vm_defs.h>
|
|
|
|
|
2009-12-02 19:55:59 +00:00
|
|
|
#include <lock.h>
|
2009-12-03 12:41:11 +00:00
|
|
|
#include <util/DoublyLinkedList.h>
|
2010-04-03 18:01:29 +00:00
|
|
|
#include <util/SinglyLinkedList.h>
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
#include <util/AVLTree.h>
|
2009-12-02 19:55:59 +00:00
|
|
|
#include <vm/vm_types.h>
|
|
|
|
|
|
|
|
|
|
|
|
struct VMAddressSpace;
|
|
|
|
struct VMCache;
|
2009-12-04 14:45:08 +00:00
|
|
|
struct VMKernelAddressSpace;
|
|
|
|
struct VMUserAddressSpace;
|
2009-12-02 19:55:59 +00:00
|
|
|
|
|
|
|
|
2010-04-03 18:01:29 +00:00
|
|
|
struct VMAreaUnwiredWaiter
|
|
|
|
: public DoublyLinkedListLinkImpl<VMAreaUnwiredWaiter> {
|
|
|
|
VMArea* area;
|
|
|
|
addr_t base;
|
|
|
|
size_t size;
|
|
|
|
ConditionVariable condition;
|
|
|
|
ConditionVariableEntry waitEntry;
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef DoublyLinkedList<VMAreaUnwiredWaiter> VMAreaUnwiredWaiterList;
|
|
|
|
|
|
|
|
|
|
|
|
struct VMAreaWiredRange : SinglyLinkedListLinkImpl<VMAreaWiredRange> {
|
|
|
|
VMArea* area;
|
|
|
|
addr_t base;
|
|
|
|
size_t size;
|
|
|
|
bool writable;
|
|
|
|
bool implicit; // range created automatically
|
|
|
|
VMAreaUnwiredWaiterList waiters;
|
|
|
|
|
2010-04-11 15:07:06 +00:00
|
|
|
VMAreaWiredRange()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-04-03 18:01:29 +00:00
|
|
|
VMAreaWiredRange(addr_t base, size_t size, bool writable, bool implicit)
|
|
|
|
:
|
|
|
|
area(NULL),
|
|
|
|
base(base),
|
|
|
|
size(size),
|
|
|
|
writable(writable),
|
|
|
|
implicit(implicit)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2010-04-11 15:07:06 +00:00
|
|
|
void SetTo(addr_t base, size_t size, bool writable, bool implicit)
|
|
|
|
{
|
|
|
|
this->area = NULL;
|
|
|
|
this->base = base;
|
|
|
|
this->size = size;
|
|
|
|
this->writable = writable;
|
|
|
|
this->implicit = implicit;
|
|
|
|
}
|
|
|
|
|
2010-04-03 18:01:29 +00:00
|
|
|
bool IntersectsWith(addr_t base, size_t size) const
|
|
|
|
{
|
|
|
|
return this->base + this->size - 1 >= base
|
|
|
|
&& base + size - 1 >= this->base;
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
typedef SinglyLinkedList<VMAreaWiredRange> VMAreaWiredRangeList;
|
|
|
|
|
|
|
|
|
2010-04-11 15:07:06 +00:00
|
|
|
struct VMPageWiringInfo {
|
|
|
|
VMAreaWiredRange range;
|
2010-05-25 21:34:08 +00:00
|
|
|
phys_addr_t physicalAddress;
|
2010-04-11 15:07:06 +00:00
|
|
|
// the actual physical address corresponding to
|
|
|
|
// the virtual address passed to vm_wire_page()
|
|
|
|
// (i.e. with in-page offset)
|
|
|
|
vm_page* page;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
struct VMAreasTreeNode {
|
|
|
|
AVLTreeNode tree_node;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct VMArea : private VMAreasTreeNode {
|
2014-10-29 12:32:37 +01:00
|
|
|
public:
|
|
|
|
enum {
|
|
|
|
// AddWaiterIfWired() flags
|
|
|
|
IGNORE_WRITE_WIRED_RANGES = 0x01, // ignore existing ranges that
|
|
|
|
// wire for writing
|
|
|
|
};
|
|
|
|
|
|
|
|
public:
|
2009-12-02 19:55:59 +00:00
|
|
|
area_id id;
|
2019-07-12 22:41:21 -04:00
|
|
|
char name[B_OS_NAME_LENGTH];
|
2009-12-02 19:55:59 +00:00
|
|
|
uint32 protection;
|
2021-03-17 15:37:44 +01:00
|
|
|
uint32 protection_max;
|
2009-12-02 19:55:59 +00:00
|
|
|
uint16 wiring;
|
|
|
|
|
2010-05-01 20:41:57 +00:00
|
|
|
private:
|
|
|
|
uint16 memory_type; // >> shifted by MEMORY_TYPE_SHIFT
|
|
|
|
|
|
|
|
public:
|
2009-12-02 19:55:59 +00:00
|
|
|
VMCache* cache;
|
|
|
|
off_t cache_offset;
|
|
|
|
uint32 cache_type;
|
|
|
|
VMAreaMappings mappings;
|
|
|
|
uint8* page_protections;
|
|
|
|
|
|
|
|
struct VMAddressSpace* address_space;
|
2024-12-17 20:16:43 +09:00
|
|
|
|
|
|
|
private:
|
|
|
|
DoublyLinkedListLink<VMArea> fCacheLink;
|
|
|
|
|
|
|
|
public:
|
|
|
|
typedef DoublyLinkedList<VMArea,
|
|
|
|
DoublyLinkedListMemberGetLink<VMArea, &VMArea::fCacheLink> > CacheList;
|
2009-12-02 19:55:59 +00:00
|
|
|
|
2009-12-03 14:18:24 +00:00
|
|
|
addr_t Base() const { return fBase; }
|
|
|
|
size_t Size() const { return fSize; }
|
|
|
|
|
2010-05-01 20:41:57 +00:00
|
|
|
inline uint32 MemoryType() const;
|
|
|
|
inline void SetMemoryType(uint32 memoryType);
|
|
|
|
|
2009-12-03 12:41:11 +00:00
|
|
|
bool ContainsAddress(addr_t address) const
|
2009-12-03 14:18:24 +00:00
|
|
|
{ return address >= fBase
|
|
|
|
&& address <= fBase + (fSize - 1); }
|
2009-12-03 12:41:11 +00:00
|
|
|
|
2010-04-03 18:01:29 +00:00
|
|
|
bool IsWired() const
|
|
|
|
{ return !fWiredRanges.IsEmpty(); }
|
|
|
|
bool IsWired(addr_t base, size_t size) const;
|
|
|
|
|
|
|
|
void Wire(VMAreaWiredRange* range);
|
|
|
|
void Unwire(VMAreaWiredRange* range);
|
2010-04-05 12:12:36 +00:00
|
|
|
VMAreaWiredRange* Unwire(addr_t base, size_t size, bool writable);
|
2010-04-03 18:01:29 +00:00
|
|
|
|
|
|
|
bool AddWaiterIfWired(VMAreaUnwiredWaiter* waiter);
|
|
|
|
bool AddWaiterIfWired(VMAreaUnwiredWaiter* waiter,
|
2014-10-29 12:32:37 +01:00
|
|
|
addr_t base, size_t size, uint32 flags = 0);
|
2010-04-03 18:01:29 +00:00
|
|
|
|
2009-12-04 17:07:16 +00:00
|
|
|
protected:
|
|
|
|
VMArea(VMAddressSpace* addressSpace,
|
|
|
|
uint32 wiring, uint32 protection);
|
|
|
|
~VMArea();
|
|
|
|
|
2010-01-27 12:45:53 +00:00
|
|
|
status_t Init(const char* name, uint32 allocationFlags);
|
2009-12-04 17:07:16 +00:00
|
|
|
|
|
|
|
protected:
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
friend struct VMAreasTreeDefinition;
|
2017-12-01 20:27:15 -05:00
|
|
|
friend struct VMKernelAddressSpace;
|
|
|
|
friend struct VMUserAddressSpace;
|
2009-12-03 15:21:18 +00:00
|
|
|
|
2009-12-04 17:07:16 +00:00
|
|
|
protected:
|
2009-12-03 15:21:18 +00:00
|
|
|
void SetBase(addr_t base) { fBase = base; }
|
|
|
|
void SetSize(size_t size) { fSize = size; }
|
|
|
|
|
2009-12-04 17:07:16 +00:00
|
|
|
protected:
|
2009-12-03 14:18:24 +00:00
|
|
|
addr_t fBase;
|
|
|
|
size_t fSize;
|
2010-04-03 18:01:29 +00:00
|
|
|
VMAreaWiredRangeList fWiredRanges;
|
2009-12-03 12:41:11 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
struct VMAreasTreeDefinition {
|
|
|
|
typedef area_id Key;
|
|
|
|
typedef VMArea Value;
|
2009-12-02 19:55:59 +00:00
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
AVLTreeNode* GetAVLTreeNode(VMArea* value) const
|
2009-12-02 19:55:59 +00:00
|
|
|
{
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
return &value->tree_node;
|
2009-12-02 19:55:59 +00:00
|
|
|
}
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
VMArea* GetValue(AVLTreeNode* node) const
|
2009-12-02 19:55:59 +00:00
|
|
|
{
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
const addr_t vmTreeNodeAddr = (addr_t)node
|
|
|
|
- offsetof(VMAreasTreeNode, tree_node);
|
|
|
|
VMAreasTreeNode* vmTreeNode =
|
|
|
|
reinterpret_cast<VMAreasTreeNode*>(vmTreeNodeAddr);
|
|
|
|
return static_cast<VMArea*>(vmTreeNode);
|
2009-12-02 19:55:59 +00:00
|
|
|
}
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
int Compare(area_id key, const VMArea* value) const
|
2009-12-02 19:55:59 +00:00
|
|
|
{
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
const area_id valueId = value->id;
|
|
|
|
if (valueId == key)
|
|
|
|
return 0;
|
|
|
|
return key < valueId ? -1 : 1;
|
2009-12-02 19:55:59 +00:00
|
|
|
}
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
int Compare(const VMArea* a, const VMArea* b) const
|
2009-12-02 19:55:59 +00:00
|
|
|
{
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
return Compare(a->id, b);
|
2009-12-02 19:55:59 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
typedef AVLTree<VMAreasTreeDefinition> VMAreasTree;
|
2009-12-02 19:55:59 +00:00
|
|
|
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
struct VMAreas {
|
2009-12-02 19:55:59 +00:00
|
|
|
static status_t Init();
|
|
|
|
|
|
|
|
static status_t ReadLock()
|
|
|
|
{ return rw_lock_read_lock(&sLock); }
|
|
|
|
static void ReadUnlock()
|
|
|
|
{ rw_lock_read_unlock(&sLock); }
|
|
|
|
static status_t WriteLock()
|
|
|
|
{ return rw_lock_write_lock(&sLock); }
|
|
|
|
static void WriteUnlock()
|
|
|
|
{ rw_lock_write_unlock(&sLock); }
|
|
|
|
|
|
|
|
static VMArea* LookupLocked(area_id id)
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
{ return sTree.Find(id); }
|
2009-12-02 19:55:59 +00:00
|
|
|
static VMArea* Lookup(area_id id);
|
|
|
|
static area_id Find(const char* name);
|
2024-08-26 14:24:10 -04:00
|
|
|
static status_t Insert(VMArea* area);
|
2009-12-02 19:55:59 +00:00
|
|
|
static void Remove(VMArea* area);
|
|
|
|
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
static VMAreasTree::Iterator GetIterator()
|
|
|
|
{ return sTree.GetIterator(); }
|
2009-12-02 19:55:59 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
static rw_lock sLock;
|
vm: Replace the VMAreas OpenHashTable with an AVLTree.
Since we used a hash table with a fixed size (1024), collisions were
obviously inevitable, meaning that while insertions would always be
fast, lookups and deletions would take linear time to search the
linked-list for the area in question. For recently-created areas,
this would be fast; for less-recently-created areas, it would get
slower and slower and slower.
A particularly pathological case was the "mmap/24-1" test from the
Open POSIX Testsuite, which creates millions of areas until it hits
ENOMEM; it then simply exits, at which point it would run for minutes
and minutes in the kernel team deletion routines; how long I don't know,
as I rebooted before it finished.
This change fixes that problem, among others, at the cost of increased
area creation time, by using an AVL tree instead of a hash. For comparison,
mmap'ing 2 million areas with the "24-1" test before this change took
around 0m2.706s of real time, while afterwards it takes about 0m3.118s,
or around a 15% increase (1.152x).
On the other hand, the total test runtime for 2 million areas went from
around 2m11.050s to 0m4.035s, or around a 97% decrease (0.031x); in other
words, with this new code, it is *32 times faster.*
Area insertion will no longer be O(1), however, so the time increase
may go up with the number of areas present on the system; but if it's
only around 3 seconds to create 2 million areas, or about 1.56 us per area,
vs. 1.35 us before, I don't think that's worth worrying about.
My nonscientific "compile HaikuDepot with 2 cores in VM" benchmark
seems to be within the realm of "noise", anyway, with most results
both before and after this change coming in around 47s real time.
Change-Id: I230e17de4f80304d082152af83db8bd5abe7b831
2023-03-14 17:42:25 -04:00
|
|
|
static VMAreasTree sTree;
|
2009-12-02 19:55:59 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2010-05-01 20:41:57 +00:00
|
|
|
uint32
|
|
|
|
VMArea::MemoryType() const
|
|
|
|
{
|
|
|
|
return (uint32)memory_type << MEMORY_TYPE_SHIFT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
VMArea::SetMemoryType(uint32 memoryType)
|
|
|
|
{
|
|
|
|
memory_type = memoryType >> MEMORY_TYPE_SHIFT;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2009-12-02 19:55:59 +00:00
|
|
|
#endif // _KERNEL_VM_VM_AREA_H
|