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

📄 sim-events.c

📁 这个是LINUX下的GDB调度工具的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  new_event->data = data;  new_event->handler = handler;  /* data */  if (events->resume_wallclock == 0)    new_event->wallclock = (events->elapsed_wallclock + delta_ms_time);  else    new_event->wallclock = (events->elapsed_wallclock			    + sim_elapsed_time_since (events->resume_wallclock)			    + delta_ms_time);  /* insert */  new_event->next = events->watchpoints;  events->watchpoints = new_event;  events->work_pending = 1;  ETRACE ((_ETRACE,	  "event watching clock at %ld - tag 0x%lx - wallclock %ld, handler 0x%lx, data 0x%lx\n",	   (long)sim_events_time (sd),	   (long)new_event,	   (long)new_event->wallclock,	   (long)new_event->handler,	   (long)new_event->data));  return new_event;}#endif#if EXTERN_SIM_EVENTS_Psim_event *sim_events_watch_sim (SIM_DESC sd,		      void *host_addr,		      int nr_bytes,		      int byte_order,		      int is_within,		      unsigned64 lb,		      unsigned64 ub,		      sim_event_handler *handler,		      void *data){  sim_events *events = STATE_EVENTS (sd);  sim_event *new_event = sim_events_zalloc (sd);  /* type */  switch (byte_order)    {    case 0:      switch (nr_bytes)	{	case 1: new_event->watching = watch_sim_host_1; break;	case 2: new_event->watching = watch_sim_host_2; break;	case 4: new_event->watching = watch_sim_host_4; break;	case 8: new_event->watching = watch_sim_host_8; break;	default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");	}      break;    case BIG_ENDIAN:      switch (nr_bytes)	{	case 1: new_event->watching = watch_sim_be_1; break;	case 2: new_event->watching = watch_sim_be_2; break;	case 4: new_event->watching = watch_sim_be_4; break;	case 8: new_event->watching = watch_sim_be_8; break;	default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");	}      break;    case LITTLE_ENDIAN:      switch (nr_bytes)	{	case 1: new_event->watching = watch_sim_le_1; break;	case 2: new_event->watching = watch_sim_le_2; break;	case 4: new_event->watching = watch_sim_le_4; break;	case 8: new_event->watching = watch_sim_le_8; break;	default: sim_io_error (sd, "sim_events_watch_sim - invalid nr bytes");	}      break;    default:      sim_io_error (sd, "sim_events_watch_sim - invalid byte order");    }  /* handler */  new_event->data = data;  new_event->handler = handler;  /* data */  new_event->host_addr = host_addr;  new_event->lb = lb;  new_event->lb64 = lb;  new_event->ub = ub;  new_event->ub64 = ub;  new_event->is_within = (is_within != 0);  /* insert */  new_event->next = events->watchpoints;  events->watchpoints = new_event;  events->work_pending = 1;  ETRACE ((_ETRACE,	   "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",	   (long)sim_events_time (sd),	   (long)new_event,	   (long)new_event->host_addr,	   (long)new_event->lb,	   (long)new_event->ub,	   (long)new_event->handler,	   (long)new_event->data));  return new_event;}#endif#if EXTERN_SIM_EVENTS_Psim_event *sim_events_watch_core (SIM_DESC sd,		       address_word core_addr,		       unsigned core_map,		       int nr_bytes,		       int byte_order,		       int is_within,		       unsigned64 lb,		       unsigned64 ub,		       sim_event_handler *handler,		       void *data){  sim_events *events = STATE_EVENTS (sd);  sim_event *new_event = sim_events_zalloc (sd);  /* type */  switch (byte_order)    {    case 0:      switch (nr_bytes)	{	case 1: new_event->watching = watch_core_targ_1; break;	case 2: new_event->watching = watch_core_targ_2; break;	case 4: new_event->watching = watch_core_targ_4; break;	case 8: new_event->watching = watch_core_targ_8; break;	default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");	}      break;    case BIG_ENDIAN:      switch (nr_bytes)	{	case 1: new_event->watching = watch_core_be_1; break;	case 2: new_event->watching = watch_core_be_2; break;	case 4: new_event->watching = watch_core_be_4; break;	case 8: new_event->watching = watch_core_be_8; break;	default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");	}      break;    case LITTLE_ENDIAN:      switch (nr_bytes)	{	case 1: new_event->watching = watch_core_le_1; break;	case 2: new_event->watching = watch_core_le_2; break;	case 4: new_event->watching = watch_core_le_4; break;	case 8: new_event->watching = watch_core_le_8; break;	default: sim_io_error (sd, "sim_events_watch_core - invalid nr bytes");	}      break;    default:      sim_io_error (sd, "sim_events_watch_core - invalid byte order");    }  /* handler */  new_event->data = data;  new_event->handler = handler;  /* data */  new_event->core_addr = core_addr;  new_event->core_map = core_map;  new_event->lb = lb;  new_event->lb64 = lb;  new_event->ub = ub;  new_event->ub64 = ub;  new_event->is_within = (is_within != 0);  /* insert */  new_event->next = events->watchpoints;  events->watchpoints = new_event;  events->work_pending = 1;  ETRACE ((_ETRACE,	   "event watching host at %ld - tag 0x%lx - host-addr 0x%lx, 0x%lx..0x%lx, handler 0x%lx, data 0x%lx\n",	   (long)sim_events_time (sd),	   (long)new_event,	   (long)new_event->host_addr,	   (long)new_event->lb,	   (long)new_event->ub,	   (long)new_event->handler,	   (long)new_event->data));  return new_event;}#endif#if EXTERN_SIM_EVENTS_Pvoidsim_events_deschedule (SIM_DESC sd,		       sim_event *event_to_remove){  sim_events *events = STATE_EVENTS (sd);  sim_event *to_remove = (sim_event*)event_to_remove;  if (event_to_remove != NULL)    {      sim_event **queue = NULL;      while ((queue = next_event_queue (sd, queue)) != NULL)	{	  sim_event **ptr_to_current;	  for (ptr_to_current = queue;	       *ptr_to_current != NULL && *ptr_to_current != to_remove;	       ptr_to_current = &(*ptr_to_current)->next);	  if (*ptr_to_current == to_remove)	    {	      sim_event *dead = *ptr_to_current;	      *ptr_to_current = dead->next;	      ETRACE ((_ETRACE,		       "event/watch descheduled at %ld - tag 0x%lx - time %ld, handler 0x%lx, data 0x%lx%s%s\n",		       (long) sim_events_time (sd),		       (long) event_to_remove,		       (long) dead->time_of_event,		       (long) dead->handler,		       (long) dead->data,		       (dead->trace != NULL) ? ", " : "",		       (dead->trace != NULL) ? dead->trace : ""));	      sim_events_free (sd, dead);	      update_time_from_event (sd);	      SIM_ASSERT ((events->time_from_event >= 0) == (events->queue != NULL));	      return;	    }	}    }  ETRACE ((_ETRACE,	   "event/watch descheduled at %ld - tag 0x%lx - not found\n",	   (long) sim_events_time (sd),	   (long) event_to_remove));}#endifSTATIC_INLINE_SIM_EVENTS\(int)sim_watch_valid (SIM_DESC sd,		 sim_event *to_do){  switch (to_do->watching)    {#define WATCH_CORE(N,OP,EXT) \      int ok; \      unsigned_##N word = 0; \      int nr_read = sim_core_read_buffer (sd, NULL, to_do->core_map, &word, \					  to_do->core_addr, sizeof (word)); \      OP (word); \      ok = (nr_read == sizeof (unsigned_##N) \	    && (to_do->is_within \		== (word >= to_do->lb##EXT \		    && word <= to_do->ub##EXT)));    case watch_core_targ_1:      {	WATCH_CORE (1, T2H,);	return ok;      }    case watch_core_targ_2:      {        WATCH_CORE (2, T2H,);	return ok;      }    case watch_core_targ_4:      {        WATCH_CORE (4, T2H,);	return ok;      }    case watch_core_targ_8:      {        WATCH_CORE (8, T2H,64);	return ok;      }    case watch_core_be_1:      {        WATCH_CORE (1, BE2H,);	return ok;      }    case watch_core_be_2:      {        WATCH_CORE (2, BE2H,);	return ok;      }    case watch_core_be_4:      {        WATCH_CORE (4, BE2H,);	return ok;      }    case watch_core_be_8:      {        WATCH_CORE (8, BE2H,64);	return ok;      }    case watch_core_le_1:      {        WATCH_CORE (1, LE2H,);	return ok;      }    case watch_core_le_2:      {        WATCH_CORE (2, LE2H,);	return ok;      }    case watch_core_le_4:      {        WATCH_CORE (4, LE2H,);	return ok;      }    case watch_core_le_8:      {        WATCH_CORE (8, LE2H,64);	return ok;      }#undef WATCH_CORE#define WATCH_SIM(N,OP,EXT) \      int ok; \      unsigned_##N word = *(unsigned_##N*)to_do->host_addr; \      OP (word); \      ok = (to_do->is_within \	    == (word >= to_do->lb##EXT \		&& word <= to_do->ub##EXT));    case watch_sim_host_1:      {        WATCH_SIM (1, word = ,);	return ok;      }    case watch_sim_host_2:      {        WATCH_SIM (2, word = ,);	return ok;      }    case watch_sim_host_4:      {        WATCH_SIM (4, word = ,);	return ok;      }    case watch_sim_host_8:      {        WATCH_SIM (8, word = ,64);	return ok;      }    case watch_sim_be_1:      {        WATCH_SIM (1, BE2H,);	return ok;      }    case watch_sim_be_2:      {        WATCH_SIM (2, BE2H,);	return ok;      }    case watch_sim_be_4:      {        WATCH_SIM (4, BE2H,);	return ok;      }    case watch_sim_be_8:      {        WATCH_SIM (8, BE2H,64);	return ok;      }    case watch_sim_le_1:      {        WATCH_SIM (1, LE2H,);	return ok;      }    case watch_sim_le_2:      {        WATCH_SIM (1, LE2H,);	return ok;      }    case watch_sim_le_4:      {        WATCH_SIM (1, LE2H,);	return ok;      }    case watch_sim_le_8:      {        WATCH_SIM (1, LE2H,64);	return ok;      }#undef WATCH_SIM    case watch_clock: /* wallclock */      {	unsigned long elapsed_time = sim_events_elapsed_time (sd);	return (elapsed_time >= to_do->wallclock);      }    default:      sim_io_error (sd, "sim_watch_valid - bad switch");      break;    }  return 1;}INLINE_SIM_EVENTS\(int)sim_events_tick (SIM_DESC sd){  sim_events *events = STATE_EVENTS (sd);  /* this should only be called after the previous ticks have been     fully processed */  /* Advance the time but *only* if there is nothing to process */  if (events->work_pending      || events->time_from_event == 0)    {      events->nr_ticks_to_process += 1;      return 1;    }  else    {      events->time_from_event -= 1;      return 0;    }}INLINE_SIM_EVENTS\(int)sim_events_tickn (SIM_DESC sd,		  int n){  sim_events *events = STATE_EVENTS (sd);  SIM_ASSERT (n > 0);  /* this should only be called after the previous ticks have been     fully processed */  /* Advance the time but *only* if there is nothing to process */  if (events->work_pending || events->time_from_event < n)    {      events->nr_ticks_to_process += n;      return 1;    }  else    {      events->time_from_event -= n;      return 0;    }}INLINE_SIM_EVENTS\(void)sim_events_slip (SIM_DESC sd,		 int slip){  sim_events *events = STATE_EVENTS (sd);  SIM_ASSERT (slip > 0);  /* Flag a ready event with work_pending instead of number of ticks     to process so that the time continues to be correct */  if (events->time_from_event < slip)    {      events->work_pending = 1;    }  events->time_from_event -= slip;}INLINE_SIM_EVENTS\(void)sim_events_preprocess (SIM_DESC sd,		       int events_were_last,		       int events_were_next){  sim_events *events = STATE_EVENTS(sd);  if (events_were_last)    {      /* Halted part way through event processing */      ASSERT (events->nr_ticks_to_process != 0);      /* The external world can't tell if the event that stopped the         simulator was the last event to process. */      ASSERT (events_were_next);      sim_events_process (sd);    }  else if (events_were_next)    {      /* Halted by the last processor */      if (sim_events_tick (sd))	sim_events_process (sd);    }}INLINE_SIM_EVENTS\(void)sim_events_process (SIM_DESC sd){  sim_events *events = STATE_EVENTS(sd);  signed64 event_time = sim_events_time(sd);  /* Clear work_pending before checking nr_held.  Clearing     work_pending after nr_held (with out a lock could loose an     event). */  events->work_pending = 0;  /* move any events that were asynchronously queued by any signal     handlers onto the real event queue.  */  if (events->nr_held > 0)    {      int i;      #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)      /*-LOCK-*/      sigset_t old_mask;      sigset_t new_mask;      sigfillset(&new_mask);      sigprocmask(SIG_SETMASK, &new_mask, &old_mask);#endif      for (i = 0; i < events->nr_held; i++)	{	  sim_event *entry = &events->held [i];	  sim_events_schedule (sd,			       entry->time_of_event,			       entry->handler,			       entry->data);	}      events->nr_held = 0;      #if defined(HAVE_SIGPROCMASK) && defined(SIG_SETMASK)      /*-UNLOCK-*/      sigprocmask(SIG_SETMASK, &old_mask, NULL);#endif          }    /* Process any watchpoints. Be careful to allow a watchpoint to     appear/disappear under our feet.     To ensure that watchpoints are processed only once per cycle,     they are moved onto a watched queue, this returned to the     watchpoint queue when all queue processing has been     completed. */  while (events->watchpoints != NULL)    {      sim_event *to_do = events->watchpoints;      events->watchpoints = to_do->next;      if (sim_watch_valid (sd, to_do))	{	  sim_event_handler *handler = to_do->handler;	  void *data = to_do->data;	  ETRACE((_ETRACE,		  "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",		  (long) event_time,		  (long) to_do,		  (long) handler,		  (long) data,		  (to_do->trace != NULL) ? ", " : "",		  (to_do->trace != NULL) ? to_do->trace : ""));	  sim_events_free (sd, to_do);	  handler (sd, data);	}      else	{	  to_do->next = events->watchedpoints;	  events->watchedpoints = to_do;	}    }    /* consume all events for this or earlier times.  Be careful to     allow an event to appear/disappear under our feet */  while (events->queue->time_of_event <	 (event_time + events->nr_ticks_to_process))    {      sim_event *to_do = events->queue;      sim_event_handler *handler = to_do->handler;      void *data = to_do->data;      events->queue = to_do->next;      update_time_from_event (sd);      ETRACE((_ETRACE,	      "event issued at %ld - tag 0x%lx - handler 0x%lx, data 0x%lx%s%s\n",	      (long) event_time,	      (long) to_do,	      (long) handler,	      (long) data,	      (to_do->trace != NULL) ? ", " : "",	      (to_do->trace != NULL) ? to_do->trace : ""));      sim_events_free (sd, to_do);      handler (sd, data);    }    /* put things back where they belong ready for the next iteration */  events->watchpoints = events->watchedpoints;  events->watchedpoints = NULL;  if (events->watchpoints != NULL)    events->work_pending = 1;    /* advance the time */  SIM_ASSERT (events->time_from_event >= events->nr_ticks_to_process);  SIM_ASSERT (events->queue != NULL); /* always poll event */  events->time_from_event -= events->nr_ticks_to_process;  /* this round of processing complete */  events->nr_ticks_to_process = 0;}#endif

⌨️ 快捷键说明

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