feature: fork() (to be tested)
This commit is contained in:
@ -75,10 +75,10 @@ int new_vzone(block_type_t type, size_t size);
|
||||
int new_kzone(block_type_t type, size_t size);
|
||||
/*----------------------------*/
|
||||
|
||||
void *vmalloc(size_t size);
|
||||
void vfree(void *ptr);
|
||||
void *umalloc(size_t size);
|
||||
void ufree(void *ptr);
|
||||
void *vrealloc(void *ptr, size_t size);
|
||||
void show_valloc_mem(void);
|
||||
void show_ualloc_mem(void);
|
||||
size_t vsize(void *virt_addr);
|
||||
void *kmalloc(size_t size);
|
||||
void kfree(void *ptr);
|
||||
|
||||
@ -29,7 +29,8 @@
|
||||
#define PDE_MULTIBOOT 1020
|
||||
|
||||
#define GET_PTE(pd_index, pt_index) \
|
||||
((uint32_t *)(VIRT_PT_BASE + ((uint32_t) pd_index) * 4096 + ((uint32_t) pt_index) * 4))
|
||||
((uint32_t *)(VIRT_PT_BASE + ((uint32_t)pd_index) * 4096 + \
|
||||
((uint32_t)pt_index) * 4))
|
||||
|
||||
#define PTE2VA(pd_index, pt_index) \
|
||||
((uint32_t *)((((uint32_t)pd_index * 1024) + (uint32_t)pt_index) * \
|
||||
@ -74,6 +75,6 @@ void init_memory(void);
|
||||
void *alloc_frame(void);
|
||||
int free_frame(void *frame_ptr);
|
||||
void *kalloc_pages(size_t nb_pages);
|
||||
void *valloc_pages(size_t nb_pages);
|
||||
int kfree_pages(void *page_ptr, size_t size);
|
||||
int vfree_pages(void *page_ptr, size_t size);
|
||||
void *ualloc_pages(size_t nb_pages);
|
||||
int kfree_pages(void *page_ptr, size_t nb_pages);
|
||||
int ufree_pages(void *page_ptr, size_t nb_pages);
|
||||
|
||||
@ -28,5 +28,5 @@ struct pcb {
|
||||
|
||||
void switch_process(struct pcb *next_pcb);
|
||||
struct pcb *create_process(uid_t uid);
|
||||
// int8_t create_kernel_process(void);
|
||||
void remove_process(struct pcb *pcb);
|
||||
pid_t fork(void);
|
||||
|
||||
@ -40,7 +40,7 @@ static void clock_handler(struct registers *regs)
|
||||
{
|
||||
scheduler_counter++;
|
||||
sleep_counter--;
|
||||
if (scheduler_counter % 100 == 0)
|
||||
if (scheduler_counter % 30 == 0)
|
||||
scheduler((uint32_t *)regs);
|
||||
}
|
||||
|
||||
|
||||
@ -33,9 +33,11 @@
|
||||
|
||||
static void uwu(void)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
kprintf("pid: %d\n", pid);
|
||||
while (1) {
|
||||
// sleep(1000);
|
||||
kprintf("uwu\n");
|
||||
// kprintf("%d\n", current_pcb->pid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,9 +57,8 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic)
|
||||
load_drivers();
|
||||
terminal_initialize();
|
||||
create_process(1);
|
||||
create_thread(current_pcb, shell_init);
|
||||
create_process(2);
|
||||
create_thread(current_pcb->next, uwu);
|
||||
// create_thread(current_pcb, shell_init);
|
||||
create_thread(current_pcb, uwu);
|
||||
toris();
|
||||
while (true)
|
||||
;
|
||||
|
||||
@ -27,7 +27,7 @@ __attribute__((noreturn)) void kpanic(const char *format, ...)
|
||||
kprintf("fault at address: %p\n", faulting_address);
|
||||
// for (int i = 16; i < 32; i++)
|
||||
// kprintf("%p\n", page_table1[i]);
|
||||
// show_valloc_mem();
|
||||
// show_ualloc_mem();
|
||||
/* kprintf("\n\n"); */
|
||||
/* print_stack(); */
|
||||
/* kprintf("\n\n"); */
|
||||
|
||||
@ -51,7 +51,7 @@ static void new_block(Zone *zone, uint32_t zone_size)
|
||||
int new_vzone(block_type_t type, uint32_t size)
|
||||
{
|
||||
// assert(current_task->pid);
|
||||
void *heap = valloc_pages(CEIL(size, PAGE_SIZE));
|
||||
void *heap = ualloc_pages(CEIL(size, PAGE_SIZE));
|
||||
if (heap == NULL) {
|
||||
kprintf(KERN_ERR "error: alloc_pages failed\n");
|
||||
return (-1);
|
||||
@ -5,7 +5,7 @@
|
||||
// FULL_INFO is to display (or not) both used and unused blocks
|
||||
#define FULL_INFO 1
|
||||
|
||||
void show_valloc_mem(void)
|
||||
void show_ualloc_mem(void)
|
||||
{
|
||||
char *const zones_name[3] = {"TINY", "SMALL", "LARGE"};
|
||||
uint32_t total_size = 0;
|
||||
@ -40,7 +40,7 @@ static uint32_t *find_next_block(size_t nb_pages)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *valloc_pages(size_t nb_pages)
|
||||
void *ualloc_pages(size_t nb_pages)
|
||||
{
|
||||
uint32_t *start = find_next_block(nb_pages);
|
||||
if (!start)
|
||||
@ -60,7 +60,7 @@ void *valloc_pages(size_t nb_pages)
|
||||
return PTE2VA(page_index / 1024, page_index % 1024);
|
||||
}
|
||||
|
||||
int vfree_pages(void *page_ptr, size_t nb_pages)
|
||||
int ufree_pages(void *page_ptr, size_t nb_pages)
|
||||
{
|
||||
const uint32_t page_addr = (uint32_t)page_ptr;
|
||||
if (page_addr % PAGE_SIZE) {
|
||||
@ -47,7 +47,7 @@ static int unmap_zone(Zone *zone)
|
||||
if (right)
|
||||
right->prev = left;
|
||||
unmap:
|
||||
err = vfree_pages((void *)zone, zone->size);
|
||||
err = ufree_pages((void *)zone, zone->size);
|
||||
if (err)
|
||||
kprintf(KERN_ERR "error: munmap failed\n");
|
||||
return (err);
|
||||
@ -94,7 +94,7 @@ static int add_available(Block *available, Block *merged)
|
||||
* newly merged block
|
||||
* Finally, we add the block to the list of available blocks
|
||||
*/
|
||||
void vfree(void *ptr)
|
||||
void ufree(void *ptr)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
return;
|
||||
@ -33,7 +33,7 @@ static Block *find_block(Zone *head, uint32_t size)
|
||||
* After the allocation, this will become
|
||||
* ... -> [5] -> [new] -> [6] -> ...
|
||||
*
|
||||
* For an example of [5].size = 32 and requiring a vmalloc of 10
|
||||
* For an example of [5].size = 32 and requiring a umalloc of 10
|
||||
* Let's say the metadata takes a size of 2:
|
||||
* ... -> [metadata][data][remaining size] -> [6]
|
||||
* ^ ^ ^
|
||||
@ -126,12 +126,12 @@ static void save_block(Zone *head, Block *block, Zone *zone)
|
||||
*
|
||||
* ptr: returns the aligned pointer of the block (after the metadata)
|
||||
*/
|
||||
void *vmalloc(uint32_t size)
|
||||
void *umalloc(uint32_t size)
|
||||
{
|
||||
void *ptr = NULL;
|
||||
|
||||
if (size == 0) {
|
||||
kprintf(KERN_WARNING "vmalloc: can't vmalloc(0)\n");
|
||||
kprintf(KERN_WARNING "umalloc: can't umalloc(0)\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -2,9 +2,9 @@
|
||||
#include "string.h"
|
||||
#include <stdint.h>
|
||||
|
||||
// Prototype for kfree and vmalloc
|
||||
// Prototype for kfree and umalloc
|
||||
void kfree(void *ptr);
|
||||
void *vmalloc(uint32_t size);
|
||||
void *umalloc(uint32_t size);
|
||||
|
||||
/*
|
||||
* ptr: block to resize (undefined behavior if invalid)
|
||||
@ -28,10 +28,10 @@ void *vrealloc(void *ptr, uint32_t size)
|
||||
block->sub_size = size;
|
||||
return (ptr);
|
||||
}
|
||||
new_ptr = vmalloc(size);
|
||||
new_ptr = umalloc(size);
|
||||
if (new_ptr == NULL)
|
||||
return NULL;
|
||||
memmove(new_ptr, ptr, block->size);
|
||||
vfree(ptr);
|
||||
ufree(ptr);
|
||||
return (new_ptr);
|
||||
}
|
||||
@ -6,7 +6,7 @@
|
||||
|
||||
static struct tcb *thread_clone(struct tcb *thread)
|
||||
{
|
||||
struct tcb *new_tcb = vmalloc(sizeof(struct tcb));
|
||||
struct tcb *new_tcb = umalloc(sizeof(struct tcb));
|
||||
if (!new_tcb)
|
||||
return NULL;
|
||||
new_tcb->tid = thread->tid;
|
||||
@ -19,20 +19,95 @@ static struct tcb *thread_clone(struct tcb *thread)
|
||||
return new_tcb;
|
||||
}
|
||||
|
||||
static void free_pts(void)
|
||||
{
|
||||
for (size_t i = USER_PT_END / 2; PD[i]; i++) {
|
||||
uint32_t *pt = PTE2VA(1023, i);
|
||||
for (size_t j = 0; j < 1024; j++)
|
||||
if (pt[j])
|
||||
ufree_pages(PTE2VA(i, j), 1);
|
||||
ufree_pages(pt, 1);
|
||||
}
|
||||
}
|
||||
|
||||
static int copy_pt(uint32_t *pt_src, uint32_t *pt_dest, size_t pd_index)
|
||||
{
|
||||
for (size_t i = 0; i < 1024; i++) {
|
||||
if (pt_src[i]) {
|
||||
pt_dest[i] = (uint32_t)alloc_frame() | INIT_FLAGS;
|
||||
if (pt_dest[i] == INIT_FLAGS) {
|
||||
for (size_t j = 0; j < i; j++)
|
||||
free_frame(
|
||||
(void *)(pt_dest[j] & PAGE_MASK));
|
||||
return -1;
|
||||
}
|
||||
void *src_page = PTE2VA(pd_index, i);
|
||||
void *dest_page = PTE2VA(pd_index + USER_PT_END / 2, i);
|
||||
memcpy(dest_page, src_page, PAGE_SIZE);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int deep_copy(struct pcb *new_pcb)
|
||||
{
|
||||
if (PD[USER_PT_END / 2])
|
||||
return -2;
|
||||
size_t i;
|
||||
for (i = USER_PT_START; PD[i]; i++) {
|
||||
void *new_pt = alloc_frame();
|
||||
if (!new_pt) {
|
||||
free_pts();
|
||||
return -1;
|
||||
}
|
||||
if (!copy_pt(PTE2VA(1023, i), new_pt, i)) {
|
||||
free_pts();
|
||||
return -1;
|
||||
}
|
||||
new_pcb->heap[i] = (uint32_t)new_pt | INIT_FLAGS;
|
||||
}
|
||||
bzero(PD + USER_PT_END / 2, i * sizeof(uint32_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
pid_t fork(void)
|
||||
{
|
||||
struct pcb *new_pcb = create_process(current_pcb->uid);
|
||||
if (!new_pcb)
|
||||
return -1;
|
||||
struct list *new_node = vmalloc(sizeof(struct list));
|
||||
struct list *new_node = kmalloc(sizeof(struct list));
|
||||
if (!new_node) {
|
||||
remove_process(new_pcb);
|
||||
return -1;
|
||||
}
|
||||
new_pcb->daddy = current_pcb;
|
||||
lst_add_back(&new_pcb->children, new_node);
|
||||
// loop on threads clone
|
||||
thread_clone(current_pcb->thread_list->content);
|
||||
|
||||
return new_pcb->pid;
|
||||
if (deep_copy(new_pcb) < 0)
|
||||
goto error;
|
||||
struct list *e;
|
||||
struct list *prev = NULL;
|
||||
for (struct list *it = current_pcb->thread_list; it; it = it->next) {
|
||||
e = kmalloc(sizeof(struct list));
|
||||
if (!e)
|
||||
goto error;
|
||||
if (prev)
|
||||
prev->next = e;
|
||||
else
|
||||
new_pcb->thread_list = e;
|
||||
struct tcb *new_content = kmalloc(sizeof(struct tcb));
|
||||
if (!new_content) {
|
||||
kfree(e);
|
||||
goto error;
|
||||
}
|
||||
memcpy(it->content, new_content, sizeof(struct tcb));
|
||||
new_content->process = new_pcb;
|
||||
e->next = NULL;
|
||||
prev = e;
|
||||
}
|
||||
|
||||
return current_pcb == new_pcb ? 0 : new_pcb->pid;
|
||||
error:
|
||||
remove_process(new_pcb);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -18,9 +18,9 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void))
|
||||
|
||||
memcpy(PD, process->heap,
|
||||
(USER_PT_END - USER_PT_START) * sizeof(uint32_t));
|
||||
new_tcb->esp0 = valloc_pages(CEIL(STACK_SIZE, PAGE_SIZE));
|
||||
new_tcb->esp0 = ualloc_pages(CEIL(STACK_SIZE, PAGE_SIZE));
|
||||
if (!new_tcb->esp0) {
|
||||
vfree(new_tcb);
|
||||
ufree(new_tcb);
|
||||
return NULL;
|
||||
}
|
||||
memcpy(process->heap, PD,
|
||||
@ -54,7 +54,7 @@ struct tcb *create_thread(struct pcb *process, void (*entry)(void))
|
||||
struct list *new_node = kmalloc(sizeof(struct list));
|
||||
if (!new_node) {
|
||||
kfree_pages(new_tcb->esp0, STACK_SIZE);
|
||||
vfree(new_tcb);
|
||||
ufree(new_tcb);
|
||||
return NULL;
|
||||
}
|
||||
new_node->content = new_tcb;
|
||||
|
||||
@ -5,5 +5,5 @@
|
||||
void heap_cmd(char *arg)
|
||||
{
|
||||
(void)arg;
|
||||
show_valloc_mem();
|
||||
show_ualloc_mem();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user