init commit of lab3_challenge3

lab3_challenge3_cow
liguo 11 months ago
parent 448d994bba
commit 452a824e9d

@ -70,7 +70,7 @@ USER_OBJS := $(addprefix $(OBJ_DIR)/, $(patsubst %.c,%.o,$(USER_CPPS)))
USER_TARGET := $(OBJ_DIR)/app_two_long_loops
USER_TARGET := $(OBJ_DIR)/app_cow
#------------------------targets------------------------
$(OBJ_DIR):
@-mkdir -p $(OBJ_DIR)

@ -196,31 +196,33 @@ int do_fork( process* parent)
// convert free_pages_address into a filter to skip reclaimed blocks in the heap
// when mapping the heap blocks
int free_block_filter[MAX_HEAP_PAGES];
memset(free_block_filter, 0, MAX_HEAP_PAGES);
uint64 heap_bottom = parent->user_heap.heap_bottom;
for (int i = 0; i < parent->user_heap.free_pages_count; i++) {
int index = (parent->user_heap.free_pages_address[i] - heap_bottom) / PGSIZE;
free_block_filter[index] = 1;
{
int free_block_filter[MAX_HEAP_PAGES];
memset(free_block_filter, 0, MAX_HEAP_PAGES);
uint64 heap_bottom = parent->user_heap.heap_bottom;
for (int i = 0; i < parent->user_heap.free_pages_count; i++) {
int index = (parent->user_heap.free_pages_address[i] - heap_bottom) / PGSIZE;
free_block_filter[index] = 1;
}
// copy and map the heap blocks
for (uint64 heap_block = current->user_heap.heap_bottom;
heap_block < current->user_heap.heap_top; heap_block += PGSIZE) {
if (free_block_filter[(heap_block - heap_bottom) / PGSIZE]) // skip free blocks
continue;
void* child_pa = alloc_page();
memcpy(child_pa, (void*)lookup_pa(parent->pagetable, heap_block), PGSIZE);
user_vm_map((pagetable_t)child->pagetable, heap_block, PGSIZE, (uint64)child_pa,
prot_to_type(PROT_WRITE | PROT_READ, 1));
}
child->mapped_info[HEAP_SEGMENT].npages = parent->mapped_info[HEAP_SEGMENT].npages;
// copy the heap manager from parent to child
memcpy((void*)&child->user_heap, (void*)&parent->user_heap, sizeof(parent->user_heap));
break;
}
// copy and map the heap blocks
for (uint64 heap_block = current->user_heap.heap_bottom;
heap_block < current->user_heap.heap_top; heap_block += PGSIZE) {
if (free_block_filter[(heap_block - heap_bottom) / PGSIZE]) // skip free blocks
continue;
void* child_pa = alloc_page();
memcpy(child_pa, (void*)lookup_pa(parent->pagetable, heap_block), PGSIZE);
user_vm_map((pagetable_t)child->pagetable, heap_block, PGSIZE, (uint64)child_pa,
prot_to_type(PROT_WRITE | PROT_READ, 1));
}
child->mapped_info[HEAP_SEGMENT].npages = parent->mapped_info[HEAP_SEGMENT].npages;
// copy the heap manager from parent to child
memcpy((void*)&child->user_heap, (void*)&parent->user_heap, sizeof(parent->user_heap));
break;
case CODE_SEGMENT:
// TODO (lab3_1): implment the mapping of child code segment to parent's
// code segment.

@ -93,6 +93,12 @@ ssize_t sys_user_yield() {
return 0;
}
ssize_t sys_user_printpa(uint64 va)
{
uint64 pa = (uint64)user_va_to_pa((pagetable_t)(current->pagetable), (void*)va);
sprint("%lx\n", pa);
return 0;
}
//
// [a0]: the syscall number; [a1] ... [a7]: arguments to the syscalls.
@ -113,6 +119,8 @@ long do_syscall(long a0, long a1, long a2, long a3, long a4, long a5, long a6, l
return sys_user_fork();
case SYS_user_yield:
return sys_user_yield();
case SYS_user_printpa:
return sys_user_printpa(a1);
default:
panic("Unknown syscall %ld \n", a0);
}

@ -14,7 +14,7 @@
// added @lab3_1
#define SYS_user_fork (SYS_user_base + 4)
#define SYS_user_yield (SYS_user_base + 5)
#define SYS_user_printpa (SYS_user_base + 6)
long do_syscall(long a0, long a1, long a2, long a3, long a4, long a5, long a6, long a7);
#endif

@ -0,0 +1,25 @@
/*
* This app fork a child process to read and write the heap data from parent process.
* Because implemented copy on write, when child process only read the heap data,
* the physical address is the same as the parent process.
* But after writing, child process heap will have different physical address.
*/
#include "user/user_lib.h"
#include "util/types.h"
int main(void) {
int *heap_data = naive_malloc();
printu("the physical address of parent process heap is: ");
printpa(heap_data);
int pid = fork();
if (pid == 0) {
printu("the physical address of child process heap before copy on write is: ");
printpa(heap_data);
heap_data[0] = 0;
printu("the physical address of child process heap after copy on write is: ");
printpa(heap_data);
}
exit(0);
return 0;
}

@ -1,28 +0,0 @@
/*
* The application of lab3_3.
* parent and child processes never give up their processor during execution.
*/
#include "user/user_lib.h"
#include "util/types.h"
int main(void) {
uint64 pid = fork();
uint64 rounds = 100000000;
uint64 interval = 10000000;
uint64 a = 0;
if (pid == 0) {
printu("Child: Hello world! \n");
for (uint64 i = 0; i < rounds; ++i) {
if (i % interval == 0) printu("Child running %ld \n", i);
}
} else {
printu("Parent: Hello world! \n");
for (uint64 i = 0; i < rounds; ++i) {
if (i % interval == 0) printu("Parent running %ld \n", i);
}
}
exit(0);
return 0;
}

@ -76,3 +76,8 @@ int fork() {
void yield() {
do_user_call(SYS_user_yield, 0, 0, 0, 0, 0, 0, 0);
}
void printpa(int* va)
{
do_user_call(SYS_user_printpa, (uint64)va, 0, 0, 0, 0, 0, 0);
}

@ -8,3 +8,4 @@ void* naive_malloc();
void naive_free(void* va);
int fork();
void yield();
void printpa(int* va);
Loading…
Cancel
Save