static inline unsigned long low_free_pages(void) { return nr_free_pages() - nr_free_highpages(); }
/* SunOS is completely broken... it returns 0 on success, otherwise * ENOMEM. For sys_sbrk() it wants the old brk value as a return * on success and ENOMEM as before on failure. */ asmlinkage int sunos_brk(unsigned long brk) { int freepages, retval = -ENOMEM; unsigned long rlim; unsigned long newbrk, oldbrk; down_write(¤t->mm->mmap_sem); if (ARCH_SUN4C_SUN4) { if (brk >= 0x20000000 && brk < 0xe0000000) { goto out; } } if (brk < current->mm->end_code) goto out; newbrk = PAGE_ALIGN(brk); oldbrk = PAGE_ALIGN(current->mm->brk); retval = 0; if (oldbrk == newbrk) { current->mm->brk = brk; goto out; } /* * Always allow shrinking brk */ if (brk <= current->mm->brk) { current->mm->brk = brk; do_munmap(current->mm, newbrk, oldbrk-newbrk); goto out; } /* * Check against rlimit and stack.. */ retval = -ENOMEM; rlim = current->signal->rlim[RLIMIT_DATA].rlim_cur; if (rlim >= RLIM_INFINITY) rlim = ~0; if (brk - current->mm->end_code > rlim) goto out; /* * Check against existing mmap mappings. */ if (find_vma_intersection(current->mm, oldbrk, newbrk+PAGE_SIZE)) goto out; /* * stupid algorithm to decide if we have enough memory: while * simple, it hopefully works in most obvious cases.. Easy to * fool it, but this should catch most mistakes. */ freepages = global_page_state(NR_FILE_PAGES); freepages >>= 1; freepages += nr_free_pages(); freepages += nr_swap_pages; freepages -= num_physpages >> 4; freepages -= (newbrk-oldbrk) >> PAGE_SHIFT; if (freepages < 0) goto out; /* * Ok, we have probably got enough memory - let it rip. */ current->mm->brk = brk; do_brk(oldbrk, newbrk-oldbrk); retval = 0; out: up_write(¤t->mm->mmap_sem); return retval; }
// LAB2: below code is used to check the first fit allocation algorithm (your EXERCISE 1) // NOTICE: You SHOULD NOT CHANGE basic_check, default_check functions! static void default_check(void) { int count = 0, total = 0; list_entry_t *le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); assert(PageProperty(p)); count ++, total += p->property; } assert(total == nr_free_pages()); basic_check(); struct Page *p0 = alloc_pages(5), *p1, *p2; assert(p0 != NULL); assert(!PageProperty(p0)); list_entry_t free_list_store = free_list; list_init(&free_list); assert(list_empty(&free_list)); assert(alloc_page() == NULL); unsigned int nr_free_store = nr_free; nr_free = 0; free_pages(p0 + 2, 3); assert(alloc_pages(4) == NULL); assert(PageProperty(p0 + 2) && p0[2].property == 3); assert((p1 = alloc_pages(3)) != NULL); assert(alloc_page() == NULL); assert(p0 + 2 == p1); p2 = p0 + 1; free_page(p0); free_pages(p1, 3); assert(PageProperty(p0) && p0->property == 1); assert(PageProperty(p1) && p1->property == 3); assert((p0 = alloc_page()) == p2 - 1); free_page(p0); assert((p0 = alloc_pages(2)) == p2 + 1); free_pages(p0, 2); free_page(p2); assert((p0 = alloc_pages(5)) != NULL); assert(alloc_page() == NULL); assert(nr_free == 0); nr_free = nr_free_store; free_list = free_list_store; free_pages(p0, 5); le = &free_list; while ((le = list_next(le)) != &free_list) { struct Page *p = le2page(le, page_link); count --, total -= p->property; } assert(count == 0); assert(total == 0); }
static void check_vma_struct(void) { size_t nr_free_pages_store = nr_free_pages(); struct mm_struct *mm = mm_create(); assert(mm != NULL); int step1 = 10, step2 = step1 * 10; int i; for (i = step1; i >= 1; i --) { struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); assert(vma != NULL); insert_vma_struct(mm, vma); } for (i = step1 + 1; i <= step2; i ++) { struct vma_struct *vma = vma_create(i * 5, i * 5 + 2, 0); assert(vma != NULL); insert_vma_struct(mm, vma); } list_entry_t *le = list_next(&(mm->mmap_list)); for (i = 1; i <= step2; i ++) { assert(le != &(mm->mmap_list)); struct vma_struct *mmap = le2vma(le, list_link); assert(mmap->vm_start == i * 5 && mmap->vm_end == i * 5 + 2); le = list_next(le); } for (i = 5; i <= 5 * step2; i +=5) { struct vma_struct *vma1 = find_vma(mm, i); assert(vma1 != NULL); struct vma_struct *vma2 = find_vma(mm, i+1); assert(vma2 != NULL); struct vma_struct *vma3 = find_vma(mm, i+2); assert(vma3 == NULL); struct vma_struct *vma4 = find_vma(mm, i+3); assert(vma4 == NULL); struct vma_struct *vma5 = find_vma(mm, i+4); assert(vma5 == NULL); assert(vma1->vm_start == i && vma1->vm_end == i + 2); assert(vma2->vm_start == i && vma2->vm_end == i + 2); } for (i =4; i>=0; i--) { struct vma_struct *vma_below_5= find_vma(mm,i); if (vma_below_5 != NULL ) { cprintf("vma_below_5: i %x, start %x, end %x\n",i, vma_below_5->vm_start, vma_below_5->vm_end); } assert(vma_below_5 == NULL); } mm_destroy(mm); assert(nr_free_pages_store == nr_free_pages()); cprintf("check_vma_struct() succeeded!\n"); }