diff --git a/.idea/git_toolbox_prj.xml b/.idea/git_toolbox_prj.xml
new file mode 100644
index 000000000..02b915b85
--- /dev/null
+++ b/.idea/git_toolbox_prj.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/arch/x86/syscalls.cpp b/src/arch/x86/syscalls.cpp
index fc2261a3f..87d68605e 100644
--- a/src/arch/x86/syscalls.cpp
+++ b/src/arch/x86/syscalls.cpp
@@ -215,14 +215,30 @@ char *syscall_sbrk(int brk) {
if (!vma) return reinterpret_cast(-1);
if (!vma->brk_start) {
- vma->brk_start = (char *) vma->mmap_mem(nullptr, VMA::kBrkSize /* 16MB */, 0, PAGE_RW | PAGE_USER);
+ vma->brk_start = (char *) vma->mmap_mem((void *) 0x100000000ULL, VMA::kBrkSize, 0, PAGE_RW | PAGE_USER);
if (!vma->brk_start) return reinterpret_cast(-1); // FIXME:
vma->brk_end_real = *vma->brk_start + VMA::kBrkSize;
vma->brk_end_fake = vma->brk_start;
}
- if (*vma->brk_end_fake + brk >= *vma->brk_start + VMA::kBrkSize) {
- return ret;
+ if (*vma->brk_end_fake + brk > *vma->brk_end_real) {
+ size_t new_len = PAGE_ROUND_UP((*vma->brk_end_fake + brk - *vma->brk_end_real));
+ void *new_end = vma->mmap_mem(*vma->brk_end_real, new_len, 0, PAGE_RW | PAGE_USER);
+ if (new_end != *vma->brk_end_real) {
+ writestr_no_yield("\nSBRK fail!\n");
+ if (!vma->munmap(new_end, PAGE_ROUND_UP(*vma->brk_end_fake + brk - *vma->brk_end_real)))
+ writestr_no_yield("\nunmap fail after SBRK fail!\n");
+ return reinterpret_cast(-1);
+ }
+ vma->brk_end_real = (char *) new_end + new_len;
+ } else if (*vma->brk_end_real - (*vma->brk_end_fake + brk) > 3 * PAGE_SIZE) {
+ uintptr_t new_end = PAGE_ROUND_UP((uintptr_t) (*vma->brk_end_fake + brk));
+ uintptr_t length_diff = (uintptr_t) *vma->brk_end_real - new_end;
+
+ if (vma->munmap((void *) new_end, length_diff) == -1)
+ writestr_no_yield("\nunmap fail in sbrk!\n");
+ else
+ *vma->brk_end_real = (char *) new_end;
}
ret = *vma->brk_end_fake;
diff --git a/src/arch/x86/task.cpp b/src/arch/x86/task.cpp
index cfbca5e5a..7acc4abf0 100644
--- a/src/arch/x86/task.cpp
+++ b/src/arch/x86/task.cpp
@@ -194,9 +194,10 @@ void Task::user_setup() {
_ownAddressSpace = UniquePtr(new AddressSpace());
_vma = UniquePtr(new VMA(_ownAddressSpace.get()));
+ static_assert(sizeof(task_pointer) <= PAGE_SIZE);
task_pointer *taskptr = static_cast(
_vma->mmap_mem(reinterpret_cast(TASK_POINTER),
- sizeof(task_pointer), 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
+ PAGE_SIZE, 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
assert((uintptr_t) taskptr == TASK_POINTER);
task_pointer *taskptr_real = reinterpret_cast(HHDM_P2V(_ownAddressSpace->virt2real(taskptr)));
@@ -224,9 +225,10 @@ void Task::user_reset() {
_vma = UniquePtr(new VMA(_ownAddressSpace.get()));
+ static_assert(sizeof(task_pointer) <= PAGE_SIZE);
task_pointer *taskptr = static_cast(
_vma->mmap_mem(reinterpret_cast(TASK_POINTER),
- sizeof(task_pointer), 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
+ PAGE_SIZE, 0, PAGE_RW | PAGE_USER)); // FIXME: this is probably unsafe
assert((uintptr_t) taskptr == TASK_POINTER);
task_pointer *taskptr_real = reinterpret_cast(HHDM_P2V(_ownAddressSpace->virt2real(taskptr)));
diff --git a/src/kernel/VMA.cpp b/src/kernel/VMA.cpp
index b2856252f..f91927b4e 100644
--- a/src/kernel/VMA.cpp
+++ b/src/kernel/VMA.cpp
@@ -81,13 +81,7 @@ void *VMA::mmap_phys(void *v_addr, void *real_addr, size_t length, int flags) {
}
void *VMA::mmap_mem(void *v_addr, size_t length, int prot, int flags) {
- size_t origlen = length;
- if ((length & (PAGE_SIZE - 1)) != 0) {
- length += PAGE_SIZE - 1;
- length &= ~(PAGE_SIZE - 1);
- }
assert((length & (PAGE_SIZE - 1)) == 0);
- assert(length >= origlen);
uint64_t page_len = length / PAGE_SIZE;
@@ -107,6 +101,73 @@ void *VMA::mmap_mem(void *v_addr, size_t length, int prot, int flags) {
return reinterpret_cast(found->begin);
}
int VMA::munmap(void *addr, size_t length) {
+ assert((length & (PAGE_SIZE - 1)) == 0);
+ assert((((uintptr_t) addr) & (PAGE_SIZE - 1)) == 0);
+
+ uint64_t page_len = length / PAGE_SIZE;
+
+ uintptr_t end = (uintptr_t) addr + length;
+ uintptr_t cur = (uintptr_t) addr;
+
+ while (cur < end) {
+ LockGuard l(regions_lock);
+ auto found = regions.upper_bound(cur);
+ --found;
+
+ if (found->second.type == EntryType::FREE) {
+ cur += found->second.length;
+ continue;
+ }
+
+ ListEntry old = found->second;
+ regions.erase(found);
+
+ if (old.begin < cur)
+ regions.emplace(std::make_pair((uintptr_t) old.begin, {old.begin, cur - old.begin, old.type, old.flags}));
+
+ old.length = old.length - (cur - old.begin);
+ old.begin = cur;
+
+ if (old.begin + old.length > end)
+ regions.emplace(std::make_pair((uintptr_t) end, {end, (old.begin + old.length) - end, old.type, old.flags}));
+
+ old.length = std::min(old.length, length);
+
+ size_t new_free_len = old.length;
+
+
+ uint64_t cur_page_len = new_free_len / PAGE_SIZE;
+
+ for (int i = 0; i < cur_page_len; i++) {
+ free4k((void *) HHDM_P2V(space->virt2real(reinterpret_cast(old.begin + i * PAGE_SIZE))));
+ {
+ LockGuard l(space_lock);
+ space->unmap(reinterpret_cast(old.begin + i * PAGE_SIZE));
+ }
+ }
+
+ // Merge free pages together
+ auto ub = regions.upper_bound(cur);
+ while (ub != regions.end() && ub->second.begin == (cur + new_free_len) && ub->second.type == EntryType::FREE) {
+ auto ubold = ub;
+ ++ub;
+ new_free_len += ubold->second.length;
+ regions.erase(ubold);
+ }
+ ub = regions.upper_bound(cur);
+ --ub;
+ while (ub != regions.end() && (ub->second.begin + ub->second.length) == cur && ub->second.type == EntryType::FREE) {
+ auto ubold = ub;
+ --ub;
+ cur = ubold->second.begin;
+ new_free_len += ubold->second.length;
+ regions.erase(ubold);
+ }
+
+ regions.emplace(std::make_pair((uintptr_t) cur, {cur, new_free_len, EntryType::FREE, old.flags}));
+
+ cur = cur + new_free_len;
+ }
return 0;
}
VMA::~VMA() {
diff --git a/src/kernel/VMA.hpp b/src/kernel/VMA.hpp
index 041b4db9f..473cd1f27 100644
--- a/src/kernel/VMA.hpp
+++ b/src/kernel/VMA.hpp
@@ -16,11 +16,11 @@ class AddressSpace;
class VMA {
public:
- VMA(AddressSpace *space);
+ VMA(AddressSpace *space);
~VMA();
- VMA(const VMA &) = delete;
- VMA(VMA &&) = delete;
+ VMA(const VMA &) = delete;
+ VMA(VMA &&) = delete;
VMA &operator=(const VMA &) = delete;
VMA &operator=(VMA &&) = delete;
@@ -32,7 +32,7 @@ public:
void *mmap_mem(void *v_addr, size_t length, int prot, int flags);
int munmap(void *addr, size_t length);
- static constexpr size_t kBrkSize = 16ULL * 1024ULL * 1024ULL;
+ static constexpr size_t kBrkSize = 4096ULL * 20ULL;
std::optional brk_start;
std::optional brk_end_fake;
std::optional brk_end_real;
diff --git a/src/kernel/elf/ElfParser.cpp b/src/kernel/elf/ElfParser.cpp
index 125d71704..2e6bff223 100644
--- a/src/kernel/elf/ElfParser.cpp
+++ b/src/kernel/elf/ElfParser.cpp
@@ -108,7 +108,7 @@ bool ElfParser::copy_to(Task *task) {
}
auto rounded_vaddr = hdr.p_vaddr & 0x000FFFFFFFFFF000ULL;
- auto real_memsz = hdr.p_memsz + (hdr.p_vaddr - rounded_vaddr);
+ auto real_memsz = PAGE_ROUND_UP(hdr.p_memsz + (hdr.p_vaddr - rounded_vaddr));
uintptr_t real_ptr = reinterpret_cast(task->_vma->mmap_mem(reinterpret_cast(rounded_vaddr), real_memsz, 0, flags | PAGE_USER));
if (real_ptr != rounded_vaddr) return false;
diff --git a/src/test/init.c b/src/test/init.c
index dfb3e906b..000c39319 100644
--- a/src/test/init.c
+++ b/src/test/init.c
@@ -32,14 +32,6 @@ int main() {
close(test123);
printf("\n %s \n", buf);
}
- while (1) {
- if (fork() == 0)
- execve("hello2", 0, 0);
- else
- wait(NULL);
- print_mem();
- sleep(500);
- }
while (1) {
printf("\n> ");