?? shd.cpp
字號:
#include "stdafx.h"
#include "shd.h"
#include <cstdlib> //for srand() and rand()
#include <cassert>
#define DEFAULT_RUN_PROCESS 4
Crunqueue::Crunqueue():n_max_run(DEFAULT_RUN_PROCESS),n_process(0),sched_kind(0),usemm(false)
{
Cmm* mp=new Cmm;
mp->size=MM_TOTAL_SIZE;
mm.push_back(mp);
}
Cpcb* Crunqueue::randpcb()
{
++n_process;
srand(n_process);
Cpcb* p=new Cpcb;
p->pid=n_process;
p->priority=rand()%MAX_PRIO;
p->time_slice=(int)rand()%DEFAULT_TIME_SLICE+1;
p->memory=rand()%MM_MAX_SIZE+8;
return p;
}
void Crunqueue::deletepcb(Cpcb* p)
{
--n_process;
delete p;
}
void Crunqueue::add_to_reserve(Cpcb* p)
{
if( p->state!=TASK_OVER )
{
reserve.push_back(p);
p->state=TASK_RESERVE;
}
if( sched_kind==SCHED_PRIO )
{
reserve.sort();
}
}
void Crunqueue::add_to_reday(Cpcb* p)
{
if( active.count<n_max_run )
{
if( p->state!=TASK_READY )
p->state=TASK_READY;
active.push_back(p);
}
}
void Crunqueue::add_to_hang(Cpcb* p)
{
if( p->state==TASK_HANG || p->state==TASK_OVER )
return;
if( p )
{
active.pop(p);
hang.push_back(p);
p->state=TASK_HANG;
}
schedule();
}
void Crunqueue::active_hang(Cpcb* p)
{
if( p->state==TASK_HANG )
{
hang.pop(p);
active.push_back(p);
in_schedule();
}
}
void Crunqueue::add_to_over(Cpcb* p)
{
over.push_back(p);
p->state=TASK_OVER;
reclaim(p);
schedule();
}
void Crunqueue::in_schedule_prio()
{
active.sort();
current=active.head;
if( !current->run() )
{
Cpcb* p=active.pop_front();
add_to_over(p);
schedule();
}
}
void Crunqueue::in_schedule_rr()
{
current=active.head;
if( !current->run() )
{
Cpcb* p=active.pop_front();
add_to_over(p);
schedule();
}
//while( active.head->run() ); //一直運行,直到該進程結束
//Cpcb* p=active.pop_front();
//add_to_over(p);
//if( !active.count && !hang.count ) return;
//schedule(); //重新載入進程
}
/*內調度(俗語低級調度或進程調度):負責就緒隊列中進程切換*/
void Crunqueue::in_schedule()
{
if( active.count==0 ) return;
if( SCHED_PRIO==sched_kind )
in_schedule_prio();
else if( SCHED_RR==sched_kind )
in_schedule_rr();
}
/*外調度(俗語高級調度或作業調度):負責就緒隊列線程的供給*/
void Crunqueue::schedule()
{
if( reserve.count>0 )
{
int canrun=0;
//判斷后備隊列是否超出規定運行線程數,是則按規定道數慢慢來,否則全部上
if( reserve.count>n_max_run-active.count) canrun=n_max_run;
else canrun=reserve.count+active.count;
for(int i=active.count;i<canrun;i++)
{
if( usemm && !alloc(reserve.head) ) break;
add_to_reday(reserve.pop_front());
}
}
/*外調度是為內調度作準備,循環機制*/
//if( active.count || hang.count )
// in_schedule();
/*當就緒隊列和掛起隊列中都沒有進程時說明調度完成*/
}
bool Crunqueue::alloc(Cpcb* p)
{
Cmm* mp=mm.head;
while(mp->size<p->memory)
{
mp=mp->nextp;
if( mp==mm.end ) //無足夠多的內存
return false;
}
//分配到內存
p->mm_begin=mp->begin;
mp->div(p->memory);
if( mp->size==0 && mp->begin!=MM_TOTAL_SIZE)
mm.remove(mp);
return true;
}
void Crunqueue::reclaim(Cpcb* p)
{
Cmm* mp=mm.head;
while( mp!=mm.end && p->mm_begin>mp->begin)
{
mp=mp->nextp;
}
Cmm* tp=new Cmm;
tp->size=p->memory;
tp->begin=p->mm_begin;
if( mp->begin==tp->begin+tp->size )
{
if( mp!=mm.head && tp->begin==mp->prep->begin+mp->prep->size )
{
mp->extent_front(tp);
mp->prep->extent_back(mp);
mm.remove(mp);
}
else
mp->extent_front(tp);
}
else if( mp!=mm.head && tp->begin==mp->prep->begin+mp->prep->size )
mp->prep->extent_back(tp);
else
mm.insert_before(tp,mp);
p->mm_begin=0;
}
void Crunqueue::clear()
{
if( n_process )
{
reserve.clear(); //清空后備隊列
active.clear(); //清空就緒隊列
hang.clear(); //清空掛起隊列
over.clear(); //清空完成隊列
n_max_run=0;
n_process=0;
sched_kind=0;
}
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -