- 论坛徽章:
- 1
|
如下代码来自于linux 2.4.18版本。中代码mlock.c
- static int do_mlock(unsigned long start, size_t len, int on)
- {
- unsigned long nstart, end, tmp;
- struct vm_area_struct * vma, * next;
- int error;
- if (on && !capable(CAP_IPC_LOCK))
- return -EPERM;
- len = PAGE_ALIGN(len);
- end = start + len;
- if (end < start)
- return -EINVAL;
- if (end == start)
- return 0;
- vma = find_vma(current->;mm, start);
- if (!vma || vma->;vm_start >; start)
- return -ENOMEM;
- for (nstart = start ; ; ) {
- unsigned int newflags;
- /* Here we know that vma->;vm_start <= nstart < vma->;vm_end. */
- newflags = vma->;vm_flags | VM_LOCKED;
- if (!on)
- newflags &= ~VM_LOCKED;
- if (vma->;vm_end >;= end) {
- error = mlock_fixup(vma, nstart, end, newflags);
- break;
- }
- tmp = vma->;vm_end;
- next = vma->;vm_next;
- error = mlock_fixup(vma, nstart, tmp, newflags);
- if (error)
- break;
- nstart = tmp;
- vma = next;
- if (!vma || vma->;vm_start != nstart) {
- error = -ENOMEM;
- break;
- }
- }
- return error;
- }
复制代码
这个系统调用有函数sys_mlock调用。实现屏蔽内存中某些用户进程所要求的页。在函数sys_mlock中的开始部分,最len做了一些初始化,如下:
- len = PAGE_ALIGN(len + (start & ~PAGE_MASK));
- start &= PAGE_MASK;
- locked = len >;>; PAGE_SHIFT;
- locked += current->;mm->;locked_vm;
- lock_limit = current->;rlim[RLIMIT_MEMLOCK].rlim_cur;
- lock_limit >;>;= PAGE_SHIFT;
复制代码
- 如此处理后在do_mlock之前
- len=(len+(start &~PAGE_MASK)+ ~PAGE_MASK)&PAGE_MASK;
- start &=PAGE_MASK;
- 在do_mlock初始话后,len可能如下
- len=(len+~PAGE_MASK)&PAGE_MASK;
- 这样一来,mlock要对由start所在页的起始地址开始,长度为len(注:len=(len+(start&~PAGE_MASK)+ ~PAGE_MASK)&PAGE_MASK)的内存区域的页进行加锁。
- 接下来,一起分析一下这个函数。并且有几个疑问。
- 1、这些具体内存区域的页是不是必须是常驻内存的?
- 2、通过fork()调用所创建的子进程能不能够继承由父进程调用mlock锁住的页面?
- 3、内存加锁没有使用压栈技术,这样被锁住多次的页面可以通过调用一次munlock或者munlockall释放相应的页面会不会出现问题?
复制代码
[ 本帖最后由 mq110 于 2006-3-13 19:14 编辑 ] |
|