#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/wait.h>
#include <string.h>
#include <signal.h>
#include <fcntl.h>
#include <time.h>
#include "job.h"
void sig_handler(int sig, siginfo_t *info,void *notused);
void schedule();
int allocjid();
void do_enq(struct jobinfo *newjob,struct jobcmd enqcmd);
void do_deq(struct jobcmd deqcmd);
void do_stat(struct jobcmd statcmd);
void updateall();
struct waitqueue* jobselect();
void jobswitch();
int jobid=0;
int siginfo=1;
int fifo;
int globalfd;
struct waitqueue *head=NULL;
struct waitqueue *next=NULL,*current=NULL;
int main()
{
struct timeval interval;
struct itimerval new,old;
struct stat statbuf;//???
struct sigaction newact,oldact1,oldact2;
if(stat("/tmp/server",&statbuf) == 0) {//??????
if(remove("/tmp/server") < 0)
printf("remove failed");
}
if(mkfifo("/tmp/server",0666) < 0)
printf("mkfifo failed");
if((fifo=open("/tmp/server",O_RDONLY|O_NONBLOCK)) < 0)
printf("open fifo failed");
if((globalfd=open("/dev/null",O_WRONLY)) < 0)//?????
printf("open global file failed");
newact.sa_sigaction=sig_handler;
sigemptyset(&newact.sa_mask);
newact.sa_flags=SA_SIGINFO;
sigaction(SIGCHLD,&newact,&oldact1);
sigaction(SIGVTALRM,&newact,&oldact2);
interval.tv_sec=0;
interval.tv_usec=100;
new.it_interval=interval;
new.it_value=interval;
setitimer(ITIMER_VIRTUAL,&new,&old);
while(siginfo == 1)
;
close(fifo);
close(globalfd);
return 0;
}
void sig_handler(int sig, siginfo_t *info,void *notused)
{
int status;
int ret;
switch(sig){
case SIGVTALRM:
schedule();
return;
case SIGCHLD:
ret=waitpid(-1,&status,WNOHANG);
if(ret == 0)
return ;
if(WIFEXITED(status)){//????????????
current->job->state=DONE;
printf("normal termation,exit status=%d\n",WEXITSTATUS(status));
}else
if(WIFSIGNALED(status)){
printf("abnormal termation,signal number=%d\n",WEXITSTATUS(status));
}else
if(WIFSTOPPED(status)){
printf("child stopped,signal number=%d\n",WSTOPSIG(status));
}
return;
default:
return;
}
}
void schedule()
{
struct jobinfo *newjob=NULL;
struct jobcmd cmd;
int count=0;
bzero(&cmd,DATALEN);
if((count=read(fifo,&cmd,DATALEN)) < 0)
printf("read fifo failed");
#ifdef DEBUG//?????????/
if(count){
printf("cmd cmdtype\t%d\n"
"cmd defpri\t%d\n"
"cmd data\t%s\n",
cmd.type,cmd.defpri,cmd.data);
}else
printf("no data read\n");
#endif
switch(cmd.type){
case ENQ:
do_enq(newjob,cmd);
break;
case DEQ:
do_deq(cmd);
break;
case STAT:
do_stat(cmd);
break;
default:
break;
}
updateall();
next=jobselect();
jobswitch();
}
void do_enq(struct jobinfo *newjob,struct jobcmd enqcmd)
{
struct waitqueue *newnode,*p;
int i=0,pid;
char *offset,*argvec,*q;
char **arglist;
sigset_t zeromask;
sigemptyset(&zeromask);
newjob=(struct jobinfo*)malloc(sizeof(struct jobinfo));
newjob->jid=allocjid();
newjob->defpri=enqcmd.defpri;
newjob->curpri=enqcmd.defpri;
newjob->ownerid=enqcmd.owner;
newjob->state=READY;
newjob->create_time=time(NULL);//????
newjob->wait_time=0;
newjob->run_time=0;
arglist=(char**)malloc(sizeof(char*)*(enqcmd.argnum+1));
newjob->cmdarg=arglist;
offset=enqcmd.data;
argvec=enqcmd.data;
while(i < enqcmd.argnum){
if(*offset == ':'){
*offset++='\0';
q=(char*)malloc(offset-argvec);
strcpy(q,argvec);
arglist[i++]=q;
argvec=offset;
}else
offset++;
}
arglist[i]=NULL;
#ifdef DEBUG
printf("enqcmd argnum %d\n",enqcmd.argnum);
for(i=0; i < enqcmd.argnum; i++)
printf("parse enqcmd:%s\n",arglist[i]);
#endif
newnode=(struct waitqueue*)malloc(sizeof(struct waitqueue));
newnode->next=NULL;
newnode->job=newjob;
if(head){
for(p=head;p->next != NULL; p=p->next) ;
p->next=newnode;
}else
head=newnode;
if((pid=fork()) < 0)
printf("enq fork failed");
if(pid == 0){
newjob->pid=getpid();
raise(SIGSTOP);
#ifdef DEBUG
printf("begin running\n");
for(i=0;arglist[i] != NULL; i++)
printf("arglist %s\n",arglist[i]);
#endif
dup2(globalfd,1);
if(execv(arglist[0],arglist) < 0)
printf("exec failed\n");
exit(1);
}else{
newjob->pid=pid;
}
}
int allocjid()
{
return ++jobid;
}
void do_deq(struct jobcmd deqcmd)
{
int deqid,i;
struct waitqueue *p,*prev,*select,*selectprev;
deqid=atoi(deqcmd.data);
#ifdef DEBUG
printf("deq jid %d\n",deqid);
#endif
if(current && current->job->jid == deqid){
printf("terminate current job\n");
kill(SIGKILL,current->job->pid);
for(i=0; (current->job->cmdarg)[i] != NULL; i++)
free((current->job->cmdarg)[i]);
free(current->job->cmdarg);
free(current->job);
free(current);
current=NULL;
}else{
select=NULL;
selectprev=NULL;
for(prev=NULL,p=head; p != NULL; prev=p,p=p->next)
if(p->job->jid == deqid)
break;
if(p != NULL){
if(prev == NULL)
head=NULL;
else
prev->next=p->next;
for(i=0; (p->job->cmdarg)[i] != NULL; i++)
free((p->job->cmdarg)[i]);
free(p->job->cmdarg);
free(p->job);
free(p);
p=NULL;
}
}
}
void do_stat(struct jobcmd statcmd)
{
struct waitqueue *p;
char timebuf[BUFLEN];
printf("JOBID\tPID\tOWNER\tRUNTIME\tWAITTIME\tCREATTIME\tSTATE\n");
if(current){
strcpy(timebuf,ctime(&(current->job->create_time)));
timebuf[strlen(timebuf) - 1]='\0';
printf("%d\t%d\t%d\t%d\t%d\t%s\t%s\n",
current->job->jid,
current->job->pid,
current->job->ownerid,
current->job->run_time,
current->job->wait_time,
timebuf,
"RUNNING");
}
for(p=head; p != NULL; p=p->next){
strcpy(timebuf,ctime(&(p->job->create_time)));
timebuf[strlen(timebuf) - 1]='\0';
printf("%d\t%d\t%d\t%d\t%d\t%s\t%s\n",
current->job->jid,
current->job->pid,
current->job->ownerid,
current->job->run_time,
current->job->wait_time,
timebuf,
"READY");
}
}
void updateall()
{
struct waitqueue *p;
if(current)
current->job->run_time += 1;
for(p=head; p != NULL; p=p->next){
p->job->wait_time += 100;
if(p->job->wait_time >= 1000 && p->job->curpri < 3)
p->job->curpri++;
}
}
struct waitqueue* jobselect()
{
struct waitqueue *p,*prev,*select,*selectprev;
int highest=-1;
select=NULL;
selectprev=NULL;
for(prev=NULL,p=head; p != NULL; prev=p,p=p->next)
if(p->job->curpri > highest){
select=p;
selectprev=prev;
highest=p->job->curpri;
}
if(select != NULL){
if(selectprev != NULL)
selectprev->next=select->next;
else
head=NULL;
}
return select;
}
void jobswitch()
{
struct waitqueue *p;
int i;
if(current != NULL && current->job->state == DONE){
for(i=0; (current->job->cmdarg)[i] != NULL; i++)
free((current->job->cmdarg)[i]);
free(current->job->cmdarg);
free(current->job);
free(current);
current=NULL;
}
if(next == NULL && current == NULL)
return ;
else
if(next != NULL && current == NULL){
printf("begin start new job\n");
current=next;
next=NULL;
current->job->state=RUNNING;
kill(current->job->pid,SIGCONT);
return ;
}else
if(next != NULL && current != NULL){
printf("begin switch\n");
kill(current->job->pid,SIGSTOP);
current->job->curpri=current->job->defpri;
current->job->wait_time=0;
current->job->state=READY;
if(head != NULL){
for(p=head; p->next != NULL; p=p->next)
;
p->next=current;
}else
head=current;
current=next;
next=NULL;
current->job->state=RUNNING;
kill(current->job->pid,SIGCONT);
return ;
}else
return;
}
没有合适的资源?快使用搜索试试~ 我知道了~
资源推荐
资源详情
资源评论
收起资源包目录
作业调度.rar (9个子文件)
源代码
enq.c 1KB
stat.c 529B
job.h 1KB
job.c 7KB
deq.c 629B
可执行文件
deq 5KB
stat 5KB
enq 6KB
job 11KB
共 9 条
- 1
资源评论
- tlzbg2013-06-17很全很方便
- adwdwefe2014-05-20基本用不到,大家要谨慎下载啊~~
Iamtheodore
- 粉丝: 5
- 资源: 95
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功