⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cpu.c

📁 思科路由器仿真器,用来仿7200系列得,可以在电脑上模拟路由器
💻 C
字号:
/* * Cisco router simulation platform. * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr) * * Management of CPU groups (for MP systems). */#define _GNU_SOURCE#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <string.h>#include <stdarg.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/mman.h>#include <fcntl.h>#include <pthread.h>#include "cpu.h"#include "memory.h"#include "device.h"#include "mips64.h"#include "mips64_cp0.h"#include "mips64_exec.h"#include "mips64_jit.h"#include "ppc32.h"#include "ppc32_exec.h"#include "ppc32_jit.h"#include "dynamips.h"#include "vm.h"/* Find a CPU in a group given its ID */cpu_gen_t *cpu_group_find_id(cpu_group_t *group,u_int id){   cpu_gen_t *cpu;   if (!group)      return NULL;   for(cpu=group->cpu_list;cpu;cpu=cpu->next)      if (cpu->id == id)         return cpu;   return NULL;}/* Find the highest CPU ID in a CPU group */int cpu_group_find_highest_id(cpu_group_t *group,u_int *highest_id){   cpu_gen_t *cpu;   u_int max_id = 0;   if (!group || group->cpu_list)      return(-1);   for(cpu=group->cpu_list;cpu;cpu=cpu->next)      if (cpu->id >= max_id)         max_id = cpu->id;   *highest_id = max_id;   return(0);}/* Add a CPU in a CPU group */int cpu_group_add(cpu_group_t *group,cpu_gen_t *cpu){   if (!group)      return(-1);   /* check that we don't already have a CPU with this id */   if (cpu_group_find_id(group,cpu->id) != NULL) {      fprintf(stderr,"cpu_group_add: CPU%u already present in group.\n",              cpu->id);      return(-1);   }      cpu->next = group->cpu_list;   group->cpu_list = cpu;   return(0);}/* Create a new CPU group */cpu_group_t *cpu_group_create(char *name){   cpu_group_t *group;   if (!(group = malloc(sizeof(*group))))      return NULL;   group->name = name;   group->cpu_list = NULL;   return group;}/* Delete a CPU group */void cpu_group_delete(cpu_group_t *group){     cpu_gen_t *cpu,*next;   if (group != NULL) {      for(cpu=group->cpu_list;cpu;cpu=next) {         next = cpu->next;         cpu_delete(cpu);      }      free(group);   }}/* Rebuild the MTS subsystem for a CPU group */int cpu_group_rebuild_mts(cpu_group_t *group){   cpu_gen_t *cpu;   for(cpu=group->cpu_list;cpu;cpu=cpu->next)      cpu->mts_rebuild(cpu);   return(0);}/* Log a message for a CPU */void cpu_log(cpu_gen_t *cpu,char *module,char *format,...){   char buffer[256];   va_list ap;   va_start(ap,format);   snprintf(buffer,sizeof(buffer),"CPU%u: %s",cpu->id,module);   vm_flog(cpu->vm,buffer,format,ap);   va_end(ap);}/* Create a new CPU */cpu_gen_t *cpu_create(vm_instance_t *vm,u_int type,u_int id){   void *(*cpu_run_fn)(void *);   cpu_gen_t *cpu;   if (!(cpu = malloc(sizeof(*cpu))))      return NULL;   memset(cpu,0,sizeof(*cpu));   cpu->vm = vm;   cpu->id = id;   cpu->type = type;   cpu->state = CPU_STATE_SUSPENDED;   switch(cpu->type) {      case CPU_TYPE_MIPS64:         cpu->jit_op_array_size = MIPS_INSN_PER_PAGE;         CPU_MIPS64(cpu)->vm = vm;         CPU_MIPS64(cpu)->gen = cpu;         mips64_init(CPU_MIPS64(cpu));         cpu_run_fn = (void *)mips64_jit_run_cpu;         if (!cpu->vm->jit_use)            cpu_run_fn = (void *)mips64_exec_run_cpu;         else            mips64_jit_init(CPU_MIPS64(cpu));         break;      case CPU_TYPE_PPC32:         cpu->jit_op_array_size = PPC32_INSN_PER_PAGE;         CPU_PPC32(cpu)->vm = vm;         CPU_PPC32(cpu)->gen = cpu;         ppc32_init(CPU_PPC32(cpu));         cpu_run_fn = (void *)ppc32_jit_run_cpu;         if (!cpu->vm->jit_use)            cpu_run_fn = (void *)ppc32_exec_run_cpu;         else            ppc32_jit_init(CPU_PPC32(cpu));         break;      default:         fprintf(stderr,"CPU type %u is not supported yet\n",cpu->type);         abort();         break;   }   /* create the CPU thread execution */   if (pthread_create(&cpu->cpu_thread,NULL,cpu_run_fn,cpu) != 0) {      fprintf(stderr,"cpu_create: unable to create thread for CPU%u\n",id);      free(cpu);      return NULL;   }   return cpu;}/* Delete a CPU */void cpu_delete(cpu_gen_t *cpu){   if (cpu) {      /* Stop activity of this CPU */      cpu_stop(cpu);      pthread_join(cpu->cpu_thread,NULL);      /* Free resources */      switch(cpu->type) {         case CPU_TYPE_MIPS64:            mips64_delete(CPU_MIPS64(cpu));            break;         case CPU_TYPE_PPC32:            ppc32_delete(CPU_PPC32(cpu));            break;      }      free(cpu);   }}/* Start a CPU */void cpu_start(cpu_gen_t *cpu){   if (cpu) {      cpu_log(cpu,"CPU_STATE","Starting CPU (old state=%u)...\n",cpu->state);      cpu->state = CPU_STATE_RUNNING;   }}/* Stop a CPU */void cpu_stop(cpu_gen_t *cpu){   if (cpu) {      cpu_log(cpu,"CPU_STATE","Halting CPU (old state=%u)...\n",cpu->state);      cpu->state = CPU_STATE_HALTED;   }}/* Start all CPUs of a CPU group */void cpu_group_start_all_cpu(cpu_group_t *group){   cpu_gen_t *cpu;      for(cpu=group->cpu_list;cpu;cpu=cpu->next)      cpu_start(cpu);}/* Stop all CPUs of a CPU group */void cpu_group_stop_all_cpu(cpu_group_t *group){   cpu_gen_t *cpu;      for(cpu=group->cpu_list;cpu;cpu=cpu->next)      cpu_stop(cpu);}/* Set a state of all CPUs of a CPU group */void cpu_group_set_state(cpu_group_t *group,u_int state){   cpu_gen_t *cpu;      for(cpu=group->cpu_list;cpu;cpu=cpu->next)      cpu->state = state;}/* Returns TRUE if all CPUs in a CPU group are inactive */static int cpu_group_check_activity(cpu_group_t *group){   cpu_gen_t *cpu;   for(cpu=group->cpu_list;cpu;cpu=cpu->next) {      if (!cpu->cpu_thread_running)         continue;      if ((cpu->state == CPU_STATE_RUNNING) || !cpu->seq_state)         return(FALSE);   }   return(TRUE);}/* Synchronize on CPUs (all CPUs must be inactive) */int cpu_group_sync_state(cpu_group_t *group){      cpu_gen_t *cpu;   m_tmcnt_t t1,t2;   /* Check that CPU activity is really suspended */   t1 = m_gettime();   for(cpu=group->cpu_list;cpu;cpu=cpu->next)      cpu->seq_state = 0;   while(!cpu_group_check_activity(group)) {      t2 = m_gettime();      if (t2 > (t1 + 10000))         return(-1);      usleep(50000);   }   return(0);}/* Save state of all CPUs */int cpu_group_save_state(cpu_group_t *group){   cpu_gen_t *cpu;      for(cpu=group->cpu_list;cpu;cpu=cpu->next)      cpu->prev_state = cpu->state;      return(TRUE);}/* Restore state of all CPUs */int cpu_group_restore_state(cpu_group_t *group){   cpu_gen_t *cpu;      for(cpu=group->cpu_list;cpu;cpu=cpu->next)      cpu->state = cpu->prev_state;   return(TRUE);}/* Virtual idle loop */void cpu_idle_loop(cpu_gen_t *cpu){   struct timespec t_spc;   m_tmcnt_t expire;   expire = m_gettime_usec() + cpu->idle_sleep_time;   pthread_mutex_lock(&cpu->idle_mutex);   t_spc.tv_sec = expire / 1000000;   t_spc.tv_nsec = (expire % 1000000) * 1000;   pthread_cond_timedwait(&cpu->idle_cond,&cpu->idle_mutex,&t_spc);   pthread_mutex_unlock(&cpu->idle_mutex);}/* Break idle wait state */void cpu_idle_break_wait(cpu_gen_t *cpu){   pthread_cond_signal(&cpu->idle_cond);   cpu->idle_count = 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -