linux 内核实验六实现
2013-04-13 18:14
344 查看
构造新内核同步机制实验 实验目的: 实验问题A 分析以上进程同步机制的功能和工作过程,通过重新定义struct __myevent结构来模拟一个信号量同步机制,并编写测试程序检测它的功能。 实验问题B 在2.6节实验问题B中我们加入了一个缺页计数器每当调用缺页处理函数则对其加一,并利用自定义系统调用返回该值。考虑一个并发控制方 案,利用实验A实现的信号量控制多个进程与缺页处理器互斥的访问缺页计数器。(可编一个shell批处理命令并发启动多个进程访问缺页计 数)。 程序完整源代码: 增加新的系统调用 step 1:/usr/src/linux../arch/x86/kernel/syscall_tabel32.S .long sys_lightbluetest .long sys_lightbluecall .long sys_lightbluetime .long sys_myevent_open .long sys_myevent_wait .long sys_myevent_signal .long sys_myevent_close .long sys_modifytimes step 2:/usr/src/linux../arch/x86/include/asm/unistd_32.h #/usr/src/linux../include/asm-generic/unistd.h #define __NR_lightbluetest 347 #define __NR_lightbluecall 348 #define __NR_lightbluetime 349 #define __NR_myevent_open 340 #define __NR_myevent_wait 351 #define __NR_myevent_signal 352 #define __NR_myevent_close 353 #define __NR_modifytimes 354 and modify the __NR_syscall 355 become #define __NR_lightbluetest 347 #define __NR_lightbluecall 348 #define __NR_lightbluetime 349 #define __NR_myevent_open 350 #define __NR_myevent_wait 351 #define __NR_myevent_signal 352 #define __NR_myevent_close 353 #define __NR_modifytimes 354 #ifdef __KERNEL__ #define __NR_syscall 355 step 3:/usr/src/linux../include/linux/syscall.h add the function statements as below asmlinkage long sys_lightbluetest(void); asmlinkage long sys_lightbluecall(struct timeval* v_time,struct timespec *s_time); asmlinkage long sys_lightbluetime(struct timeval* v_time,struct timespec * s_time,unsigned long *times) ; asmlinkage long sys_myevent_open(int eventNum,int count); asmlinkage long sys_myevent_wait(int eventNum); asmlinkage long sys_myevent_signal(int eventNum); asmlinkage long sys_myevent_close(int eventNum); asmlinkage long sys_modifytimes(unsigned long times); step 4:/usr/src/linux../kernel/sys.c #include <linux/time.h> #include <linux/wait.h> #include <linux/lightblue.h> #include <linux/lightbluesema.h> myevent_t * scheventNum(int eventNum,myevent_t **prev){ myevent_t *tmp=lpmyevent_head; *prev=NULL; while(tmp){ if(tmp->eventNum==eventNum) return tmp; *prev = tmp; tmp=tmp->next; } return NULL; } asmlinkage long sys_lightbluetest(){ printk("lightblue test\n"); return 222; } asmlinkage long sys_lightbluecall(struct timeval* v_time,struct timespec *s_time){ printk("hello call\n"); *s_time=current_kernel_time(); do_gettimeofday(v_time); return 17; } asmlinkage long sys_lightbluetime(struct timeval* v_time,struct timespec * s_time,unsigned long *times) { printk("hello call\n"); *times=lightbluetimes; *s_time=current_kernel_time(); do_gettimeofday(v_time); return 17; } asmlinkage long sys_myevent_open(int eventNum,int count){ printk("open it\n"); myevent_t * new; myevent_t *prev; int result; if(eventNum) if(!scheventNum(eventNum,&prev)) result=0; else result=eventNum; else{ new=(myevent_t *)kmalloc(sizeof(myevent_t),GFP_KERNEL); init_waitqueue_head(&new->p); new->next=NULL; new->p.task_list.next=&new->p.task_list; new->p.task_list.prev=&new->p.task_list; if(!lpmyevent_head){ new->eventNum=2; lpmyevent_head =lpmyevent_end=new; } else{ new->eventNum=lpmyevent_end->eventNum+2; lpmyevent_end->next=new; lpmyevent_end=new; } result=new->eventNum; new->count=count; } return result; //return 18; } asmlinkage long sys_myevent_wait(int eventNum){ printk("wait it\n"); myevent_t *tmp; myevent_t *prev=NULL; if((tmp=scheventNum(eventNum,&prev))!=NULL){ spin_lock(&tmp->p.lock); tmp->count--; spin_unlock(&tmp->p.lock); if(tmp->count<0){ DEFINE_WAIT(wait); prepare_to_wait_exclusive(&tmp->p,&wait,TASK_INTERRUPTIBLE); schedule(); finish_wait(&tmp->p,&wait); } return eventNum; } return 0; } asmlinkage long sys_myevent_signal(int eventNum){ printk("signal it\n"); myevent_t *tmp=NULL; myevent_t *prev=NULL; if((tmp=scheventNum(eventNum,&prev))!=NULL){ spin_lock(&tmp->p.lock); tmp->count++; spin_unlock(&tmp->p.lock); if(tmp->count<=0){ wake_up(&tmp->p); return eventNum; } } return 0; } asmlinkage long sys_myevent_close(int eventNum){ printk("close it\n"); myevent_t *prev=NULL; myevent_t *releaseItem; if((releaseItem=scheventNum(eventNum,&prev))!=NULL){ if(releaseItem==lpmyevent_end) lpmyevent_end=prev; else if(releaseItem==lpmyevent_head) lpmyevent_head=lpmyevent_head->next; else prev->next=releaseItem->next; sys_myevent_signal(eventNum); kfree(releaseItem); return eventNum; } return 0; } asmlinkage long sys_modifytimes(unsigned long times){ lightbluetimes=times; return 22; } step 5: /usr/src/linux../include/linux/ vim lightblue.h extern unsigned long lightbluetimes; vim lightbluesema.h add the below codes: #include <linux/wait.h> typedef struct __myevent{ int count; int eventNum; wait_queue_head_t p; struct __myevent *next; }myevent_t; myevent_t * lpmyevent_head =NULL; myevent_t * lpmyevent_end=NULL; step 6: /usr/src/linux../arch/x86/mm/ vim fault.c #include <linux/lightblue.h> before the function 'do_page_fault()' ,add unsigned long lightbluetimes=0; in the function add : lightbluetimes++; 测试程序: mysemaphore.h int lightblueopen(int num,int count); int lightblueup(int num); int lightbluedown(int num); int lightblueclose(int num); unsigned long lightbluereadtimes(); int lightbluewritetimes(int times); mysemaphore.c #include "mysemaphore.h" #include <stdlib.h> #include <stdio.h> #include <sys/time.h> #include <linux/unistd.h> #include <sys/syscall.h> int lightblueopen(int num,int count){ return syscall(350,num,count); } int lightblueup(int num){ return syscall(351,num); } int lightbluedown(int num){ return syscall(352,num); } int lightblueclose(int num){ return syscall(353,num); } unsigned long lightbluereadtimes(){ struct timespec *s_time=(struct timespec *)malloc(20); struct timeval *v_time=(struct timeval*)malloc(20); unsigned long times=0; syscall(349,v_time,s_time,×); free(s_time); free(v_time); return times; } int lightbluewritetimes(int times){ return syscall(354,times); } readandwrite.c #include "mysemaphore.h" #include <stdlib.h> #include <stdio.h> #include <unistd.h> int semanum=0; int main(){ semanum=lightblueopen(0,2); int pid; pid=fork(); if(pid==0){//father process write int pid2=fork(); if(pid2==0){//father while(1){ lightblueup(semanum); printf("father process write \n"); lightbluewritetimes(1); lightbluedown(semanum); } } else{//child 1 read while(1){ lightblueup(semanum); printf("child 1 read page fault times is:%lu\n",lightbluereadtimes()); lightbluedown(semanum); } } } else{//child 2 read while(1){ lightblueup(semanum); printf("child 2 read page fault times is:%lu\n",lightbluereadtimes()); lightbluedown(semanum); } } return 0; } myread.c #include <linux/unistd.h> #include <sys/syscall.h> #include <stdio.h> #include <stdlib.h> #include "mysemaphore.h" /* *read paga fault times */ int main(int argc,char *argv[]){ int num=0; //if(argc>1) // { // printf("create new semaphore\n"); // num=atoi(argv[1]); // printf("semaphore num is:%d\n",num); // } // lightblueopen(num,2);//open a new semaphore and its value is 2 int index=3; unsigned long times=0; for(index=0;index<4;index++ ){ // lightblueup(num); times=lightbluereadtimes(); printf("page fault times is:%d\n",times); } } mywrite.c #include <linux/unistd.h> #include <sys/syscall.h> #include <stdio.h> #include <stdlib.h> #include "mysemaphore.h" int main(int argc,char *argv[]){ if(argc==1){ printf("input init times\n"); return 1; } int times=atoi(argv[1]); int index=0; for(index=0;index<2;index++){ lightbluewritetimes(times); } }
相关文章推荐
- linux device drive 第六章代码示例-scullpipe的实验(poll和fasync方法的实现)之一
- [积累] 在Ubuntu16.04 64位系统上配置linux-0.11内核实验环境
- linux路由内核实现分析(三)---路由查找过程
- Linux 实现自动安装服务组件以及优化内核参数 (转)
- Linux内核调试技术——jprobe使用与实现
- Linux内核抢占实现机制分析(转)
- Linux内核基于端口限速的研究及实现
- TCP/IP 网络子系统 在Linux 内核中实现详解 (基于2.6.35版)
- 一步步理解Linux进程(3)--内核中进程的实现
- Linux0.11内核--系统中断处理程序int 0x80实现原理
- Linux内核调试技术——jprobe使用与实现
- linux内核进程调度以及定时器实现机制
- linux-2.6.26内核中ARM中断实现详解(3)
- Linux内核--网络栈实现分析(五)--传输层之UDP协议(上)
- Linux内核--网络栈实现分析(十一)--驱动程序层(下)
- Linux内核设计与实现----Linux内核简介
- 深入理解linux内核list_head的实现
- netfilter:Linux 防火墙在内核中的实现
- Linux内核--网络栈实现分析(十)--网络层之IP协议(下)
- Linux内核设计与实现第五周读书笔记