*参照元 [#ab446093] #backlinks *説明 [#t1e69ecd] -パス: [[linux-2.6.33/mm/mmap.c]] -FIXME: これは何? --説明 **引数 [#u611384f] -struct file *filp -- --[[linux-2.6.33/file]] -unsigned long addr -- -unsigned long len -- -unsigned long pgoff -- -unsigned long flags -- **返り値 [#tece2720] -unsigned long -- **参考 [#zda2b135] *実装 [#sa376f5a] /* Get an address range which is currently unmapped. * For shmat() with addr=0. * * Ugly calling convention alert: * Return value with the low bits set means error value, * ie * if (ret & ~PAGE_MASK) * error = ret; * * This function "knows" that -ENOMEM has the bits set. */ #ifndef HAVE_ARCH_UNMAPPED_AREA -アーキテクチャ独自の get_unmapped_area() を定義していなければ、 下記の標準関数を使用する。 --[[linux-2.6.33/HAVE_ARCH_UNMAPPED_AREA]] unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr, unsigned long len, unsigned long pgoff, unsigned long flags) { struct mm_struct *mm = current->mm; struct vm_area_struct *vma; unsigned long start_addr; - --[[linux-2.6.33/mm_struct]] --[[linux-2.6.33/vm_area_struct]] if (len > TASK_SIZE) return -ENOMEM; - --[[linux-2.6.33/TASK_SIZE]] if (flags & MAP_FIXED) return addr; - --[[linux-2.6.33/MAP_FIXED]] if (addr) { addr = PAGE_ALIGN(addr); - --[[linux-2.6.33/PAGE_ALIGN()]] vma = find_vma(mm, addr); - --[[linux-2.6.33/find_vma()]] if (TASK_SIZE - len >= addr && (!vma || addr + len <= vma->vm_start)) return addr; } if (len > mm->cached_hole_size) { start_addr = addr = mm->free_area_cache; } else { start_addr = addr = TASK_UNMAPPED_BASE; mm->cached_hole_size = 0; - --[[linux-2.6.33/TASK_UNMAPPED_BASE]] } full_search: for (vma = find_vma(mm, addr); ; vma = vma->vm_next) { - --[[linux-2.6.33/find_vma()]] /* At this point: (!vma || addr < vma->vm_end). */ if (TASK_SIZE - len < addr) { /* * Start a new search - just in case we missed * some holes. */ if (start_addr != TASK_UNMAPPED_BASE) { addr = TASK_UNMAPPED_BASE; start_addr = addr; mm->cached_hole_size = 0; goto full_search; } return -ENOMEM; } if (!vma || addr + len <= vma->vm_start) { /* * Remember the place where we stopped the search: */ mm->free_area_cache = addr + len; return addr; } if (addr + mm->cached_hole_size < vma->vm_start) mm->cached_hole_size = vma->vm_start - addr; addr = vma->vm_end; } } #endif *コメント [#n7581223]