哈哈,最后一个做得比较的水啊,不过还是在0.11 下能跑了。
其他的做得还行吧,反正自己测试都没有问题,。。。,老师都还没有评分的。
写的比较好的有sem.c,不仅经受了实验4的考验,还完美过了实验5~~,哈哈
在此粘贴出来留做纪念:
#include <errno.h> #include <linux/sched.h> #include <linux/tty.h> #include <linux/kernel.h> #include <asm/segment.h> #include <sys/times.h> #include <sys/utsname.h> #include <linux/sched.h> /* * sti() */ static __inline__ void sti(void) { __asm__ __volatile__ ("sti"); } static __inline__ void cli(void) { __asm__ __volatile__("cli") ; } struct Node { struct task_struct * process_ptr ; struct Node * next ; } ; typedef struct Node Node ; struct Sem { char name[20] ; int val ; int flag ; Node * head ; } ; typedef struct Sem Sem ; typedef int sem_t ; #define SEM_SIZE 5 Sem sems[SEM_SIZE] ; //sems struct sem_t * indexp ; int hasInit = 0 ; //the flag to recongnize the init of the sems struct //print debug info void my_debug(const char * str) { printk("[my_debug info]:%s\n",str) ; return ; } //sleep_on void my_sleep_on(int index) { //first ,add to the sem's task_struct queue Node * pos ; Node * tmp ; if(sems[index].head == NULL) { sems[index].head = malloc(sizeof(Node)) ; sems[index].head->process_ptr = current ; sems[index].head->next = NULL ; //my_debug("@sem_wait: head , sleep on") ; } else { pos = sems[index].head ; //find the rear while(pos->next != NULL) { pos = pos->next ; } //add this process tmp = malloc(sizeof(Node)) ; tmp->process_ptr = current ; tmp->next = NULL ; pos->next = tmp ; //my_debug("@sem_wait: a new process to sleep") ; } current->state = TASK_INTERRUPTIBLE ; //my_debug("@sem_wait:schedule") ; sti() ;//will it be ok? schedule() ; return ; } void my_wake_up(int index) { //wake up the head if(sems[index].head == NULL) //may occur return ; Node * pos =sems[index].head ; sems[index].head = sems[index].head->next ; pos->process_ptr->state = TASK_RUNNING ;//change state free(pos) ; return ; } sem_t * sys_sem_open(const char * name , unsigned int value) { //to init the sem struct int i ; if(!hasInit) { for(i = 0 ; i < SEM_SIZE ; i++) { memset(&sems[i],0,sizeof(Sem)) ; } hasInit = 1 ; } //printk("sem_open ok\n") ; //printk("%s\n",sems[0].name) ; char kernelName[20] = "" ; char x ; i = 0 ; while((x = get_fs_byte(name+i)) != '\0') { kernelName[i] = x ; i++ ; } kernelName[i] = '\0' ; //printk("%s,%d\n",kernelName,value) ; indexp = malloc(sizeof(int)) ; //1. has existed ,return &index //2. not existed , but can be creat ,to create ,and return the &index //3. not existed and can't be creat( full ),return NULL //int isFull = 0 ;// is full,0 stands for full, 1 stands not full cli() ;//it seems that it doesn't need do this ,but it may be more ok for(i = 0 ; i < SEM_SIZE ; i++) { if(strcmp(sems[i].name,kernelName) == 0 && sems[i].flag == 1) { //find //my_debug("@sem_open : find sem") ; *indexp = i ; sti() ; return indexp ; } } //not found,to add for(i = 0 ; i < SEM_SIZE ; i++) { if(sems[i].flag == 0) { //my_debug("@sem_open : create new sem") ; strcpy(sems[i].name,kernelName) ; sems[i].val = value ; sems[i].flag = 1 ; *indexp = i ; sti() ; return indexp ; } } //full //my_debug("@sem_open : full") ; free(indexp) ; sti() ; return NULL ; } int sys_sem_wait(sem_t * sem) { //printk("sem_wait ok\n") ; if(sem == NULL) return -1 ; //ok //my_debug("@sem_wait: this sem val now is ") ; //printk("%d\n",sems[(*sem)].val) ; int index = (*sem) ; //cli cli() ; sems[index].val -- ; //sti //sti() ; if(sems[index].val < 0) { //my_debug("@sem_wait: the process has to sleep") ; //sleep my_sleep_on(index) ; //my_debug("@sem_wait:process wake up") ; } sti() ; return 0 ; } int sys_sem_post(sem_t * sem) { //printk("sem_post ok\n") ; if(sem == NULL) return -1 ; //my_debug("@sem_post:this sem now is ") ; //printk("%d\n",sems[(*sem)].val) ; int index = (*sem) ; cli() ; sems[index].val++ ; //sti() ; if(sems[index].val <= 0)//!! <= 0 that seems there has the the sleep process!!!! { my_wake_up(index) ; //my_debug("@sem_post:wake up a process") ; } sti() ; return 0 ; } int sys_sem_unlink(const char * name) { //printk("sem_unlink ok\n") ; char kernelName[20] = "" ; char x ; int i = 0 ; while((x = get_fs_byte(name+i)) != '\0') { kernelName[i] = x ; i++ ; } kernelName[i] = '\0' ; cli() ; for(i = 0 ; i < SEM_SIZE ; i++) { if(strcmp(kernelName,sems[i].name) == 0 && sems[i].flag == 1) { sems[i].flag = 0 ; strcpy(sems[i].name,"") ; sti() ; return 0 ; } } sti() ; return -1 ; }