1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
use super::{frame_allocator::free_space_size_rdlock, memory_set::MapArea};
use crate::fs::FileLike;
use alloc::sync::Arc;
use alloc::vec::Vec;
use core::fmt::Result;
use lazy_static::*;
use log::info;
use spin::{RwLock, RwLockReadGuard};
lazy_static! {
pub static ref ELF_CACHE: RwLock<Vec<MapArea>> = RwLock::new(Vec::new());
}
pub fn push_elf_area(file: Arc<crate::fs::OSInode>) -> Result {
let len: usize = file.size();
let rd = ELF_CACHE.read();
let elf_file = rd.iter().find(|now| {
if let FileLike::Regular(ref i) = now.map_file.as_ref().unwrap() {
i.get_ino() == file.get_ino()
} else {
false
}
});
if elf_file.is_some() {
return crate::mm::KERNEL_SPACE
.lock()
.push_no_alloc(elf_file.unwrap());
}
if len > free_space_size_rdlock() {
log::info!("[push_elf_area] No more space. Trying to replace the saved elfs");
try_remove_elf(rd, Some(len));
if len > free_space_size_rdlock() {
panic!("[push_elf_area] No space left.")
}
} else {
drop(rd);
}
let mut i = crate::mm::KERNEL_SPACE
.lock()
.insert_program_area(
crate::config::MMAP_BASE.into(),
(crate::config::MMAP_BASE + len).into(),
crate::mm::MapPermission::R | crate::mm::MapPermission::W,
)
.unwrap();
i.map_file = Some(FileLike::Regular(file));
ELF_CACHE.write().push(i);
Err(core::fmt::Error)
}
pub fn try_remove_elf(rd: RwLockReadGuard<Vec<MapArea>>, len_exp: Option<usize>) {
info!("[elf_cache] Trying to remove a cached file.");
let mut v = Vec::new();
let acc_size = 0;
for i in (0..rd.len()).rev() {
if rd[i].file_ref().unwrap() == 1 {
info!(
"[push_elf_area] file {} has file_ref {}",
i,
rd[i].file_ref().unwrap()
);
v.push(i);
}
}
drop(rd);
for i in v {
ELF_CACHE.write().remove(i);
}
}