[dirty:segfault] stage 1
This commit is contained in:
commit
b4edf54aa6
|
@ -0,0 +1,23 @@
|
|||
CCFLAGS = -g -O0 -Iinc/ -I.
|
||||
|
||||
|
||||
main: main.o kernel.o mmu.o process.o random.o
|
||||
gcc $(CCFLAGS) -o main main.o kernel.o mmu.o process.o random.o
|
||||
|
||||
main.o: src/main.c
|
||||
gcc $(CCFLAGS) -c -o main.o src/main.c
|
||||
|
||||
kernel.o: src/kernel.c
|
||||
gcc $(CCFLAGS) -c -o kernel.o src/kernel.c
|
||||
|
||||
mmu.o: src/mmu.c
|
||||
gcc $(CCFLAGS) -c -o mmu.o src/mmu.c
|
||||
|
||||
process.o: src/process.c
|
||||
gcc $(CCFLAGS) -c -o process.o src/process.c
|
||||
|
||||
random.o: src/random.c
|
||||
gcc $(CCFLAGS) -c -o random.o src/random.c
|
||||
|
||||
clean:
|
||||
rm *.o main
|
|
@ -0,0 +1,34 @@
|
|||
#ifndef KERNEL_HEADER
|
||||
#define KERNEL_HEADER
|
||||
|
||||
#include "process.h"
|
||||
|
||||
struct RunQ {
|
||||
struct Process *current_proc;
|
||||
size_t max_procs;
|
||||
size_t proc_amount;
|
||||
size_t next_proc_id;
|
||||
};
|
||||
|
||||
struct RunQ *RunQ(size_t max_procs);
|
||||
void RUNQ_add_process(size_t max_page_accesses, size_t total_pages_owned);
|
||||
|
||||
static struct RunQ *runq;
|
||||
|
||||
|
||||
struct PhysPage {
|
||||
size_t ppn;
|
||||
size_t busy_flag;
|
||||
struct PhysPage *prev;
|
||||
struct PhysPage *next;
|
||||
struct PageTable *pt;
|
||||
size_t pt_index;
|
||||
};
|
||||
|
||||
static struct PhysPage *first_free_page;
|
||||
static struct PhysPage *first_busy_page;
|
||||
|
||||
|
||||
void KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,2 @@
|
|||
void MMU_read(struct PageTableEntry *pt, size_t page_no);
|
||||
void MMU_write(struct PageTableEntry *pt, size_t page_no);
|
|
@ -0,0 +1,29 @@
|
|||
#ifndef PROCESS_HEADER
|
||||
#define PROCESS_HEADER
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
struct PageTableEntry {
|
||||
size_t p:1;
|
||||
size_t r:1;
|
||||
size_t m:1;
|
||||
size_t ppn;
|
||||
};
|
||||
|
||||
struct Process {
|
||||
struct Process *prev;
|
||||
struct Process *next;
|
||||
size_t id;
|
||||
size_t pages_accessed;
|
||||
size_t max_accesses;
|
||||
size_t total_pages_owned;
|
||||
struct PageTableEntry *pt;
|
||||
};
|
||||
|
||||
struct Process *Process(size_t proc_id,
|
||||
size_t max_accesses,
|
||||
size_t total_pages_owned);
|
||||
|
||||
size_t PROCESS_run_for(struct Process *p, size_t time_bits);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
#ifndef RANDOM_HEADER
|
||||
#define RANDOM_HEADER
|
||||
|
||||
size_t randint(size_t max);
|
||||
|
||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kernel.h"
|
||||
#include "process.h"
|
||||
|
||||
struct RunQ *
|
||||
RunQ(size_t max_procs)
|
||||
{
|
||||
struct RunQ *runq = malloc(sizeof(struct RunQ));
|
||||
runq->current_proc = NULL;
|
||||
runq->max_procs = max_procs;
|
||||
runq->proc_amount = 0;
|
||||
runq->next_proc_id = 1;
|
||||
|
||||
return runq;
|
||||
}
|
||||
|
||||
void
|
||||
RUNQ_add_process(size_t max_page_accesses,
|
||||
size_t total_pages_owned)
|
||||
{
|
||||
if (runq->proc_amount >= runq->max_procs)
|
||||
return;
|
||||
|
||||
struct Process *new_p = Process(runq->next_proc_id, max_page_accesses, total_pages_owned);
|
||||
|
||||
if (!runq->current_proc) {
|
||||
runq->current_proc = new_p;
|
||||
new_p->next = new_p;
|
||||
new_p->prev = new_p;
|
||||
} else {
|
||||
new_p->next = runq->current_proc;
|
||||
new_p->prev = runq->current_proc->prev;
|
||||
new_p->next->prev = new_p;
|
||||
new_p->prev->next = new_p;
|
||||
runq->current_proc = new_p;
|
||||
}
|
||||
|
||||
runq->proc_amount++;
|
||||
runq->next_proc_id++;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
KERNEL_page_fault(struct PageTableEntry *pt, size_t page_no)
|
||||
{
|
||||
if (first_free_page) {
|
||||
pt[page_no].ppn = first_free_page->ppn;
|
||||
pt[page_no].p = 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "kernel.h"
|
||||
|
||||
#include "config.h"
|
||||
|
||||
int
|
||||
main(void)
|
||||
{
|
||||
first_busy_page = NULL;
|
||||
|
||||
struct PhysPage *first_free_page = malloc(sizeof(struct PhysPage));
|
||||
first_free_page->ppn = 0;
|
||||
first_free_page->busy_flag = 0;
|
||||
first_free_page->prev = first_free_page;
|
||||
first_free_page->next = first_free_page;
|
||||
|
||||
for (int i = 1; i <= PHYSICAL_PAGE_AMOUNT; i++) {
|
||||
struct PhysPage *pp = malloc(sizeof(struct PhysPage));
|
||||
pp->ppn = i;
|
||||
pp->busy_flag = 0;
|
||||
|
||||
/*
|
||||
* insert into here
|
||||
* |
|
||||
* v
|
||||
* [ ] [ ] [ ]
|
||||
* ^
|
||||
* |
|
||||
* *first_free_page
|
||||
*/
|
||||
pp->prev = first_free_page->prev;
|
||||
pp->next = first_free_page;
|
||||
pp->next->prev = pp;
|
||||
pp->prev->next = pp;
|
||||
}
|
||||
|
||||
runq = RunQ(10);
|
||||
RUNQ_add_process(10000, 50);
|
||||
RUNQ_add_process(10000, 50);
|
||||
RUNQ_add_process(10000, 50);
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
#include "kernel.h"
|
||||
|
||||
void MMU_read(struct PageTableEntry *pt, size_t page_no)
|
||||
{
|
||||
if (!pt[page_no].p)
|
||||
KERNEL_page_fault(pt, page_no);
|
||||
|
||||
pt[page_no].r = 1;
|
||||
}
|
||||
|
||||
void MMU_write(struct PageTableEntry *pt, size_t page_no)
|
||||
{
|
||||
if (!pt[page_no].p)
|
||||
KERNEL_page_fault(pt, page_no);
|
||||
|
||||
pt[page_no].r = 1;
|
||||
pt[page_no].m = 1;
|
||||
}
|
|
@ -0,0 +1,43 @@
|
|||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "process.h"
|
||||
#include "mmu.h"
|
||||
#include "random.h"
|
||||
|
||||
struct Process *
|
||||
Process(size_t proc_id, size_t max_accesses, size_t total_pages_owned)
|
||||
{
|
||||
struct Process *p = malloc(sizeof(struct Process));
|
||||
p->id = proc_id;
|
||||
p->max_accesses = max_accesses;
|
||||
p->pages_accessed = 0;
|
||||
p->total_pages_owned = total_pages_owned;
|
||||
p->pt = malloc(sizeof(struct PageTableEntry) * total_pages_owned);
|
||||
|
||||
for (size_t i = 0; i < p->total_pages_owned; i++)
|
||||
p->pt[i].p = 0;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
size_t PROCESS_run_for(struct Process *p, size_t time_bits)
|
||||
{
|
||||
for (size_t i = 0;
|
||||
(i < time_bits) && (p->pages_accessed < p->max_accesses);
|
||||
i++, p->pages_accessed++)
|
||||
{
|
||||
// no working set yet
|
||||
int accessed_page_no = randint(p->total_pages_owned);
|
||||
|
||||
if (randint(10) > 7) {
|
||||
printf("[process] Writing to page #%d\n", accessed_page_no);
|
||||
MMU_write(p->pt, accessed_page_no);
|
||||
} else {
|
||||
printf("[process] Reading from page #%d\n", accessed_page_no);
|
||||
MMU_read(p->pt, accessed_page_no);
|
||||
}
|
||||
}
|
||||
|
||||
return p->pages_accessed >= p->max_accesses;
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
#include <fcntl.h>
|
||||
#include <stddef.h>
|
||||
#include <unistd.h>
|
||||
|
||||
size_t randint(size_t max)
|
||||
{
|
||||
size_t random_value;
|
||||
|
||||
int f = open("/dev/urandom", O_RDONLY);
|
||||
read(f, &random_value, 8);
|
||||
close(f);
|
||||
|
||||
return random_value % max;
|
||||
}
|
Loading…
Reference in New Issue