2 /* This file implements the methods of anonymous memory.
4 * Anonymous memory is memory that is for private use to a process
5 * and can not be related to a file (hence anonymous).
15 /* These functions are static so as to not pollute the
16 * global namespace, and are accessed through their function
20 static void anon_split(struct vmproc
*vmp
, struct vir_region
*vr
,
21 struct vir_region
*r1
, struct vir_region
*r2
);
22 static int anon_lowshrink(struct vir_region
*vr
, vir_bytes len
);
23 static int anon_unreference(struct phys_region
*pr
);
24 static int anon_pagefault(struct vmproc
*vmp
, struct vir_region
*region
,
25 struct phys_region
*ph
, int write
, vfs_callback_t cb
, void *state
,
27 static int anon_sanitycheck(struct phys_region
*pr
, const char *file
, int line
);
28 static int anon_writable(struct phys_region
*pr
);
29 static int anon_resize(struct vmproc
*vmp
, struct vir_region
*vr
, vir_bytes l
);
30 static u32_t
anon_regionid(struct vir_region
*region
);
31 static int anon_refcount(struct vir_region
*vr
);
32 static int anon_pt_flags(struct vir_region
*vr
);
34 struct mem_type mem_type_anon
= {
35 .name
= "anonymous memory",
36 .ev_unreference
= anon_unreference
,
37 .ev_pagefault
= anon_pagefault
,
38 .ev_resize
= anon_resize
,
39 .ev_sanitycheck
= anon_sanitycheck
,
40 .ev_lowshrink
= anon_lowshrink
,
41 .ev_split
= anon_split
,
42 .regionid
= anon_regionid
,
43 .writable
= anon_writable
,
44 .refcount
= anon_refcount
,
45 .pt_flags
= anon_pt_flags
,
48 static int anon_pt_flags(struct vir_region
*vr
){
50 return ARM_VM_PTE_CACHED
;
56 static int anon_unreference(struct phys_region
*pr
)
58 assert(pr
->ph
->refcount
== 0);
59 if(pr
->ph
->phys
!= MAP_NONE
)
60 free_mem(ABS2CLICK(pr
->ph
->phys
), 1);
64 static int anon_pagefault(struct vmproc
*vmp
, struct vir_region
*region
,
65 struct phys_region
*ph
, int write
, vfs_callback_t cb
, void *state
,
68 phys_bytes new_page
, new_page_cl
;
71 allocflags
= vrallocflags(region
->flags
);
73 assert(ph
->ph
->refcount
> 0);
75 if((new_page_cl
= alloc_mem(1, allocflags
)) == NO_MEM
) {
76 printf("anon_pagefault: out of memory\n");
79 new_page
= CLICK2ABS(new_page_cl
);
81 /* Totally new block? Create it. */
82 if(ph
->ph
->phys
== MAP_NONE
) {
83 ph
->ph
->phys
= new_page
;
84 assert(ph
->ph
->phys
!= MAP_NONE
);
89 if(ph
->ph
->refcount
< 2 || !write
) {
90 /* memory is ready already */
94 assert(region
->flags
& VR_WRITABLE
);
96 return mem_cow(region
, ph
, new_page_cl
, new_page
);
99 static int anon_sanitycheck(struct phys_region
*pr
, const char *file
, int line
)
101 MYASSERT(usedpages_add(pr
->ph
->phys
, VM_PAGE_SIZE
) == OK
);
105 static int anon_writable(struct phys_region
*pr
)
107 assert(pr
->ph
->refcount
> 0);
108 if(pr
->ph
->phys
== MAP_NONE
)
110 if(pr
->parent
->remaps
> 0)
112 return pr
->ph
->refcount
== 1;
115 static int anon_resize(struct vmproc
*vmp
, struct vir_region
*vr
, vir_bytes l
)
117 /* Shrinking not implemented; silently ignored.
118 * (Which is ok for brk().)
124 assert(vr
->flags
& VR_ANON
);
125 assert(!(l
% VM_PAGE_SIZE
));
127 USE(vr
, vr
->length
= l
;);
132 static u32_t
anon_regionid(struct vir_region
*region
)
137 static int anon_lowshrink(struct vir_region
*vr
, vir_bytes len
)
142 static int anon_refcount(struct vir_region
*vr
)
144 return 1 + vr
->remaps
;
147 static void anon_split(struct vmproc
*vmp
, struct vir_region
*vr
,
148 struct vir_region
*r1
, struct vir_region
*r2
)