trapslab initialized
This commit is contained in:
193
user/alarmtest.c
Normal file
193
user/alarmtest.c
Normal file
@@ -0,0 +1,193 @@
|
||||
//
|
||||
// test program for the alarm lab.
|
||||
// you can modify this file for testing,
|
||||
// but please make sure your kernel
|
||||
// modifications pass the original
|
||||
// versions of these tests.
|
||||
//
|
||||
|
||||
#include "kernel/param.h"
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "kernel/riscv.h"
|
||||
#include "user/user.h"
|
||||
|
||||
void test0();
|
||||
void test1();
|
||||
void test2();
|
||||
void test3();
|
||||
void periodic();
|
||||
void slow_handler();
|
||||
void dummy_handler();
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
test0();
|
||||
test1();
|
||||
test2();
|
||||
test3();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
volatile static int count;
|
||||
|
||||
void
|
||||
periodic()
|
||||
{
|
||||
count = count + 1;
|
||||
printf("alarm!\n");
|
||||
sigreturn();
|
||||
}
|
||||
|
||||
// tests whether the kernel calls
|
||||
// the alarm handler even a single time.
|
||||
void
|
||||
test0()
|
||||
{
|
||||
int i;
|
||||
printf("test0 start\n");
|
||||
count = 0;
|
||||
sigalarm(2, periodic);
|
||||
for(i = 0; i < 1000*500000; i++){
|
||||
if((i % 1000000) == 0)
|
||||
write(2, ".", 1);
|
||||
if(count > 0)
|
||||
break;
|
||||
}
|
||||
sigalarm(0, 0);
|
||||
if(count > 0){
|
||||
printf("test0 passed\n");
|
||||
} else {
|
||||
printf("\ntest0 failed: the kernel never called the alarm handler\n");
|
||||
}
|
||||
}
|
||||
|
||||
void __attribute__ ((noinline)) foo(int i, int *j) {
|
||||
if((i % 2500000) == 0) {
|
||||
write(2, ".", 1);
|
||||
}
|
||||
*j += 1;
|
||||
}
|
||||
|
||||
//
|
||||
// tests that the kernel calls the handler multiple times.
|
||||
//
|
||||
// tests that, when the handler returns, it returns to
|
||||
// the point in the program where the timer interrupt
|
||||
// occurred, with all registers holding the same values they
|
||||
// held when the interrupt occurred.
|
||||
//
|
||||
void
|
||||
test1()
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
|
||||
printf("test1 start\n");
|
||||
count = 0;
|
||||
j = 0;
|
||||
sigalarm(2, periodic);
|
||||
for(i = 0; i < 500000000; i++){
|
||||
if(count >= 10)
|
||||
break;
|
||||
foo(i, &j);
|
||||
}
|
||||
if(count < 10){
|
||||
printf("\ntest1 failed: too few calls to the handler\n");
|
||||
} else if(i != j){
|
||||
// the loop should have called foo() i times, and foo() should
|
||||
// have incremented j once per call, so j should equal i.
|
||||
// once possible source of errors is that the handler may
|
||||
// return somewhere other than where the timer interrupt
|
||||
// occurred; another is that that registers may not be
|
||||
// restored correctly, causing i or j or the address ofj
|
||||
// to get an incorrect value.
|
||||
printf("\ntest1 failed: foo() executed fewer times than it was called\n");
|
||||
} else {
|
||||
printf("test1 passed\n");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// tests that kernel does not allow reentrant alarm calls.
|
||||
void
|
||||
test2()
|
||||
{
|
||||
int i;
|
||||
int pid;
|
||||
int status;
|
||||
|
||||
printf("test2 start\n");
|
||||
if ((pid = fork()) < 0) {
|
||||
printf("test2: fork failed\n");
|
||||
}
|
||||
if (pid == 0) {
|
||||
count = 0;
|
||||
sigalarm(2, slow_handler);
|
||||
for(i = 0; i < 1000*500000; i++){
|
||||
if((i % 1000000) == 0)
|
||||
write(2, ".", 1);
|
||||
if(count > 0)
|
||||
break;
|
||||
}
|
||||
if (count == 0) {
|
||||
printf("\ntest2 failed: alarm not called\n");
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
wait(&status);
|
||||
if (status == 0) {
|
||||
printf("test2 passed\n");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
slow_handler()
|
||||
{
|
||||
count++;
|
||||
printf("alarm!\n");
|
||||
if (count > 1) {
|
||||
printf("test2 failed: alarm handler called more than once\n");
|
||||
exit(1);
|
||||
}
|
||||
for (int i = 0; i < 1000*500000; i++) {
|
||||
asm volatile("nop"); // avoid compiler optimizing away loop
|
||||
}
|
||||
sigalarm(0, 0);
|
||||
sigreturn();
|
||||
}
|
||||
|
||||
//
|
||||
// dummy alarm handler; after running immediately uninstall
|
||||
// itself and finish signal handling
|
||||
void
|
||||
dummy_handler()
|
||||
{
|
||||
sigalarm(0, 0);
|
||||
sigreturn();
|
||||
}
|
||||
|
||||
//
|
||||
// tests that the return from sys_sigreturn() does not
|
||||
// modify the a0 register
|
||||
void
|
||||
test3()
|
||||
{
|
||||
uint64 a0;
|
||||
|
||||
sigalarm(1, dummy_handler);
|
||||
printf("test3 start\n");
|
||||
|
||||
asm volatile("lui a5, 0");
|
||||
asm volatile("addi a0, a5, 0xac" : : : "a0");
|
||||
for(int i = 0; i < 500000000; i++)
|
||||
;
|
||||
asm volatile("mv %0, a0" : "=r" (a0) );
|
||||
|
||||
if(a0 != 0xac)
|
||||
printf("test3 failed: register a0 changed\n");
|
||||
else
|
||||
printf("test3 passed\n");
|
||||
}
|
||||
10
user/bttest.c
Normal file
10
user/bttest.c
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
sleep(1);
|
||||
exit(0);
|
||||
}
|
||||
17
user/call.c
Normal file
17
user/call.c
Normal file
@@ -0,0 +1,17 @@
|
||||
#include "kernel/param.h"
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int g(int x) {
|
||||
return x+3;
|
||||
}
|
||||
|
||||
int f(int x) {
|
||||
return g(x);
|
||||
}
|
||||
|
||||
void main(void) {
|
||||
printf("%d %d\n", f(8)+1, 13);
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,62 +0,0 @@
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "user/user.h"
|
||||
|
||||
void
|
||||
test_dirtypages()
|
||||
{
|
||||
printf("dirtypages test starting\n");
|
||||
|
||||
// Allocate some pages
|
||||
char *buf = malloc(32 * 4096); // 32 pages
|
||||
if(buf == 0) {
|
||||
printf("malloc failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Clear dirty bits first by calling dirtypages
|
||||
unsigned int dbits;
|
||||
if (dirtypages(buf, 32, &dbits) < 0) {
|
||||
printf("dirtypages failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("Initial dirty bits cleared: 0x%x\n", dbits);
|
||||
|
||||
// Write to some pages to make them dirty
|
||||
buf[0] = 1; // Page 0
|
||||
buf[4096 * 5] = 1; // Page 5
|
||||
buf[4096 * 10] = 1; // Page 10
|
||||
|
||||
// Check dirty pages
|
||||
if (dirtypages(buf, 32, &dbits) < 0) {
|
||||
printf("dirtypages failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("Dirty bits after writes: 0x%x\n", dbits);
|
||||
|
||||
// Check if the expected pages are marked as dirty
|
||||
if (dbits & (1 << 0))
|
||||
printf("Page 0 is dirty (expected)\n");
|
||||
if (dbits & (1 << 5))
|
||||
printf("Page 5 is dirty (expected)\n");
|
||||
if (dbits & (1 << 10))
|
||||
printf("Page 10 is dirty (expected)\n");
|
||||
|
||||
// Check again - dirty bits should be cleared now
|
||||
if (dirtypages(buf, 32, &dbits) < 0) {
|
||||
printf("dirtypages failed\n");
|
||||
exit(1);
|
||||
}
|
||||
printf("Dirty bits after clearing: 0x%x (should be 0)\n", dbits);
|
||||
|
||||
free(buf);
|
||||
printf("dirtypages test: OK\n");
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
test_dirtypages();
|
||||
exit(0);
|
||||
}
|
||||
98
user/find.c
98
user/find.c
@@ -1,98 +0,0 @@
|
||||
#include "kernel/fs.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "kernel/types.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int match_pattern(const char *name, const char *pattern) {
|
||||
const char *star = 0;
|
||||
const char *name_ptr = name;
|
||||
const char *pattern_ptr = pattern;
|
||||
|
||||
while (1) {
|
||||
if (*pattern_ptr == '*') {
|
||||
star = pattern_ptr++;
|
||||
name_ptr = name;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!*name)
|
||||
return (!*pattern_ptr || (star && !*++pattern_ptr));
|
||||
if (*pattern_ptr == '?' || *pattern_ptr == *name) {
|
||||
pattern_ptr++;
|
||||
name++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (star) {
|
||||
pattern_ptr = star + 1;
|
||||
name = ++name_ptr;
|
||||
continue;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void find(char *path, char *pattern) {
|
||||
char buf[512], *p;
|
||||
int fd;
|
||||
struct dirent de;
|
||||
struct stat st;
|
||||
|
||||
if ((fd = open(path, 0)) < 0) {
|
||||
fprintf(2, "find: cannot open %s\n", path);
|
||||
return;
|
||||
}
|
||||
|
||||
if (fstat(fd, &st) < 0) {
|
||||
fprintf(2, "find: cannot stat %s\n", path);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (st.type != T_DIR) {
|
||||
fprintf(2, "find: %s is not a directory\n", path);
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
if (strlen(path) + 1 + DIRSIZ + 1 > sizeof buf) {
|
||||
fprintf(2, "find: path too long\n");
|
||||
close(fd);
|
||||
return;
|
||||
}
|
||||
|
||||
strcpy(buf, path);
|
||||
p = buf + strlen(buf);
|
||||
*p++ = '/';
|
||||
|
||||
while (read(fd, &de, sizeof(de)) == sizeof(de)) {
|
||||
if (de.inum == 0 || !strcmp(de.name, ".") || !strcmp(de.name, ".."))
|
||||
continue;
|
||||
|
||||
memmove(p, de.name, DIRSIZ);
|
||||
p[DIRSIZ] = 0;
|
||||
|
||||
if (stat(buf, &st) < 0) {
|
||||
fprintf(2, "find: cannot stat %s\n", buf);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (st.type == T_DIR) {
|
||||
find(buf, pattern);
|
||||
} else if (st.type == T_FILE) {
|
||||
if (match_pattern(de.name, pattern)) {
|
||||
fprintf(1, "%s\n", buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
close(fd);
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 3) {
|
||||
fprintf(2, "Usage: find <path> <pattern>\n");
|
||||
exit(1);
|
||||
}
|
||||
find(argv[1], argv[2]);
|
||||
exit(0);
|
||||
}
|
||||
164
user/pgtbltest.c
164
user/pgtbltest.c
@@ -1,164 +0,0 @@
|
||||
#include "kernel/param.h"
|
||||
#include "kernel/fcntl.h"
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/riscv.h"
|
||||
#include "user/user.h"
|
||||
|
||||
#define N (8 * (1 << 20))
|
||||
|
||||
void print_pgtbl();
|
||||
void print_kpgtbl();
|
||||
void ugetpid_test();
|
||||
void pgaccess_test();
|
||||
void superpg_test();
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
print_pgtbl();
|
||||
ugetpid_test();
|
||||
print_kpgtbl();
|
||||
pgaccess_test();
|
||||
superpg_test();
|
||||
printf("pgtbltest: all tests succeeded\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
char *testname = "???";
|
||||
|
||||
void
|
||||
err(char *why)
|
||||
{
|
||||
printf("pgtbltest: %s failed: %s, pid=%d\n", testname, why, getpid());
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void
|
||||
print_pte(uint64 va)
|
||||
{
|
||||
pte_t pte = (pte_t) pgpte((void *) va);
|
||||
printf("va 0x%lx pte 0x%lx pa 0x%lx perm 0x%lx\n", va, pte, PTE2PA(pte), PTE_FLAGS(pte));
|
||||
}
|
||||
|
||||
void
|
||||
print_pgtbl()
|
||||
{
|
||||
printf("print_pgtbl starting\n");
|
||||
for (uint64 i = 0; i < 10; i++) {
|
||||
print_pte(i * PGSIZE);
|
||||
}
|
||||
uint64 top = MAXVA/PGSIZE;
|
||||
for (uint64 i = top-10; i < top; i++) {
|
||||
print_pte(i * PGSIZE);
|
||||
}
|
||||
printf("print_pgtbl: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
ugetpid_test()
|
||||
{
|
||||
int i;
|
||||
|
||||
printf("ugetpid_test starting\n");
|
||||
testname = "ugetpid_test";
|
||||
|
||||
for (i = 0; i < 64; i++) {
|
||||
int ret = fork();
|
||||
if (ret != 0) {
|
||||
wait(&ret);
|
||||
if (ret != 0)
|
||||
exit(1);
|
||||
continue;
|
||||
}
|
||||
if (getpid() != ugetpid())
|
||||
err("missmatched PID");
|
||||
exit(0);
|
||||
}
|
||||
printf("ugetpid_test: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
print_kpgtbl()
|
||||
{
|
||||
printf("print_kpgtbl starting\n");
|
||||
kpgtbl();
|
||||
printf("print_kpgtbl: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
pgaccess_test()
|
||||
{
|
||||
char *buf;
|
||||
unsigned int abits;
|
||||
printf("pgaccess_test starting\n");
|
||||
testname = "pgaccess_test";
|
||||
buf = malloc(32 * PGSIZE);
|
||||
if (pgaccess(buf, 32, &abits) < 0)
|
||||
err("pgaccess failed");
|
||||
buf[PGSIZE * 1] += 1;
|
||||
buf[PGSIZE * 2] += 1;
|
||||
buf[PGSIZE * 30] += 1;
|
||||
if (pgaccess(buf, 32, &abits) < 0)
|
||||
err("pgaccess failed");
|
||||
if (abits != ((1 << 1) | (1 << 2) | (1 << 30)))
|
||||
err("incorrect access bits set");
|
||||
free(buf);
|
||||
printf("pgaccess_test: OK\n");
|
||||
}
|
||||
|
||||
void
|
||||
supercheck(uint64 s)
|
||||
{
|
||||
pte_t last_pte = 0;
|
||||
|
||||
for (uint64 p = s; p < s + 512 * PGSIZE; p += PGSIZE) {
|
||||
pte_t pte = (pte_t) pgpte((void *) p);
|
||||
if(pte == 0)
|
||||
err("no pte");
|
||||
if ((uint64) last_pte != 0 && pte != last_pte) {
|
||||
err("pte different");
|
||||
}
|
||||
if((pte & PTE_V) == 0 || (pte & PTE_R) == 0 || (pte & PTE_W) == 0){
|
||||
err("pte wrong");
|
||||
}
|
||||
last_pte = pte;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 512; i += PGSIZE){
|
||||
*(int*)(s+i) = i;
|
||||
}
|
||||
|
||||
for(int i = 0; i < 512; i += PGSIZE){
|
||||
if(*(int*)(s+i) != i)
|
||||
err("wrong value");
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
superpg_test()
|
||||
{
|
||||
int pid;
|
||||
|
||||
printf("superpg_test starting\n");
|
||||
testname = "superpg_test";
|
||||
|
||||
char *end = sbrk(N);
|
||||
if (end == 0 || end == (char*)0xffffffffffffffff)
|
||||
err("sbrk failed");
|
||||
|
||||
uint64 s = SUPERPGROUNDUP((uint64) end);
|
||||
supercheck(s);
|
||||
if((pid = fork()) < 0) {
|
||||
err("fork");
|
||||
} else if(pid == 0) {
|
||||
supercheck(s);
|
||||
exit(0);
|
||||
} else {
|
||||
int status;
|
||||
wait(&status);
|
||||
if (status != 0) {
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
printf("superpg_test: OK\n");
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "kernel/types.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int proc_f2s[2], proc_s2f[2];
|
||||
char buffer[8];
|
||||
pipe(proc_f2s);
|
||||
pipe(proc_s2f);
|
||||
|
||||
if (fork() == 0) {
|
||||
read(proc_s2f[0], buffer, 4);
|
||||
printf("%d: received %s\n", getpid(), buffer);
|
||||
write(proc_f2s[1], "pong", strlen("pong"));
|
||||
} else {
|
||||
write(proc_s2f[1], "ping", strlen("ping"));
|
||||
read(proc_f2s[0], buffer, 4);
|
||||
printf("%d: received %s\n", getpid(), buffer);
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,61 +0,0 @@
|
||||
#include "kernel/types.h"
|
||||
#include "user/user.h"
|
||||
|
||||
void redirect(int n, int pd[]) {
|
||||
close(n);
|
||||
dup(pd[n]);
|
||||
close(pd[0]);
|
||||
close(pd[1]);
|
||||
}
|
||||
|
||||
void primes() {
|
||||
int previous, next;
|
||||
int fd[2];
|
||||
|
||||
while (read(0, &previous, sizeof(int))) {
|
||||
printf("prime %d\n", previous);
|
||||
|
||||
if (pipe(fd) < 0) {
|
||||
fprintf(2, "pipe failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fork() == 0) {
|
||||
redirect(1, fd);
|
||||
while (read(0, &next, sizeof(int))) {
|
||||
if (next % previous != 0) {
|
||||
write(1, &next, sizeof(int));
|
||||
}
|
||||
}
|
||||
exit(0);
|
||||
} else {
|
||||
close(fd[1]);
|
||||
redirect(0, fd);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int fd[2];
|
||||
|
||||
if (pipe(fd) < 0) {
|
||||
fprintf(2, "pipe failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (fork() == 0) {
|
||||
redirect(1, fd);
|
||||
for (int i = 2; i < 36; i++) {
|
||||
write(1, &i, sizeof(int));
|
||||
}
|
||||
exit(0);
|
||||
} else {
|
||||
close(fd[1]);
|
||||
redirect(0, fd);
|
||||
primes();
|
||||
}
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
13
user/sleep.c
13
user/sleep.c
@@ -1,13 +0,0 @@
|
||||
#include "kernel/types.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 2) {
|
||||
fprintf(2, "Usage: sleep <time>\n");
|
||||
exit(1);
|
||||
}
|
||||
int time = atoi(argv[1]);
|
||||
// printf("time: %d\n", time);
|
||||
sleep(time);
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,21 +0,0 @@
|
||||
#include "kernel/param.h"
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int main() {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) < 0) {
|
||||
printf("sysinfo: failed to retrieve system information\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
printf("System Information:\n");
|
||||
printf(" Free Memory: %d bytes\n", info.freemem);
|
||||
printf(" Number of Processes: %d\n", info.nproc);
|
||||
printf(" Unused Process Slots: %d\n", info.unused_proc_num);
|
||||
printf(" Load Average: %d / 100 \n", info.load_avg);
|
||||
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/riscv.h"
|
||||
/*#include "kernel/sysinfo.h"*/
|
||||
#include "user/user.h"
|
||||
|
||||
|
||||
void
|
||||
sinfo(struct sysinfo *info) {
|
||||
if (sysinfo(info) < 0) {
|
||||
printf("FAIL: sysinfo failed");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// use sbrk() to count how many free physical memory pages there are.
|
||||
//
|
||||
int
|
||||
countfree()
|
||||
{
|
||||
uint64 sz0 = (uint64)sbrk(0);
|
||||
struct sysinfo info;
|
||||
int n = 0;
|
||||
|
||||
while(1){
|
||||
if((uint64)sbrk(PGSIZE) == 0xffffffffffffffff){
|
||||
break;
|
||||
}
|
||||
n += PGSIZE;
|
||||
}
|
||||
sinfo(&info);
|
||||
if (info.freemem != 0) {
|
||||
printf("FAIL: there is no free mem, but sysinfo.freemem=%d\n",
|
||||
info.freemem);
|
||||
exit(1);
|
||||
}
|
||||
sbrk(-((uint64)sbrk(0) - sz0));
|
||||
return n;
|
||||
}
|
||||
|
||||
void
|
||||
testmem() {
|
||||
struct sysinfo info;
|
||||
uint64 n = countfree();
|
||||
|
||||
sinfo(&info);
|
||||
|
||||
if (info.freemem!= n) {
|
||||
printf("FAIL: free mem %d (bytes) instead of %d\n", info.freemem, n);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if((uint64)sbrk(PGSIZE) == 0xffffffffffffffff){
|
||||
printf("sbrk failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sinfo(&info);
|
||||
|
||||
if (info.freemem != n-PGSIZE) {
|
||||
printf("FAIL: free mem %d (bytes) instead of %d\n", n-PGSIZE, info.freemem);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if((uint64)sbrk(-PGSIZE) == 0xffffffffffffffff){
|
||||
printf("sbrk failed");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sinfo(&info);
|
||||
|
||||
if (info.freemem != n) {
|
||||
printf("FAIL: free mem %d (bytes) instead of %d\n", n, info.freemem);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
testcall() {
|
||||
struct sysinfo info;
|
||||
|
||||
if (sysinfo(&info) < 0) {
|
||||
printf("FAIL: sysinfo failed\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if (sysinfo((struct sysinfo *) 0xeaeb0b5b00002f5e) != 0xffffffffffffffff) {
|
||||
printf("FAIL: sysinfo succeeded with bad argument\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void testproc() {
|
||||
struct sysinfo info;
|
||||
uint64 nproc, unused_proc_num;
|
||||
int status;
|
||||
int pid;
|
||||
|
||||
sinfo(&info);
|
||||
nproc = info.nproc;
|
||||
unused_proc_num = info.unused_proc_num;
|
||||
|
||||
pid = fork();
|
||||
if(pid < 0){
|
||||
printf("sysinfotest: fork failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if(pid == 0){
|
||||
sinfo(&info);
|
||||
if(info.nproc != nproc+1) {
|
||||
printf("sysinfotest: FAIL nproc is %d instead of %d\n", info.nproc, nproc+1);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
if(info.unused_proc_num != unused_proc_num-1) {
|
||||
printf("sysinfotest: FAIL unused_proc_num is %d instead of %d\n", info.unused_proc_num, unused_proc_num-1);
|
||||
exit(1);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
wait(&status);
|
||||
sinfo(&info);
|
||||
if(info.nproc != nproc) {
|
||||
printf("sysinfotest: FAIL nproc is %d instead of %d\n", info.nproc, nproc);
|
||||
exit(1);
|
||||
}
|
||||
if(info.unused_proc_num != unused_proc_num) {
|
||||
printf("sysinfotest: FAIL unused_proc_num is %d instead of %d\n", info.unused_proc_num, unused_proc_num);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void testbad() {
|
||||
int pid = fork();
|
||||
int xstatus;
|
||||
|
||||
if(pid < 0){
|
||||
printf("sysinfotest: fork failed\n");
|
||||
exit(1);
|
||||
}
|
||||
if(pid == 0){
|
||||
sinfo(0x0);
|
||||
exit(0);
|
||||
}
|
||||
wait(&xstatus);
|
||||
if(xstatus == -1) // kernel killed child?
|
||||
exit(0);
|
||||
else {
|
||||
printf("sysinfotest: testbad succeeded %d\n", xstatus);
|
||||
exit(xstatus);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
printf("sysinfotest: start\n");
|
||||
testcall();
|
||||
testmem();
|
||||
testproc();
|
||||
printf("sysinfotest: OK\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
24
user/trace.c
24
user/trace.c
@@ -1,24 +0,0 @@
|
||||
#include "kernel/param.h"
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "user/user.h"
|
||||
int
|
||||
main(int argc, char *argv[])
|
||||
{
|
||||
int i;
|
||||
char *nargv[MAXARG];
|
||||
|
||||
if(argc < 3 || (argv[1][0] < '0' || argv[1][0] > '9')){
|
||||
fprintf(2, "Usage: %s mask command\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
if (trace(atoi(argv[1])) < 0) {
|
||||
fprintf(2, "%s: trace failed\n", argv[0]);
|
||||
exit(1);
|
||||
}
|
||||
for(i = 2; i < argc && i < MAXARG; i++){
|
||||
nargv[i-2] = argv[i];
|
||||
}
|
||||
exec(nargv[0], nargv);
|
||||
exit(0);
|
||||
}
|
||||
14
user/ulib.c
14
user/ulib.c
@@ -1,13 +1,8 @@
|
||||
#include "kernel/types.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "kernel/fcntl.h"
|
||||
#ifdef LAB_PGTBL
|
||||
#include "kernel/riscv.h"
|
||||
#include "kernel/memlayout.h"
|
||||
#endif
|
||||
#include "user/user.h"
|
||||
|
||||
|
||||
//
|
||||
// wrapper so that it's OK if main() does not call exit().
|
||||
//
|
||||
@@ -150,12 +145,3 @@ memcpy(void *dst, const void *src, uint n)
|
||||
{
|
||||
return memmove(dst, src, n);
|
||||
}
|
||||
|
||||
#ifdef LAB_PGTBL
|
||||
int
|
||||
ugetpid(void)
|
||||
{
|
||||
struct usyscall *u = (struct usyscall *)USYSCALL;
|
||||
return u->pid;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
#include "kernel/types.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc != 1) {
|
||||
// 错误输出到stderr(文件描述符2)
|
||||
fprintf(2, "Usage: uptime\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fprintf(1,"up: %d\n",uptime());
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
25
user/user.h
25
user/user.h
@@ -1,12 +1,3 @@
|
||||
#ifdef LAB_MMAP
|
||||
typedef unsigned long size_t;
|
||||
typedef long int off_t;
|
||||
#endif
|
||||
|
||||
typedef unsigned int uint;
|
||||
typedef unsigned char uchar;
|
||||
typedef unsigned long uint64;
|
||||
|
||||
struct stat;
|
||||
|
||||
// system calls
|
||||
@@ -31,19 +22,6 @@ int getpid(void);
|
||||
char* sbrk(int);
|
||||
int sleep(int);
|
||||
int uptime(void);
|
||||
#ifdef LAB_NET
|
||||
int bind(uint32);
|
||||
int unbind(uint32);
|
||||
int send(uint32, uint32, uint32, char *, uint32);
|
||||
int recv(uint32, uint32*, uint32*, char *, uint32);
|
||||
#endif
|
||||
#ifdef LAB_PGTBL
|
||||
int ugetpid(void);
|
||||
uint64 pgpte(void*);
|
||||
void kpgtbl(void);
|
||||
int pgaccess(void *base, int len, void *mask);
|
||||
int dirtypages(void *base, int len, void *mask);
|
||||
#endif
|
||||
|
||||
// ulib.c
|
||||
int stat(const char*, struct stat*);
|
||||
@@ -59,9 +37,6 @@ void* memset(void*, int, uint);
|
||||
int atoi(const char*);
|
||||
int memcmp(const void *, const void *, uint);
|
||||
void *memcpy(void *, const void *, uint);
|
||||
#ifdef LAB_LOCK
|
||||
int statistics(void*, int);
|
||||
#endif
|
||||
|
||||
// umalloc.c
|
||||
void* malloc(uint);
|
||||
|
||||
@@ -244,7 +244,7 @@ copyinstr3(char *s)
|
||||
// See if the kernel refuses to read/write user memory that the
|
||||
// application doesn't have anymore, because it returned it.
|
||||
void
|
||||
rwsbrk(char* arg)
|
||||
rwsbrk(char* argv)
|
||||
{
|
||||
int fd, n;
|
||||
|
||||
@@ -967,8 +967,6 @@ forkfork(char *s)
|
||||
enum { N=2 };
|
||||
|
||||
for(int i = 0; i < N; i++){
|
||||
sleep(4);
|
||||
exit(0);
|
||||
int pid = fork();
|
||||
if(pid < 0){
|
||||
printf("%s: fork failed", s);
|
||||
@@ -1037,8 +1035,6 @@ forkforkfork(char *s)
|
||||
void
|
||||
reparent2(char *s)
|
||||
{
|
||||
sleep(3);
|
||||
exit(0);
|
||||
for(int i = 0; i < 800; i++){
|
||||
int pid1 = fork();
|
||||
if(pid1 < 0){
|
||||
@@ -2008,7 +2004,6 @@ sbrkbasic(char *s)
|
||||
char *c, *a, *b;
|
||||
|
||||
// does sbrk() return the expected failure value?
|
||||
exit(0);
|
||||
pid = fork();
|
||||
if(pid < 0){
|
||||
printf("fork failed in sbrkbasic\n");
|
||||
@@ -2071,7 +2066,6 @@ sbrkmuch(char *s)
|
||||
enum { BIG=100*1024*1024 };
|
||||
char *c, *oldbrk, *a, *lastaddr, *p;
|
||||
uint64 amt;
|
||||
exit(0);
|
||||
|
||||
oldbrk = sbrk(0);
|
||||
|
||||
@@ -2186,7 +2180,6 @@ sbrkfail(char *s)
|
||||
char *c, *a;
|
||||
int pids[10];
|
||||
int pid;
|
||||
exit(0);
|
||||
|
||||
if(pipe(fds) != 0){
|
||||
printf("%s: pipe() failed\n", s);
|
||||
|
||||
@@ -36,11 +36,3 @@ entry("getpid");
|
||||
entry("sbrk");
|
||||
entry("sleep");
|
||||
entry("uptime");
|
||||
entry("bind");
|
||||
entry("unbind");
|
||||
entry("send");
|
||||
entry("recv");
|
||||
entry("pgpte");
|
||||
entry("kpgtbl");
|
||||
entry("pgaccess");
|
||||
entry("dirtypages");
|
||||
|
||||
59
user/xargs.c
59
user/xargs.c
@@ -1,59 +0,0 @@
|
||||
#include "kernel/param.h"
|
||||
#include "kernel/stat.h"
|
||||
#include "kernel/types.h"
|
||||
#include "user/user.h"
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 2) {
|
||||
fprintf(2, "Usage: xargs command\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
char *cmd[argc + 1];
|
||||
int index = 0, data = 0;
|
||||
for (int i = 1; i < argc; ++i) {
|
||||
cmd[index++] = argv[i];
|
||||
}
|
||||
|
||||
char buffer[MAXARG];
|
||||
char line[MAXARG] = {0};
|
||||
int line_pos = 0;
|
||||
|
||||
while ((data = read(0, buffer, MAXARG)) > 0) {
|
||||
for (int i = 0; i < data; ++i) {
|
||||
if (buffer[i] == '\n' || buffer[i] == ' ') {
|
||||
line[line_pos] = 0;
|
||||
if (line_pos > 0) {
|
||||
char *arg = malloc(line_pos + 1);
|
||||
strcpy(arg, line);
|
||||
cmd[index++] = arg;
|
||||
}
|
||||
line_pos = 0;
|
||||
|
||||
if (buffer[i] == '\n') {
|
||||
cmd[index] = 0;
|
||||
if (fork() == 0) {
|
||||
exec(cmd[0], cmd);
|
||||
exit(1);
|
||||
}
|
||||
wait(0);
|
||||
index = argc - 1;
|
||||
}
|
||||
} else {
|
||||
line[line_pos++] = buffer[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// bug fixed
|
||||
if (line_pos > 0) {
|
||||
line[line_pos] = 0;
|
||||
cmd[index++] = line;
|
||||
cmd[index] = 0;
|
||||
if (fork() == 0) {
|
||||
exec(cmd[0], cmd);
|
||||
}
|
||||
wait(0);
|
||||
}
|
||||
exit(0);
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
mkdir a
|
||||
echo hello > a/b
|
||||
mkdir c
|
||||
echo hello > c/b
|
||||
echo hello > b
|
||||
find . b | xargs grep hello
|
||||
Reference in New Issue
Block a user