summaryrefslogtreecommitdiff
path: root/vm
diff options
context:
space:
mode:
authorMaksym Planeta <mcsim.planeta@gmail.com>2012-10-08 16:01:13 +0200
committerMaksym Planeta <mcsim.planeta@gmail.com>2012-10-28 12:23:14 +0100
commite70ecc311676b9f30cbc5ca7c2029b7f522cbb25 (patch)
treec55707e26f15135bf9cd6b565f2528690c4c5a60 /vm
parent6a08b518a60bd0e9448278f88f6f55681a5b9c6c (diff)
Add IPC functions that allow user to manipulate with memory advice.
* include/mach/mach_types.defs (vm_advice_t): New type definition. * include/mach/mach.defs (vm_advise): New RPC definition. (memory_object_set_advice): Likewise. (memory_object_get_advice): Likewise. * kern/ipc_mig.c (syscall_vm_advice): New function. This is optimization function for RPC that is processed by kernel. * kern/syscall_sw.c (syscall_vm_advice): Add function prototype. (mach_trap_table): Add syscall_vm_advice to trap table. * vm/memory_object.c (memory_object_set_advice): New function. Sets memory advice for memory object. (memory_object_get_advice): New function. Returns memory advice of memory object. * vm/vm_user.c (vm_advise): New function. Wrapper for vm_map_advice. * vm/vm_map.h (vm_map_advice): Add function prototype. * vm/vm_map.c (vm_map_advice): New function. Sets memory advice for memory range.
Diffstat (limited to 'vm')
-rw-r--r--vm/memory_object.c43
-rw-r--r--vm/vm_map.c40
-rw-r--r--vm/vm_map.h3
-rw-r--r--vm/vm_user.c26
4 files changed, 112 insertions, 0 deletions
diff --git a/vm/memory_object.c b/vm/memory_object.c
index e281c6a3..090b58eb 100644
--- a/vm/memory_object.c
+++ b/vm/memory_object.c
@@ -1037,6 +1037,49 @@ kern_return_t memory_object_get_attributes(object, object_ready,
return(KERN_SUCCESS);
}
+kern_return_t
+memory_object_set_advice(vm_object_t object, vm_advice_t advice)
+{
+ if (object == VM_OBJECT_NULL)
+ return(KERN_INVALID_ARGUMENT);
+
+ switch(advice) {
+ case VM_ADVICE_DEFAULT:
+ case VM_ADVICE_RANDOM:
+ case VM_ADVICE_SEQUENTIAL:
+ case VM_ADVICE_NORMAL:
+ case VM_ADVICE_KEEP:
+ break;
+ default:
+ vm_object_deallocate(object);
+ return(KERN_INVALID_ARGUMENT);
+ }
+
+ vm_object_lock(object);
+ if (advice != VM_ADVICE_KEEP)
+ object->advice = advice;
+ vm_object_unlock(object);
+
+ vm_object_deallocate(object);
+
+ return(KERN_SUCCESS);
+}
+
+kern_return_t
+memory_object_get_advice(vm_object_t object, vm_advice_t *advice)
+{
+ if (object == VM_OBJECT_NULL)
+ return(KERN_INVALID_ARGUMENT);
+
+ vm_object_lock(object);
+ *advice = object->advice;
+ vm_object_unlock(object);
+
+ vm_object_deallocate(object);
+
+ return(KERN_SUCCESS);
+}
+
/*
* If successful, consumes the supplied naked send right.
*/
diff --git a/vm/vm_map.c b/vm/vm_map.c
index 22fe0eae..0afaff29 100644
--- a/vm/vm_map.c
+++ b/vm/vm_map.c
@@ -1346,6 +1346,46 @@ kern_return_t vm_map_inherit(map, start, end, new_inheritance)
}
/*
+ * vm_map_advise:
+ *
+ * Sets the page fault advice of the specified
+ * address range in the target map. Advice
+ * affects how the page fault will be
+ * handled at the time of vm_fault.
+ */
+kern_return_t
+vm_map_advise(vm_map_t map, vm_offset_t address,
+ vm_size_t length, vm_advice_t advice)
+{
+ register vm_map_entry_t entry;
+ vm_map_entry_t temp_entry;
+ vm_offset_t end = address + length;
+
+ vm_map_lock(map);
+
+ VM_MAP_RANGE_CHECK(map, address, end);
+
+ if (vm_map_lookup_entry(map, address, &temp_entry)) {
+ entry = temp_entry;
+ vm_map_clip_start(map, entry, address);
+ }
+ else
+ entry = temp_entry->vme_next;
+
+ while ((entry != vm_map_to_entry(map))
+ && (entry->vme_start < end)) {
+ vm_map_clip_end(map, entry, end);
+
+ entry->advice = advice;
+
+ entry = entry->vme_next;
+ }
+
+ vm_map_unlock(map);
+ return(KERN_SUCCESS);
+}
+
+/*
* vm_map_pageable_common:
*
* Sets the pageability of the specified address
diff --git a/vm/vm_map.h b/vm/vm_map.h
index af7588ba..96c0bcbf 100644
--- a/vm/vm_map.h
+++ b/vm/vm_map.h
@@ -397,6 +397,9 @@ extern kern_return_t vm_map_protect(vm_map_t, vm_offset_t, vm_offset_t,
/* Change inheritance */
extern kern_return_t vm_map_inherit(vm_map_t, vm_offset_t, vm_offset_t,
vm_inherit_t);
+/* Change page fault policy */
+extern kern_return_t vm_map_advise(vm_map_t, vm_offset_t, vm_size_t,
+ vm_advice_t);
/* Debugging: print a map */
extern void vm_map_print(vm_map_t);
diff --git a/vm/vm_user.c b/vm/vm_user.c
index 59c2a36e..c5530a69 100644
--- a/vm/vm_user.c
+++ b/vm/vm_user.c
@@ -171,6 +171,32 @@ kern_return_t vm_protect(map, start, size, set_maximum, new_protection)
set_maximum));
}
+
+/*
+ * vm_advise sets page fault handling policy of the specified range
+ * in the specified map.
+ */
+
+kern_return_t
+vm_advise(vm_map_t map, vm_offset_t address,
+ vm_size_t length, vm_advice_t advice)
+{
+ if (map == VM_MAP_NULL)
+ return(KERN_INVALID_ARGUMENT);
+
+ switch(advice) {
+ case VM_ADVICE_DEFAULT:
+ case VM_ADVICE_RANDOM:
+ case VM_ADVICE_SEQUENTIAL:
+ case VM_ADVICE_NORMAL:
+ break;
+ default:
+ return(KERN_INVALID_ARGUMENT);
+ }
+
+ return(vm_map_advise(map, address, length, advice));
+}
+
kern_return_t vm_statistics(map, stat)
vm_map_t map;
vm_statistics_data_t *stat;