include: reduce default stack size
[minix.git] / servers / vm / mem_anon.c
blob0971708fd7f304732bbab91de5ea9f0fbbc779ca
2 /* This file implements the methods of anonymous memory.
3 *
4 * Anonymous memory is memory that is for private use to a process
5 * and can not be related to a file (hence anonymous).
6 */
8 #include <assert.h>
10 #include "proto.h"
11 #include "vm.h"
12 #include "region.h"
13 #include "glo.h"
15 /* These functions are static so as to not pollute the
16 * global namespace, and are accessed through their function
17 * pointers.
20 static int anon_reference(struct phys_region *pr);
21 static int anon_unreference(struct phys_region *pr);
22 static int anon_pagefault(struct vmproc *vmp, struct vir_region *region,
23 struct phys_region *ph, int write);
24 static int anon_sanitycheck(struct phys_region *pr, char *file, int line);
25 static int anon_writable(struct phys_region *pr);
26 static int anon_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l);
27 static u32_t anon_regionid(struct vir_region *region);
28 static int anon_refcount(struct vir_region *vr);
30 struct mem_type mem_type_anon = {
31 .name = "anonymous memory",
32 .ev_reference = anon_reference,
33 .ev_unreference = anon_unreference,
34 .ev_pagefault = anon_pagefault,
35 .ev_resize = anon_resize,
36 .ev_sanitycheck = anon_sanitycheck,
37 .regionid = anon_regionid,
38 .writable = anon_writable,
39 .refcount = anon_refcount
42 static int anon_reference(struct phys_region *pr)
44 return OK;
47 static int anon_unreference(struct phys_region *pr)
49 assert(pr->ph->refcount == 0);
50 if(pr->ph->phys != MAP_NONE)
51 free_mem(ABS2CLICK(pr->ph->phys), 1);
52 return OK;
55 static int anon_pagefault(struct vmproc *vmp, struct vir_region *region,
56 struct phys_region *ph, int write)
58 phys_bytes new_page, new_page_cl;
59 struct phys_block *pb;
60 u32_t allocflags;
62 allocflags = vrallocflags(region->flags);
64 assert(ph->ph->refcount > 0);
66 if((new_page_cl = alloc_mem(1, allocflags)) == NO_MEM)
67 return ENOMEM;
68 new_page = CLICK2ABS(new_page_cl);
70 /* Totally new block? Create it. */
71 if(ph->ph->phys == MAP_NONE) {
72 ph->ph->phys = new_page;
73 assert(ph->ph->phys != MAP_NONE);
75 return OK;
78 if(ph->ph->refcount < 2 || !write) {
79 printf("anon_pagefault: %d refcount, %d write - not handling pagefault\n",
80 ph->ph->refcount, write);
81 return OK;
84 assert(region->flags & VR_WRITABLE);
86 if(sys_abscopy(ph->ph->phys, new_page, VM_PAGE_SIZE) != OK) {
87 panic("VM: abscopy failed\n");
88 return EFAULT;
91 if(!(pb = pb_new(new_page))) {
92 free_mem(new_page_cl, 1);
93 return ENOMEM;
96 pb_unreferenced(region, ph, 0);
97 pb_link(ph, pb, ph->offset, region);
99 return OK;
102 static int anon_sanitycheck(struct phys_region *pr, char *file, int line)
104 MYASSERT(usedpages_add(pr->ph->phys, VM_PAGE_SIZE) == OK);
105 return OK;
108 static int anon_writable(struct phys_region *pr)
110 assert(pr->ph->refcount > 0);
111 if(pr->parent->remaps > 0)
112 return 1;
113 return pr->ph->phys != MAP_NONE && pr->ph->refcount == 1;
116 static int anon_resize(struct vmproc *vmp, struct vir_region *vr, vir_bytes l)
118 /* Shrinking not implemented; silently ignored.
119 * (Which is ok for brk().)
121 if(l <= vr->length)
122 return OK;
124 assert(vr);
125 assert(vr->flags & VR_ANON);
126 assert(!(l % VM_PAGE_SIZE));
128 USE(vr, vr->length = l;);
130 return OK;
133 static u32_t anon_regionid(struct vir_region *region)
135 return region->id;
138 static int anon_refcount(struct vir_region *vr)
140 return 1 + vr->remaps;