* 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:
Ingo Weinhold
2010-04-03 18:01:29 +00:00
parent 21ff565f76
commit 550376ffb8
4 changed files with 845 additions and 242 deletions
+1 -2
View File
@@ -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
+56
View File
@@ -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;
};