* vm_delete_areas(): Changed return type to void (was status_t and not used).
* _user_map_file(), _user_unmap_memory(): Verify that the address (if given) is
page aligned.
* Reworked memory locking (wiring):
- VMArea does now have a list of wired memory ranges and supports waiting for
a range to be removed.
- vm_soft_fault():
- Added "wirePage" parameter that, if given, makes the function wire the
page and return it.
- Added "wiredRange" parameter (for calls from lock_memory_etc()) and made
sure we never unmap wired pages. This could e.g. happen when a page from a
lower cache was read-mapped and a write fault occurred. Now in such a
situation the function waits for the page to be unwired and restarts.
- All functions that manipulate areas in a way that could affect wired ranges
do now either require the caller to make sure there are no wired ranges in
the way or do that themselves. Added a few wait_if_*_is_wired() helper
functions for that purpose.
- lock_memory_etc():
- Does now also work correctly when the range spans more than one area.
- Adds VMAreaWiredRanges to the affected VMAreas and retains an address
space reference (so that the address space won't be deleted as long as a
wired range exists).
- Resolved TODO: The area's caches are now locked when
increment_page_wired_count() is called.
- Resolved TODO: The race condition due to missing locking after looking up
the page mapping is now prevented. We hold the cache locks (in case the
page is already mapped) and the new vm_soft_fault() parameter allows us
to get the page wired.
- unlock_memory_etc(): Changes symmetrical to those in lock_memory_etc() and
resolved all TODOs.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@36030 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -198,8 +198,7 @@ VMAddressSpace::GetAreaIterator()
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
status_t vm_delete_areas(struct VMAddressSpace *aspace,
|
||||
bool deletingAddressSpace);
|
||||
void vm_delete_areas(struct VMAddressSpace *aspace, bool deletingAddressSpace);
|
||||
#define vm_swap_address_space(from, to) arch_vm_aspace_swap(from, to)
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
|
||||
#include <lock.h>
|
||||
#include <util/DoublyLinkedList.h>
|
||||
#include <util/SinglyLinkedList.h>
|
||||
#include <util/OpenHashTable.h>
|
||||
#include <vm/vm_types.h>
|
||||
|
||||
@@ -22,6 +23,46 @@ struct VMKernelAddressSpace;
|
||||
struct VMUserAddressSpace;
|
||||
|
||||
|
||||
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;
|
||||
|
||||
VMAreaWiredRange(addr_t base, size_t size, bool writable, bool implicit)
|
||||
:
|
||||
area(NULL),
|
||||
base(base),
|
||||
size(size),
|
||||
writable(writable),
|
||||
implicit(implicit)
|
||||
{
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
||||
struct VMArea {
|
||||
char* name;
|
||||
area_id id;
|
||||
@@ -48,6 +89,20 @@ struct VMArea {
|
||||
{ return address >= fBase
|
||||
&& address <= fBase + (fSize - 1); }
|
||||
|
||||
bool IsWired() const
|
||||
{ return !fWiredRanges.IsEmpty(); }
|
||||
bool IsWired(addr_t base, size_t size) const;
|
||||
|
||||
void Wire(VMAreaWiredRange* range);
|
||||
VMAreaWiredRange* Wire(addr_t base, size_t size, bool writable);
|
||||
void Unwire(VMAreaWiredRange* range);
|
||||
void Unwire(addr_t base, size_t size, bool writable);
|
||||
|
||||
bool AddWaiterIfWired(VMAreaUnwiredWaiter* waiter);
|
||||
bool AddWaiterIfWired(VMAreaUnwiredWaiter* waiter,
|
||||
addr_t base, size_t size,
|
||||
VMAreaWiredRange* ignoreRange = NULL);
|
||||
|
||||
protected:
|
||||
VMArea(VMAddressSpace* addressSpace,
|
||||
uint32 wiring, uint32 protection);
|
||||
@@ -67,6 +122,7 @@ protected:
|
||||
protected:
|
||||
addr_t fBase;
|
||||
size_t fSize;
|
||||
VMAreaWiredRangeList fWiredRanges;
|
||||
};
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user