static void test_large_block_reads(){ blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0)); int i; for (i = 1; i < 129; i++){ char *readbuf = (char *) page_alloc_n(i); char *writebuf = (char *) page_alloc_n(i); int j; for (j = 0; j < (i * BLOCK_SIZE); j++){ writebuf[j] = 'f'; } int write_result = bd->bd_ops->write_block(bd, writebuf, 0, i); KASSERT(write_result == 0); int read_result = bd->bd_ops->read_block(bd, readbuf, 0, i); KASSERT(read_result == 0); int k; for (k = 0; k < (i * BLOCK_SIZE); k++){ KASSERT(readbuf[k] == 'f'); } page_free_n((void *) readbuf, i); page_free_n((void *) writebuf, i); } dbg(DBG_TESTPASS, "large read stress tests passed\n"); }
int kshell_ata_read(kshell_t *k, int argc, char **argv){ if (argc != 3){ dbg(DBG_DISK | DBG_TERM, "received wrong amount of arguments\n"); kprintf(k, "Usage: <read_block> <num_blocks>\n"); return -1; } blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0)); int blocknum = toint(argv[1]); int count = toint(argv[2]); char *data = (char *) page_alloc_n(count); if (data == NULL){ kprintf(k, "not enough memory"); return -1; } int result = bd->bd_ops->read_block(bd, data, blocknum, count); char newline[2] = {'\n', '\0'}; kprintf(k, data); kprintf(k, newline); page_free_n((void *) data, count); return result; }
/** * Allocates a new kernel stack. * * @return a newly allocated stack, or NULL if there is not enough * memory available */ static char *alloc_stack(void) { /* extra page for "magic" data */ char *kstack; int npages = 1 + (DEFAULT_STACK_SIZE >> PAGE_SHIFT); kstack = (char *)page_alloc_n(npages); return kstack; }
/** * Allocates a new kernel stack. * * @return a newly allocated stack, or NULL if there is not enough * memory available */ static char * alloc_stack(void) { /* extra page for "magic" data */ char *kstack; int npages = 1 + (DEFAULT_STACK_SIZE >> PAGE_SHIFT); /* MC define in kernel/mm/page.c, kernel/include/config.h page shift = 12, 4MB as a unit define in kernel/include/config.h DEFAULT_STACK_SIZE 56*1024 */ kstack = (char *)page_alloc_n(npages); return kstack; }
void test_multiple_threads(){ dbg(DBG_TEST | DBG_DISK, "testing reading and writing to disk with multiple threads\n"); blockdev_t *bd = blockdev_lookup(MKDEVID(1, 0)); KASSERT (bd != NULL); char *readbuf1 = (char *) page_alloc_n(BLOCKS_TO_READ); char *readbuf2 = (char *) page_alloc_n(BLOCKS_TO_READ); char *writebuf1 = (char *) page_alloc_n(BLOCKS_TO_WRITE); char *writebuf2 = (char *) page_alloc_n(BLOCKS_TO_WRITE); KASSERT(readbuf1 != NULL && readbuf2 != NULL && writebuf2 != NULL && writebuf2 != NULL && "not enough memory"); unsigned int i; for (i = 0; i < (BLOCK_SIZE * BLOCKS_TO_WRITE); i++){ writebuf1[i] = 'a'; writebuf2[i] = 'b'; } /* create and run procs and threads for writing */ rw_args_t write_args_1 = {bd, writebuf1, BLOCKNUM_1, BLOCKS_TO_WRITE}; rw_args_t write_args_2 = {bd, writebuf2, BLOCKNUM_2, BLOCKS_TO_WRITE}; proc_t *wp1 = proc_create("ata_write_proc_1"); proc_t *wp2 = proc_create("ata_write_proc_2"); kthread_t *wt1 = kthread_create(wp1, write_func, 0, (void *) &write_args_1); kthread_t *wt2 = kthread_create(wp2, write_func, 0, (void *) &write_args_2); sched_make_runnable(wt1); sched_make_runnable(wt2); int status; do_waitpid(wp1->p_pid, 0, &status); do_waitpid(wp2->p_pid, 0, &status); /* create and run procs and threads for reading */ rw_args_t read_args_1 = {bd, readbuf1, BLOCKNUM_1, BLOCKS_TO_READ}; rw_args_t read_args_2 = {bd, readbuf2, BLOCKNUM_2, BLOCKS_TO_READ}; proc_t *rp1 = proc_create("ata_read_proc_1"); proc_t *rp2 = proc_create("ata_read_proc_2"); kthread_t *rt1 = kthread_create(rp1, read_func, 0, (void *) &read_args_1); kthread_t *rt2 = kthread_create(rp2, read_func, 0, (void *) &read_args_2); sched_make_runnable(rt1); sched_make_runnable(rt2); do_waitpid(rp1->p_pid, 0, &status); do_waitpid(rp2->p_pid, 0, &status); /* make sure that we wrote and read properly */ unsigned int j; for (j = 0; j < BLOCK_SIZE * BLOCKS_TO_READ; j++){ KASSERT(readbuf1[j] == 'a'); KASSERT(readbuf2[j] == 'b'); } page_free_n((void *) readbuf1, BLOCKS_TO_READ); page_free_n((void *) readbuf2, BLOCKS_TO_READ); page_free_n((void *) writebuf1, BLOCKS_TO_WRITE); page_free_n((void *) writebuf2, BLOCKS_TO_WRITE); dbg(DBG_TESTPASS, "All multi-threaded read/write tests passed\n"); }