[模拟] 简单的进程调度模拟

原创 2007年09月12日 17:35:00
简单的进程调度模拟
roadtang 2007/09/12

在论坛上见到的这个,正好有兴趣,也有时间,就写了下, 分别有抢占和非抢占的proc_schedule ,代码里加了注释.
仅仅是为了示例用,调度规则就是  优先级大的先执行.


原问题链接
http://community.csdn.net/Expert/TopicView3.asp?id=5752551

注意: 这个垃圾程序 没有执行出口, 呵呵.

============  Code start ==================

/*
Simple Operating System Process Schedule Simulation


http://community.csdn.net/Expert/TopicView3.asp?id=5752551

roadtang 2007/09/12
*/


#include <stdlib.h>
#include <stdio.h>
#include <string.h>


/* ------- VM (cpu , interrupt)  ----------*/

#define REG_NUM 20
#define CPU_HZ 1000000

typedef struct vcpu_s {
  int reg[20];
  int flag;
  long long tick;
  double time;
  void *eip;    // pointer to execution process.
} vcpu_t;



#define INT_SIZE  1024
#define INT_TIME  5
#define INT_IDLE  6
typedef void (*func)(void);
typedef struct vm_s {
  vcpu_t  cpu;
  func    int_tab[INT_SIZE];  // virtual machine interrupt table
#define tick cpu.tick
#define eip  cpu.eip
} vm_t;

vm_t  vm;

void cpu_frame();

void vm_init();
void vm_start();
void vm_stop();


/* ------- OS simulation (process schedule) -----------*/

/*
  OS timer mechanism
*/
#define STIME_FREE 0
#define STIME_ACTIVE 1

#define STIME_SIZE  1024
typedef struct tm_ent_s{
  int flag;
  int time;
  func fn;
} tm_ent_t;

tm_ent_t  timers[STIME_SIZE];  // operating system tiemrs hooks

void timeridle_init();
int register_timer(int time, func f);  //success return id, failure return -1
int unregister_timer(int id);
void os_timer_vmhandle();

/*
idle mechanism
*/
void os_idle_vmhandle(void);

/*
  OS process schedule
*/
#define PF_FREE     0
#define PF_READY    1
#define PF_RUNNING  2
#define PF_DONE     3
typedef struct proc_s {
  int flag;  /* PF_ */
  char name;
  int prio;
  int exet;
  int exed;
  int freq;  /* if freq > 0, it's cycle task */
  func fn;
  /*
  struct proc_s *prev;
  struct proc_s *next;
  */
} proc_t;
/*
#define PROCHEAD_INIT(p) do {  p->prev = p; p->next = p; } while(0)

struct proc_s ready;   
struct proc_s running;
struct proc_s done;
*/

#define PROCESS_SIZE   64
#define SCHED_INTERVAL 1
proc_t procs[PROCESS_SIZE];

int create_proc(char name, int prio, int exet, int freq, func f);
void release_proc(int id);
void proc_schedule_handle_preempt(void);
void proc_schedule_handle_nonpreempt(void);

/*
single user operation  and misc &
*/

void user_init();

void print(char c);









/*=========================================================================================================

   The Implementation is following

=========================================================================================================*/


/*
simulate cpu one exection
*/
void cpu_frame(vcpu_t *cpu)
{
  func ifp, idp;

  ++ vm.tick;

 
  /* in our vm, the hardware timer interrupt is triggered every cpu pulse, (i.e.veryfast) */
  ifp = vm.int_tab[INT_TIME];
  if (ifp)
    ifp();

  if (vm.eip)
    ((func)(vm.eip))();
  else /* idle */
    if (idp = vm.int_tab[INT_IDLE])
      idp();
}


/*
VM initialization
including:
  OS initialize.,
  user initialize operation.
*/
void vm_init()
{
  /* clear every thing */
  memset (&vm, 0, sizeof(vm));
  memset (timers, 0, sizeof(timers));
  memset (procs, 0 , sizeof(procs));

  /* os init
     init os timers modules
     init task schedule modeuls
  */

  timeridle_init();
  register_timer(SCHED_INTERVAL,  proc_schedule_handle_nonpreempt);

  /*
    user init,  push root thread ,or something etc.
  */
  user_init();

}

void vm_start()
{
  while(1)
    cpu_frame(0);
}

void vm_stop()
{
}


/*
  OS timer & idle
*/

void timeridle_init()
{
  vm.int_tab[INT_TIME] = &os_timer_vmhandle;
  vm.int_tab[INT_IDLE] = &os_idle_vmhandle;
}
 
