哈哈,最后一个做得比较的水啊,不过还是在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 ;
}
ok,操作系统实验全部做完了,安心准备考试了