*参照元 [#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]

トップ   編集 差分 履歴 添付 複製 名前変更 リロード   新規 一覧 検索 最終更新   ヘルプ   最終更新のRSS