int register_timer(int time, func f)  //success return id, failure return -1
{
  int i;
  for (i = 0; i < STIME_SIZE; ++i)
    if (timers[i].flag==STIME_FREE){
      timers[i].flag = STIME_ACTIVE;
      timers[i].time = time;
      timers[i].fn = f;
      return i;
    }
  return -1;
}

int unregister_timer(int id){
  memset(&timers[id], 0 , sizeof(timers[0]));
}

/**
  
 */
void os_timer_vmhandle()
{
  int i;

  for (i=0; i<STIME_SIZE; ++i)
    if (timers[i].flag == STIME_ACTIVE
    && vm.tick % timers[i].time ==0)
    timers[i].fn();
}

void os_idle_vmhandle()
{


}



/*
 
  OS  process schedule simulation

 */


int create_proc(char name, int prio, int exet, int freq, func f)
{
  int i;
  for (i = 0; i < PROCESS_SIZE; ++i)
    if (procs[i].flag == PF_FREE)
      {
    proc_t *p = &procs[i];
    p->flag = PF_READY;
    p->name = name;
    p->prio = prio;
    p->exet = exet;
    p->freq = freq;
    p->fn    = f;
    return i;
      }
  return -1;
}

void release_proc(int id)
{
  memset(&procs[id], 0, sizeof(proc_t));
}

/*
The primary method for process schedule
*/
void proc_schedule_handle_preempt(void)
{
  /* does:
     1. calculate the exetime of the running procs
     2.(preempt) schedule a new procs to execution
     3. terminate the non-cycle finished proc, mark dead. and purge them.
     4. reset the cycle proc to ready status for next
   */
  int i;
  proc_t *p;
  proc_t *sch = 0; int prio = 0;

  static long long base_tck;
  if (!base_tck)
    base_tck = vm.tick;

  /* cal tick */
  for (i = 0; i < PROCESS_SIZE; ++i)
    {
      p = &procs[i];

      switch(p->flag)
    {
    case PF_FREE:  /* skip for empty node */
      continue;

    case PF_RUNNING: 
      p->exed += (vm.tick - base_tck);
      base_tck = vm.tick;
      if (p->exed >= p->exet)
        p->flag = PF_DONE;
      else
        p->flag = PF_READY;  /* take part in next schedule */
      break;

    case PF_DONE:
      if (p->freq <= 0)
        release_proc(i);
      else if (vm.tick% p->freq == 0)
        {   /* cycle task, reset  */
          p->flag = PF_READY;
          p->exed = 0;
        }
      break;

    case PF_READY:/* get max priority proc , store it in  (proc_t*)sch */
      if (p->prio > prio)
        {
          sch = p;
          prio = p->prio;
        }
      break;
    }
    }

  /* schedule */
  if (sch)
    {
      vm.eip = sch->fn;
      sch->flag = PF_RUNNING;
      print(sch->name);
    }
  else
    print('/');
}



void proc_schedule_handle_nonpreempt(void)
{
  /* does:
     1. calculate the exetime of the running procs
     2.(nonpreempt) remain the running proc execute if it doesn't finish. otherwise schedule a new proc
     3. terminate the non-cycle finished proc, mark dead. and purge them.
     4. reset the cycle proc to ready status for next
   */
  int i;
  proc_t *p;
  proc_t *sch = 0; int prio = 0;
  static proc_t *running = 0;   /* store the running proc, if exist, */

  static long long base_tck;
  if (!base_tck)
    base_tck = vm.tick;

  /* cal tick */
  for (i = 0; i < PROCESS_SIZE; ++i)
    {
      p = &procs[i];

      switch(p->flag)
    {
    case PF_FREE:  /* skip for empty node */
      continue;

    case PF_RUNNING: 
      running = p;
      p->exed += (vm.tick - base_tck);
      base_tck = vm.tick;
      if (p->exed >= p->exet)
        {
          p->flag = PF_DONE;
          running = 0;
        }
      break;

    case PF_DONE:
      if (p->freq <= 0)
        release_proc(i);
      else if (vm.tick% p->freq == 0)
        {   /* cycle task, reset  */
          p->flag = PF_READY;
          p->exed = 0;
        }
      break;

    case PF_READY:/* get max priority proc , store it in  (proc_t*)sch */
      if (p->prio > prio)
        {
          sch = p;
          prio = p->prio;
        }
      break;
    }
    }

  /* schedule */
  if (running)
    sch = running;

  if (sch)
    {
      vm.eip = sch->fn;
      sch->flag = PF_RUNNING;
      print(sch->name);
    }
  else
    print('/');
}

