k++){
tmp=tmp*x。
}
returntmp。
}
introot(intx,inty){//计算y的开x次方
intresult=y,count=0。
while(result!
=1){
result=result/x。
count++。
}
returncount。
}
//对内存块进行拆分
intsplit(inttempId){
block*pend=(structblock*)malloc(sizeof(structblock))。
//被拆分结点
block*cend=(structblock*)malloc(sizeof(structblock))。
//挂载点
block*newf=(structblock*)malloc(sizeof(structblock))。
//拆分后的第二个结点
block*newu=(structblock*)malloc(sizeof(structblock))。
//拆分后的第一个结点
pend=id[tempId]->next。
intflag=0,isFirst=0。
while(pend!
=NULL){
if(pend->loc==0){//可拆分
//卸载被拆分结点
if(isFirst==0){
id[tempId]->next=pend->next。
}else{
pend->prior->next=pend->next。
}
//拆分后的结点初始化
intsize=(pend->size)/2。
intstart=pend->start。
newu->size=size。
newu->start=start。
newf->start=start+size。
newu->loc=0。
newf->size=size。
newf->loc=0。
newf->prior=newu。
newu->next=newf。
newf->next=NULL。
tempId--。
cend=id[tempId]。
while(cend->next!
=NULL){
cend=cend->next。
}
cend->next=newu。
//将拆分后的结点进行挂载
newu->prior=cend。
flag=1。
return1。
}else{
pend=pend->next。
isFirst++。
}
}
if(flag==0){
tempId=tempId+1。
if(tempId<=9){
free(pend)。
free(cend)。
free(newu)。
free(newf)。
split(tempId)。
}else{
return-1。
}
}
}
//归并
intmerge(inttempId,block*first){
block*merger=(structblock*)malloc(sizeof(structblock))。
//合并后的结点
block*second=NULL。
//查找可合并的结点
second=id[tempId]->next。
intnextStart=first->start+first->size。
intpreStart=first->start-first->size。
intflag=0,isFirst=0。
while(second!
=NULL){
if((second->start==nextStart||second->start==preStart)&&second->loc==0){
//初始化合并后的结点
merger->size=(first->size)+(second->size)。
merger->loc=0。
merger->start=(first->start)<(second->start)?
(first->start):
(second->start)。
//卸载可合并的结点
if(first->next!
=NULL){
first->next->prior=first->prior。
}
if((first->prior->prior)==first->prior){
id[tempId]->next=first->next。
}else{
first->prior->next=first->next。
}
if(second->next!
=NULL){
second->next->prior=second->prior。
}
if(isFirst==0){
id[tempId]->next=second->next。
}else{
second->prior->next=second->next。
}
//挂载合并后的结点
tempId++。
merger->next=id[tempId]->next。
merger->prior=id[tempId]。
if(id[tempId]->next!
=NULL)id[tempId]->next->prior=merger。
id[tempId]->next=merger。
if(tempId<9){
merge(tempId,merger)。
}else{
return0。
}
return1。
}else{
second=second->next。
isFirst++。
}
}
return1。
}
//内存释放
intfreeb(intsize){
block*first=(structblock*)malloc(sizeof(structblock))。
inttempId=root(2,size)。
first=id[tempId]->next。
intflag=0。
while(first!
=NULL){
if(first->loc==1){
first->loc=0。
flag=1。
break。
}else{
first=first->next。
}
}
if(flag==1){
merge(tempId,first)。
//归并
printmem()。
}else{
printf("需要释放的内存块不存在!
\n")。
}
return1。
}
intrequestb(intsize){//申请size个页面
block*temp=(structblock*)malloc(sizeof(structblock))。
inttempId=root(2,size)。
intflag=0。
temp=id[tempId]->next。
while(temp!
=NULL){
if(temp->loc==0&&temp->size==size){//分配
temp->loc=1。
flag=1。
printf("分配成功!
\n")。
printmem()。
return1。
}else{
temp=temp->next。
}
}
if(flag==0){
tempId++。
if(tempId<=9){
intrs=split(tempId)。
if(rs==-1){
printf("没有合适的空间可分配!
\n")。
return-1。
}else{
requestb(size)。
}
}else{
printf("没有合适的空间可分配!
\n")。
return-1。
}
}
free(temp)。
}
intmain(){
init()。
intflag=1。
//是否继续
intsize。
//申请/释放内存大小(2的次幂)
charorder。
//操作命令,r申请,f释放
do{
printf("请输入命令:
(以空格相隔,示例:
r8)\n")。
scanf("%c%d",&order,&size)。
if(order=='r'){//申请内存
requestb(size)。
}elseif(order=='f'){//释放内存
freeb(size)。
}else{
printf("error!
")。
}
printf("是否继续?
(1继续,0退出):
")。
scanf("%d",&flag)。
getchar()。
}while(flag==1)。
}
结果图:
2.页故障率反馈模型
源程序。
#include
#include
#include
#defineMAX_WORKSET10
#defineWINDOW_SIZE20
intmempage=10。
//内存页面总数(进程要访问的页面从0到该范围内随机生成)
intprocArray[WINDOW_SIZE]。
//进程访问页面序列
intwin[MAX_WORKSET][2]。
//工作集
doublemaxRate=0.8,minRate=0.2。
//故障率上下限
doublecurRate。
intcur_workset=3。
intconflictCount=0。
//故障次数
voidprint(){//程序输出函数
curRate=(double)conflictCount/(double)WINDOW_SIZE。
printf("缺页故障率:
%g,故障率上限/下限:
%g/%g\n",curRate,maxRate,minRate)。
}
voidchangeArray(){//动态改变访问页面序列
inti。
for(i=0。
ii++){
procArray[i]=rand()%mempage。
}
printf("进程调用页面序列:
")。
for(i=0。
ii++){
printf("%d|",procArray[i])。
}
printf("\n")。
}
voidinit(){//初始化工作集和页面序列
inti,j。
//changeArray()。
for(i=0。
ii++){
win[i][0]=-1。
win[i][1]=cur_workset。
}
}
voidchangePage(intnumber){//换页
inti,flag=0。
for(i=1。
ii++){
if(win[flag][1]<=win[i][1]){//寻找最先进入的
flag=i。
}
}
win[flag][0]=procArray[number]。
//换页
win[flag][1]=1。
conflictCount++。
//冲突次数加1
for(i=0。
ii++){
if(i!
=flag&&win[i][1]!
=-1){//工作集进入顺序处理
win[i][1]++。
}
}
}
voidstep(intnumber){//调用一次内存页面
inti,hit=0。
for(i=0。
ii++){
if(procArray[number]==win[i][0]){//命中
//number++。
hit=1。
break。
}
}
if(hit==0){//尚未命中
changePage(number)。
//换页
//number++。
}
//returnnumber。
}
voidrun(){//程序运行
inti。
conflictCount=0。
changeArray()。
for(i=0。
ii++){
step(i)。
}
printf("冲突次数:
%d,",conflictCount)。
}
voidfeedback(){
curRate=(double)conflictCount/(double)WINDOW_SIZE。
if(curRate>maxRate){
cur_workset++。
}elseif(curRatecur_workset--。
}
}
intmain(){
init()。
//初始化
charquit。
do{
run()。
print()。
feedback()。
printf("输入任意字符继续,q退出\n")。
scanf("%c",&quit)。
getchar()。
}while(quit!
='q')。
}
结果图:
4、结果分析与实验体会