X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?p=pintos-anon;a=blobdiff_plain;f=src%2Fthreads%2Fpalloc.c;h=4fc8394c8f078a20c5a48722c36e3e022658620e;hp=c99abe35daaafb66568bce5b24256be1e02a6660;hb=a03618133f7df0954802a470a4bee7674f7aed45;hpb=c9bd85496b98a3cc5ab79701644f73be7d910890 diff --git a/src/threads/palloc.c b/src/threads/palloc.c index c99abe3..4fc8394 100644 --- a/src/threads/palloc.c +++ b/src/threads/palloc.c @@ -7,10 +7,9 @@ #include #include #include -#include "threads/init.h" #include "threads/loader.h" -#include "threads/mmu.h" #include "threads/synch.h" +#include "threads/vaddr.h" /* Page allocator. Hands out memory in page-size (or page-multiple) chunks. See malloc.h for an allocator that @@ -35,26 +34,20 @@ struct pool }; /* Two pools: one for kernel data, one for user pages. */ -struct pool kernel_pool, user_pool; - -/* Maximum number of pages to put in user pool. */ -size_t user_page_limit = SIZE_MAX; +static struct pool kernel_pool, user_pool; static void init_pool (struct pool *, void *base, size_t page_cnt, const char *name); static bool page_from_pool (const struct pool *, void *page); -/* Initializes the page allocator. */ +/* Initializes the page allocator. At most USER_PAGE_LIMIT + pages are put into the user pool. */ void -palloc_init (void) +palloc_init (size_t user_page_limit) { - /* End of the kernel as recorded by the linker. - See kernel.lds.S. */ - extern char _end; - - /* Free memory. */ - uint8_t *free_start = pg_round_up (&_end); - uint8_t *free_end = ptov (ram_pages * PGSIZE); + /* Free memory starts at 1 MB and runs to the end of RAM. */ + uint8_t *free_start = ptov (1024 * 1024); + uint8_t *free_end = ptov (init_ram_pages * PGSIZE); size_t free_pages = (free_end - free_start) / PGSIZE; size_t user_pages = free_pages / 2; size_t kernel_pages; @@ -85,8 +78,9 @@ palloc_get_multiple (enum palloc_flags flags, size_t page_cnt) return NULL; lock_acquire (&pool->lock); - page_idx = bitmap_scan_and_flip (pool->used_map, 0, page_cnt, false); + lock_release (&pool->lock); + if (page_idx != BITMAP_ERROR) pages = pool->base + PGSIZE * page_idx; else @@ -103,12 +97,11 @@ palloc_get_multiple (enum palloc_flags flags, size_t page_cnt) PANIC ("palloc_get: out of pages"); } - lock_release (&pool->lock); - return pages; } -/* Obtains and returns a single free page. +/* Obtains a single free page and returns its kernel virtual + address. If PAL_USER is set, the page is obtained from the user pool, otherwise from the kernel pool. If PAL_ZERO is set in FLAGS, then the page is filled with zeros. If no pages are @@ -144,10 +137,8 @@ palloc_free_multiple (void *pages, size_t page_cnt) memset (pages, 0xcc, PGSIZE * page_cnt); #endif - lock_acquire (&pool->lock); - ASSERT (bitmap_all (pool->used_map, page_idx, page_idx + page_cnt)); - bitmap_set_multiple (pool->used_map, page_idx, page_idx + page_cnt, false); - lock_release (&pool->lock); + ASSERT (bitmap_all (pool->used_map, page_idx, page_cnt)); + bitmap_set_multiple (pool->used_map, page_idx, page_cnt, false); } /* Frees the page at PAGE. */ @@ -165,7 +156,7 @@ init_pool (struct pool *p, void *base, size_t page_cnt, const char *name) /* We'll put the pool's used_map at its base. Calculate the space needed for the bitmap and subtract it from the pool's size. */ - size_t bm_pages = DIV_ROUND_UP (bitmap_needed_bytes (page_cnt), PGSIZE); + size_t bm_pages = DIV_ROUND_UP (bitmap_buf_size (page_cnt), PGSIZE); if (bm_pages > page_cnt) PANIC ("Not enough memory in %s for bitmap.", name); page_cnt -= bm_pages; @@ -173,9 +164,8 @@ init_pool (struct pool *p, void *base, size_t page_cnt, const char *name) printf ("%zu pages available in %s.\n", page_cnt, name); /* Initialize the pool. */ - lock_init (&p->lock, name); - p->used_map = bitmap_create_preallocated (page_cnt, base, - bm_pages * PGSIZE); + lock_init (&p->lock); + p->used_map = bitmap_create_in_buf (page_cnt, base, bm_pages * PGSIZE); p->base = base + bm_pages * PGSIZE; }