/*
single user operation
*/
void dummy()
{
}
void user_init()
{
  create_proc('A', 3, 1, 0, dummy);
  create_proc('B', 5, 1, 100, dummy);
  create_proc('C', 4, 2, 200, dummy);
  create_proc('D', 2, 1, 100, dummy);
  create_proc('E', 1, 1, 100, dummy);

}

void print(char ch)
{
  static char c = 0;

  if (c != '/'){
    putchar (ch);
    putchar ('|');
  }
  c = ch;

}

/*
 */
main()
{
  vm_init();
  vm_start();
}



=======  Code end  ====================================


输出结果:
B|C|C|A|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|
E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|
E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|
E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|
E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|
E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|
E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|
E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D|E|/|C|C|D|E|/|D

用C++模拟操作系统进程调度的几种算法

***************************************     *****1.******* 先来先服务算法 ***********     *****2.********  ...
  • kai8wei
  • kai8wei
  • 2015年11月30日 23:52
  • 1945

【进程调度】模拟进程调度的过程

1.目的和要求 通过这次实验,理解进程调度的过程,进一步掌握进程状态的转变、进程调度的策略,进一步体会多道程序并发执行的特点,并分析具体的调度算法的特点,掌握对系统性能的评价方法。 2.实验内容 ...
  • cutter_point
  • cutter_point
  • 2014年05月06日 16:34
  • 2595

使用java实现模拟进程调度

这本来是我的操作系统作业,斑竹本来想偷懒在网上找一篇交上去,但无奈没有找到符合的,只好自己写了。言归正传,在这个例子中,我实现了进程调度的三种算法,分别是优先级算法,时间片算法,和段作业优先算法(fc...
  • xiaowei1118
  • xiaowei1118
  • 2014年12月15日 14:23
  • 2085

进程调度模拟程序设计-----FCFS算法简单实现

题目描述: 一.实验目的和要求 加深对进程概念和进程调度过程/算法的理解。本实验要求用高级语言编写和调试一个模拟动态优先权的进程调度算法程序。 二、实验内容 1.给出进程调度的算法描述(如基于...
  • chenqiai0
  • chenqiai0
  • 2012年11月27日 12:47
  • 11798

进程调度模拟(C语言)

在CSDN里的第一篇,从之前UNIX程序设计课的学期作业里找了个当时的模拟进程调度的代码贴上。不足之处,请见谅。   #include #include using namespace std...
  • pangshensen
  • pangshensen
  • 2014年02月27日 12:35
  • 3003

操作系统实验一——模拟进程调度时间片轮转算法

本程序用于模拟进程。总体思路为:用一个调度线程来模拟操作系统的调度进程,用一个线程来模拟一个进程。于是,对应于每一个被模拟的进程,都有相应的线程来模拟,并在调度线程的调度下,实现时间片轮转的调度算法。...
  • ffee
  • ffee
  • 2006年05月21日 13:50
  • 13031

进程调度模拟算法

进程调度模拟算法1.先进先出调度。进程按申请进入内存的时间执行。2.优先级调度。进程按操作系统分配的优先级,执行。3.时间轮转调度。进程按申请进入内存的时间依次执行一个时间片。4.分级调度。时间轮转调...
  • Ivan4412
  • Ivan4412
  • 2010年04月22日 18:18
  • 1285

Linux编程:模拟进程调度算法

稍稍有点操作系统基础的朋友应该知道进程的调度算法,在这里Koala还是给大家略微介绍一下接下来将要用到的几种算法: 先来先服务(FCFS) 采用FCFS调度,先请求CPU的进程会先分配到CPU。 ...
  • KoalaZB
  • KoalaZB
  • 2016年12月10日 23:28
  • 2821

进程调度算法模拟程序设计C++

#include #include using namespace std; //#define N 3 typedef struct{ int ID; int PRIORITY; int...
  • myfather103
  • myfather103
  • 2015年07月09日 16:05
  • 1777

操作系统用C语言模拟基于时间片进程调度程序

操作系统用C语言模拟基于时间片进程调度程序
  • Yee_XU
  • Yee_XU
  • 2016年03月07日 00:19
  • 1571
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:[模拟] 简单的进程调度模拟
举报原因:
原因补充:

(最多只允许输入30个字)