📄 sched.c
字号:
/*
miniTOS V0.1.3 1998-2004 (c) 林良水 (Lin LS)
miniTOS是一个开放源码的软件,授权LGPL,但开发人员不保证本软件的可靠性,
以及对您的损失负任何责任。
www.minitos.com
本文实现miniTOS进程调度及优先级管理。
create by Lin LS ,1998.10
*/
//#define VC
#include <stdio.h>
#include "minitosdef.h"
#include "extdefine.h"
#ifdef VC
#include "proctbl.h"
void lock_int(void){};
void unlock_int(void){};
void switch_task(void){};
void SendOneChar(int i,char a){i=i;a=a;};
#endif
struct ProcTbl * ptrTaskRdy[N_TASK_PRIO]; //0--highest,N_TASK_PRIO-1 is lowest for task
// 0..7
struct ProcTbl * ptrServerRdy; //[N_SERVER_PRIO];//server priority is lower than task
//Server priority is from N_TASK_PRIO to ...
// now only one is 8
struct ProcTbl * ptrProcRdy; //[N_PROC_PRIO]; //user process priority is lower than server
// 9
// idle process priority is 10
struct ProcTbl * ptrIdle;
unsigned char TaskPrioCnt=0; //task priority count use.
// bit.0 =1 mean ptrTaskRdy[0] have Task Rdy
// bit.7 =1 mean ptrTaskRdy[7] have Task Rdy
/****************************************************************
** function: count to get a highest priority task or server or proc,ortherwise
is idle.
**
*****************************************************************/
struct ProcTbl * SelectHightestPrioTask(void)
{
int i;
for(i=0;i<N_TASK_PRIO;i++)
{
if(ptrTaskRdy[i]!=NULL)
return ptrTaskRdy[i];
}
if(ptrServerRdy!=NULL)
return ptrServerRdy;
if(ptrProcRdy!=NULL)
return ptrProcRdy;
return ptrIdle;
}
/****************************************************************
**function:
**
*****************************************************************/
void SelectNewTask(void)
{
ptrCurrProc=SelectHightestPrioTask();
}
/*
why in this is error??
void InitTaskRdy(void)
{
ptrTaskRdy[0]=&Proc[0]; //idle1
//ptrServerRdy=&Proc[1]; //idle2
//ptrProcRdy= &Proc[2]; //idle3
//ptrCurrProc= &(Proc[1]);
}
*/
/*************************************************
**Function:开机启动把进程表初始化
**
*************************************************/
void InitTaskRdyPtrToNULL(void)
{
int i;
for(i=0;i<N_TASK_PRIO;i++)
{
ptrTaskRdy[i]=NULL;
}
ptrServerRdy=NULL;
ptrProcRdy=NULL;
}
//进程调度函数,调用本子程序实现进程调度。
void sched(void)
{
lock_int();
switch_task();
unlock_int();
}
/***************************************************************************
**Function: 把rp所指的进程加到就绪表中使进程可运行。
**input:
**output:
***************************************************************************/
void ready(PROC *rp)
{
/*
int prio;
prio=rp->priority;
if(prio<SERVER_PRIO)
{ //TASK
ptrTaskRdy[prio]=rp; //ptrTaskRdy[priority]指向rp
return;
}
if(prio==SERVER_PRIO)
{
ptrServerRdy=rp; //ptrServerRdy指向rp
return;
}
if(prio==PROC_PRIO)
{
ptrProcRdy=rp; //ptrProcRdy指向rp
return;
}
*/
int prio;
PROC *ptrTmpOld;
prio=rp->priority;
//SendOneChar(1,prio+'0');
if(prio<SERVER_PRIO)
{ //TASK,加到Ready链表的末尾
if( (ptrTmpOld=FindLastPos(ptrTaskRdy[prio]))==NULL)
{
ptrTaskRdy[prio]=rp;
}else
{
//现在ptrTmpOld指向链表最后一个位置
ptrTmpOld->ptrNextProc=rp;
}
rp->ptrNextProc=NULL;
//rp加入ptrTaskRdy[priority]链表的最后一个位置
return;
}
if(prio==SERVER_PRIO)
{
if( (ptrTmpOld=FindLastPos(ptrServerRdy))==NULL)
{
ptrServerRdy=rp;
}else
{
//现在ptrTmpOld指向链表最后一个位置
ptrTmpOld->ptrNextProc=rp;
}
rp->ptrNextProc=NULL;
//rp加入ptrServerRdy链表的最后一个位置
return;
}
if(prio==PROC_PRIO)
{
if( (ptrTmpOld=FindLastPos(ptrProcRdy))==NULL)
{
ptrProcRdy=rp;
}else
{
//现在ptrTmpOld指向链表最后一个位置
ptrTmpOld->ptrNextProc=rp;
}
rp->ptrNextProc=NULL;
//rp加入ptrProcRdy链表的最后一个位置
return;
}
}
/***************************************************************************
**Function:把rp所指的进程从就绪表中去掉,使不可运行。
**input:
**output:
***************************************************************************/
void unready(PROC *rp)
{
/*
int prio;
prio=rp->priority;
if(prio<SERVER_PRIO)
{
ptrTaskRdy[prio]=NULL;
return;
}
if(prio==SERVER_PRIO)
{
ptrServerRdy=NULL;
return;
}
if(prio==PROC_PRIO)
{
ptrProcRdy=NULL;
return;
}
*/
int prio,i;
PROC * ptrTmpOld;
prio=rp->priority;
if(prio<SERVER_PRIO)
{
//ptrTaskRdy[prio]=NULL;
ptrTmpOld=FindProcPos(ptrTaskRdy[prio],rp,&i);
if(i<0)return ;
if(i==0)
{ //删除第一个
ptrTaskRdy[prio]=rp->ptrNextProc;
}else
{ //删除rp所指向的项
ptrTmpOld->ptrNextProc=rp->ptrNextProc;
}
return;
}
if(prio==SERVER_PRIO)
{
//ptrServerRdy=NULL;
ptrTmpOld=FindProcPos(ptrServerRdy,rp,&i);
if(i<0)return ;
if(i==0)
{ //删除第一个
ptrServerRdy=rp->ptrNextProc;
}else
{ //删除rp所指向的项
ptrTmpOld->ptrNextProc=rp->ptrNextProc;
}
return;
}
if(prio==PROC_PRIO)
{
//ptrProcRdy=NULL;
ptrTmpOld=FindProcPos(ptrProcRdy,rp,&i);
// SendOneChar(1,i+'0');
if(i<0)return ;
if(i==0)
{ //删除第一个
ptrProcRdy=ptrProcRdy->ptrNextProc;
//SendOneChar(1,'f');
}else
{ //删除rp所指向的项
ptrTmpOld->ptrNextProc=rp->ptrNextProc;
//SendOneChar(1,'k');
}
return;
}
}
//调用本子程序时,是处于定时时间片,rp一定处于该优先级rdy表的第一个位置
void ChangeProcPos(PROC *rp)
{
int prio;
PROC *ptrTmpOld;
prio=rp->priority;
if(prio<SERVER_PRIO)
{
ptrTmpOld=FindLastPos(ptrTaskRdy[prio]);
if(ptrTmpOld==NULL)
{ //i==0空表
return ; //在SwitchTaskTimeOver调用不可能出现
}else
if(ptrTmpOld==ptrTaskRdy[prio])
{ //最后一项等于第一项,只有一项,就是自己,不用改变
return;
}else
{
ptrTaskRdy[prio]=rp->ptrNextProc; //删除处于开头的rp
//现在ptrTmpOld指向链表最后一个位置
ptrTmpOld->ptrNextProc=rp; //rp加入ptrTaskRdy[priority]链表的最后一个位置
rp->ptrNextProc=NULL;
}
return;
}
if(prio==SERVER_PRIO)
{
ptrTmpOld=FindLastPos(ptrServerRdy);
if(ptrTmpOld==NULL)
{ //i==0空表
return ; //在SwitchTaskTimeOver调用不可能为出现
}else
if(ptrTmpOld==ptrServerRdy)
{ //只有一项,就是自己,不用改变
return;
}else
{
ptrServerRdy=rp->ptrNextProc; //删除处于开头的rp
//现在ptrTmpOld指向链表最后一个位置
ptrTmpOld->ptrNextProc=rp; //rp加入ptrServerRdy链表的最后一个位置
rp->ptrNextProc=NULL;
}
return;
}
if(prio==PROC_PRIO)
{
ptrTmpOld=FindLastPos(ptrProcRdy);
if(ptrTmpOld==NULL)
{ //i==0空表
return ; //在SwitchTaskTimeOver调用不可能为出现
}else
if(ptrTmpOld==ptrProcRdy)
{ //只有一项,就是自己,不用改变
return;
}else
{
ptrProcRdy=rp->ptrNextProc; //删除处于开头的rp
//现在ptrTmpOld指向链表最后一个位置
ptrTmpOld->ptrNextProc=rp; //rp加入ptrProcRdy链表的最后一个位置
rp->ptrNextProc=NULL;
}
return;
}
}
/*******************************************************************
**Function:if process priority is same,time slice down come,let other same priority
process run.
本子程序必须在time中断中调用。放在OnTime子程序之后,使从sleep进程ready后
先运行。
本子程序必须在定时中断中调用。如果在中断中加入,可实现同一优先级的时间轮询调度。
**
*********************************************************************/
void SwitchTaskTimeOver(void)
{
if(ptrCurrProc->RunTicksCount)
ptrCurrProc->RunTicksCount--;
if(ptrCurrProc->RunTicksCount==0)
{
ptrCurrProc->RunTicksCount=ptrCurrProc->RunTicksInit;
ChangeProcPos(ptrCurrProc);
}
}
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/*******************************************************************
**Function:
**Input: head--
**Output:ptrLastPos
**return: 链表中共有几项,0--空表,>0项数
********************************************************************/
PROC * FindLastPos(PROC *head)
{
PROC *ptrTmp,*ptrTmpOld;
if(head==NULL)
return NULL; //空表
ptrTmp=head;
ptrTmpOld=head;
while(ptrTmp!=NULL)
{
ptrTmpOld=ptrTmp;
ptrTmp=ptrTmp->ptrNextProc;
}
//现在ptrTmpOld指向链表最后一个位置
return ptrTmpOld;
}
/*******************************************************************
**Function:
**Input: head--
rp--要找的指针
**Output:ptrPos-指向rp的前一个项的指针
如图: ptrPos->A->B
rp->B
**return: 链表中第几项,-1--空表,0,第一项,1--第二项...
********************************************************************/
PROC * FindProcPos(PROC *head,PROC *rp,int *cnt)
{
PROC *ptrTmp,*ptrTmpOld;
*cnt=-1;
if(head==NULL)
return NULL; //空表,ERR
*cnt=0;
ptrTmp=head;
ptrTmpOld=head;
while(ptrTmp!=rp)
{
(*cnt)+=1;
ptrTmpOld=ptrTmp;
ptrTmp=ptrTmp->ptrNextProc;
}
return ptrTmpOld;
}
/*******************************************************************
**Function:
**Input: head--
pProc--要加的进程指针
**Output:
none
**return:
********************************************************************/
PROC * AddLinkToProcLastPos(PROC *head,PROC *pProc)
{
PROC *ptrTmp;
ptrTmp=FindLastPos(head);
if(ptrTmp==NULL)
return NULL;
//加入到尾部
ptrTmp->ptrNextProc=pProc;
pProc->ptrNextProc=NULL;
return pProc;
}
/*******************************************************************
**Function:
**Input: head--
pProc--要删的进程指针
**Output:
none
**return: <0 空表
=0 在第一项
>0 成功
********************************************************************/
int RemoveProcFromProcLink(PROC *head,PROC *pProc)
{
int i;
PROC * ptrTmpProc;
ptrTmpProc=FindProcPos(head,pProc,&i);
if(i<0) return i; //空表
if(i==0)
{ //删除第一个
head=pProc->ptrNextProc;
}else
{ //删除rp所指向的项
ptrTmpProc->ptrNextProc=pProc->ptrNextProc;
}
return i;
}
#ifdef VC
void InitTaskRdy(void)
{
PROC *ptrTmpOld;
int i;
InitTaskRdyPtrToNULL();
// ptrTaskRdy[0]=&Proc[0]; //idle1
// ptrServerRdy=&Proc[0]; //idle2
Proc[0].priority=PROC_PRIO;//SERVER_PRIO;
// ptrProcRdy= &Proc[1]; //idle3
Proc[1].priority=PROC_PRIO;
ready(&Proc[0]);
ready(&Proc[1]);
// ptrIdle= &Proc[2]; //Idle3 will run forever
Proc[2].priority=PROC_PRIO;
ready(&Proc[2]);
unready(&Proc[0]);
ready(&Proc[0]);
unready(&Proc[0]);
ready(&Proc[0]);
unready(&Proc[0]);
ptrTmpOld=FindLastPos(ptrProcRdy);
SendOneChar(1,'0');
for(;;);
}
void main(void)
{
InitTaskRdy();
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -