#include <stdint.h>
#include <stdio.h>
#include <string.h>
-#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
};
/* 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;
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
memset (pages, 0xcc, PGSIZE * page_cnt);
#endif
- 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);
+ 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. */
/* 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;
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;
}