diff -rc old/prototypes.h ./prototypes.h
*** old/prototypes.h	Sun Feb 28 11:03:01 1993
--- ./prototypes.h	Sun Feb 28 11:19:45 1993
***************
*** 9,15 ****
   *
   * Description: Function prototypes for all GLOBAL procedures
   *
!  * Last Modified: $Date: 93/02/28 10:22:54 $
   *
   * Data Structures: none
   *
--- 9,15 ----
   *
   * Description: Function prototypes for all GLOBAL procedures
   *
!  * Last Modified: $Date: 93/02/28 11:18:43 $
   *
   * Data Structures: none
   *
***************
*** 36,43 ****
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.
   ***************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/old/RCS/prototypes.h,v 1.1 93/02/28 10:22:54 dfk Exp Locker: dfk $
   * $Log:	prototypes.h,v $
   * Revision 1.1  93/02/28  10:22:54  dfk
   * Initial revision
   * 
--- 36,54 ----
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.
   ***************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/RCS/prototypes.h,v 1.2 93/02/28 11:18:43 dfk Exp $
   * $Log:	prototypes.h,v $
+  * Revision 1.2  93/02/28  11:18:43  dfk
+  * >  * changed the sleeping-thread system to be much more efficient.
+  * >  * If a processor is idle, it will skip ahead to the wakeup time
+  * >  * for the first sleeping thread.
+  * >  * It runs MUCH faster than spinning on the TIMER_PERIOD method.
+  * >  * Questions:
+  * >  *   how does it interact with preemptive scheduling? It should work.
+  * >  *   how does it interact with semaphores, which also use timer requests
+  * >  *   does it work with multiple sleeping threads? it should
+  * >  *   does it work when a new thread is creating on a sleeping processor? should.
+  * 
   * Revision 1.1  93/02/28  10:22:54  dfk
   * Initial revision
   * 
***************
*** 364,370 ****
  
  Time ReadTimer(int p);
  void WriteTimer(int p, int t);
! void _timer_handler(void);
  FuncPtr define_timer_handler(int processor, FuncPtr handler);
  FuncPtr define_switch_handler(int processor, FuncPtr handler);
  FuncPtr define_mismatch_handler(int processor, FuncPtr handler);
--- 375,381 ----
  
  Time ReadTimer(int p);
  void WriteTimer(int p, int t);
! void _timer_handler(int processor, int currtid, Time currenttime);
  FuncPtr define_timer_handler(int processor, FuncPtr handler);
  FuncPtr define_switch_handler(int processor, FuncPtr handler);
  FuncPtr define_mismatch_handler(int processor, FuncPtr handler);
diff -rc old/rt_thread.aux.c ./rt_thread.aux.c
*** old/rt_thread.aux.c	Sun Feb 28 11:03:01 1993
--- ./rt_thread.aux.c	Sun Feb 28 11:19:47 1993
***************
*** 10,16 ****
   *
   * Description: Auxiliary non-cycle-counted runtime procedures
   *
!  * Last Modified:  $Date: 93/02/28 10:22:56 $ (eab)
   *
   * Originally written by C. N. Dellarocas  5-91
   *
--- 10,16 ----
   *
   * Description: Auxiliary non-cycle-counted runtime procedures
   *
!  * Last Modified:  $Date: 93/02/28 11:19:47 $ (eab)
   *
   * Originally written by C. N. Dellarocas  5-91
   *
***************
*** 46,53 ****
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.		
   ****************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/old/RCS/rt_thread.aux.c,v 1.1 93/02/28 10:22:56 dfk Exp Locker: dfk $
   * $Log:	rt_thread.aux.c,v $
   * Revision 1.1  93/02/28  10:22:56  dfk
   * Initial revision
   * 
--- 46,64 ----
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.		
   ****************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/RCS/rt_thread.aux.c,v 1.2 93/02/28 11:19:47 dfk Exp $
   * $Log:	rt_thread.aux.c,v $
+  * Revision 1.2  93/02/28  11:19:47  dfk
+  * >  * changed the sleeping-thread system to be much more efficient.
+  * >  * If a processor is idle, it will skip ahead to the wakeup time
+  * >  * for the first sleeping thread.
+  * >  * It runs MUCH faster than spinning on the TIMER_PERIOD method.
+  * >  * Questions:
+  * >  *   how does it interact with preemptive scheduling? It should work.
+  * >  *   how does it interact with semaphores, which also use timer requests
+  * >  *   does it work with multiple sleeping threads? it should
+  * >  *   does it work when a new thread is creating on a sleeping processor? should.
+  * 
   * Revision 1.1  93/02/28  10:22:56  dfk
   * Initial revision
   * 
***************
*** 215,225 ****
  #endif
  #ifdef PREEMPT
  	    if (currpptr->p_numthreads > 0)
  #else
! 	    if (PP->sleep_nonempty)
  #endif
- 	      make_timer_request_(CURR_PROCESSOR, CURR_TID,
- 				  CURR_TIME + ReadTimer(CURR_PROCESSOR));
  	} else printf("*** Warning: at point 1 in rt_thread.aux.c; proc=%d\n",
  		      CURR_PROCESSOR);
  	TrapToSimulator();
--- 226,239 ----
  #endif
  #ifdef PREEMPT
  	    if (currpptr->p_numthreads > 0)
+ 	      make_timer_request_(CURR_PROCESSOR, CURR_TID, 
+ 						 CURR_TIME + ReadTimer(CURR_PROCESSOR));
  #else
! 	    if (PP->sleep_nonempty) {
! 		   Time wakeup_time = *(PP->sleep_head); /* first thing to awake */
! 		   make_timer_request_(CURR_PROCESSOR, CURR_TID, wakeup_time);
! 	    }
  #endif
  	} else printf("*** Warning: at point 1 in rt_thread.aux.c; proc=%d\n",
  		      CURR_PROCESSOR);
  	TrapToSimulator();
diff -rc old/rt_thread.ca ./rt_thread.ca
*** old/rt_thread.ca	Sun Feb 28 11:03:02 1993
--- ./rt_thread.ca	Sun Feb 28 11:19:48 1993
***************
*** 10,16 ****
   *
   * Description: Core runtime thread routines
   *
!  * Last Modified:  $Date: 93/02/28 10:22:57 $ (eab)
   *
   * Originally written by C. N. Dellarocas  3-91
   *
--- 10,16 ----
   *
   * Description: Core runtime thread routines
   *
!  * Last Modified:  $Date: 93/02/28 11:19:48 $ (eab)
   *
   * Originally written by C. N. Dellarocas  3-91
   *
***************
*** 50,57 ****
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.		
   ***************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/old/RCS/rt_thread.ca,v 1.1 93/02/28 10:22:57 dfk Exp Locker: dfk $
   * $Log:	rt_thread.ca,v $
  Revision 1.1  93/02/28  10:22:57  dfk
  Initial revision
  
--- 50,68 ----
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.		
   ***************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/RCS/rt_thread.ca,v 1.2 93/02/28 11:19:48 dfk Exp $
   * $Log:	rt_thread.ca,v $
+ Revision 1.2  93/02/28  11:19:48  dfk
+ >  * changed the sleeping-thread system to be much more efficient.
+ >  * If a processor is idle, it will skip ahead to the wakeup time
+ >  * for the first sleeping thread.
+ >  * It runs MUCH faster than spinning on the TIMER_PERIOD method.
+ >  * Questions:
+ >  *   how does it interact with preemptive scheduling? It should work.
+ >  *   how does it interact with semaphores, which also use timer requests
+ >  *   does it work with multiple sleeping threads? it should
+ >  *   does it work when a new thread is creating on a sleeping processor? should.
+ 
  Revision 1.1  93/02/28  10:22:57  dfk
  Initial revision
  
***************
*** 183,193 ****
  #endif
  
  /* Insert thread into sleep queue. Stid is the simulator tid, head is the
!  * head node index of the sleep queue and key is the duration of sleep.
!  * (number of clock ticks between current time and time stid will be 
!  * woken up). The value written in the qkey field of the sleep queue 
!  * is the difference (in clock ticks) between the wakeup time of stid
!  * and the immediately preceding thread in the sleep queue
   */
  
  static void insertd(stid, head, key)
--- 194,200 ----
  #endif
  
  /* Insert thread into sleep queue. Stid is the simulator tid, head is the
!  * head node index of the sleep queue and key is the wakeup time.
   */
  
  static void insertd(stid, head, key)
***************
*** 197,210 ****
      
      for( prev = head, next = q[head].qnext ; q[next].qkey < key ;
  	prev = next, next = q[next].qnext )
!       key -= q[next].qkey;
      
      q[stid].qnext = next;
      q[stid].qprev = prev;
      q[stid].qkey  = key;
      q[prev].qnext = q[next].qprev = stid;
-     if (next < MAX_THREADS )
-       q[next].qkey -= key;
  }
  
  
--- 204,215 ----
      
      for( prev = head, next = q[head].qnext ; q[next].qkey < key ;
  	prev = next, next = q[next].qnext )
! 	 ;
      
      q[stid].qnext = next;
      q[stid].qprev = prev;
      q[stid].qkey  = key;
      q[prev].qnext = q[next].qprev = stid;
  }
  
  
***************
*** 223,239 ****
  
  /* Wakeup (make ready again) all eligible threads from the sleep queue */
  
! static void wakeup()
  {
      int clockq = PP->clockq;
      int flag = FALSE;
      
!     while( nonempty(clockq) && firstkey( clockq ) <= 0 ) {
  	flag = TRUE;
  	make_ready( T_OSBLOCK(getfirst(clockq))->t_tid, FALSE );
      }
      if ((PP->sleep_nonempty = nonempty(clockq)) != 0 )
!       PP->sleep_head = & q[ q[clockq].qnext ].qkey;
      /* call the scheduler, removed 8-11-92 by eab */
      /* this is correct, but leads to odd timing with round-robin
         scheduling -- current thread always preempted */
--- 228,244 ----
  
  /* Wakeup (make ready again) all eligible threads from the sleep queue */
  
! static void wakeup(Time currenttime)
  {
      int clockq = PP->clockq;
      int flag = FALSE;
      
!     while( nonempty(clockq) && firstkey( clockq ) <= currenttime ) {
  	flag = TRUE;
  	make_ready( T_OSBLOCK(getfirst(clockq))->t_tid, FALSE );
      }
      if ((PP->sleep_nonempty = nonempty(clockq)) != 0 )
! 	 PP->sleep_head = (Time *) (& q[ q[clockq].qnext ].qkey);
      /* call the scheduler, removed 8-11-92 by eab */
      /* this is correct, but leads to odd timing with round-robin
         scheduling -- current thread always preempted */
***************
*** 357,367 ****
  #ifdef PREEMPT
  	if (currpptr->p_numthreads > 1)
  	  /* use > 1 instead of > 0 since this thread not yet destroyed */
  #else
! 	if (PP->sleep_nonempty)
  #endif
- 	  make_timer_request_(CURR_PROCESSOR, CURR_TID,
- 			      t + ReadTimer(CURR_PROCESSOR));
  #ifdef EMERALD
  	if (emerald)
  	  context_switch_hook(currosptr->t_stid, -1);
--- 362,375 ----
  #ifdef PREEMPT
  	if (currpptr->p_numthreads > 1)
  	  /* use > 1 instead of > 0 since this thread not yet destroyed */
+ 	  make_timer_request_(CURR_PROCESSOR, CURR_TID, 
+ 					  t + ReadTimer(CURR_PROCESSOR));
  #else
! 	if (PP->sleep_nonempty) {
! 	    Time wakeup_time = *(PP->sleep_head); /* first thing to awake */
! 	    make_timer_request_(CURR_PROCESSOR, CURR_TID, wakeup_time);
! 	}
  #endif
  #ifdef EMERALD
  	if (emerald)
  	  context_switch_hook(currosptr->t_stid, -1);
***************
*** 708,719 ****
  #endif
  
  #ifdef PREEMPT
! 	    if (currpptr->p_numthreads > 0)
  #else
! 	    if (PP->sleep_nonempty)
  #endif
- 	      make_timer_request_(CURR_PROCESSOR, CURR_TID,
- 				  t + ReadTimer(CURR_PROCESSOR));
  	    CYCLE_COUNTING_ON;
  	} else
  	  printf("*** Warning: at point 1 in rt_thread.ca, proc=%d\n",
--- 716,730 ----
  #endif
  
  #ifdef PREEMPT
! 	if (currpptr->p_numthreads > 0)
! 	  make_timer_request_(CURR_PROCESSOR, CURR_TID, 
! 					  t + ReadTimer(CURR_PROCESSOR));
  #else
! 	if (PP->sleep_nonempty) {
! 	    Time wakeup_time = *(PP->sleep_head); /* first thing to awake */
! 	    make_timer_request_(CURR_PROCESSOR, CURR_TID, wakeup_time);
! 	}
  #endif
  	    CYCLE_COUNTING_ON;
  	} else
  	  printf("*** Warning: at point 1 in rt_thread.ca, proc=%d\n",
***************
*** 837,842 ****
--- 848,855 ----
  {    
      Thread *osptr;
      Word prev;
+     Time wakeup_time;
+     ProcBlk *pptr = &proc_table_[CURR_PROCESSOR];
      
      if (Invalidtid(tid) ||
  	(((osptr = OSBLOCK(tid)) == NULL) ? TRUE
***************
*** 850,857 ****
      
      prev = lock();
      
!     insertd(osptr->t_stid, PP->clockq, duration);
!     PP->sleep_head     = & q[ q[PP->clockq].qnext ].qkey;
      
      switch( osptr->t_state ) {
        case T_CURRENT:
--- 863,872 ----
      
      prev = lock();
      
!     /* use the wakeup time as the priority queue key */
!     wakeup_time = CURR_TIME + duration * TIMER_PERIOD;
!     insertd(osptr->t_stid, PP->clockq, wakeup_time);
!     PP->sleep_head = (Time *)(& q[ q[PP->clockq].qnext ].qkey);
      
      switch( osptr->t_state ) {
        case T_CURRENT:
***************
*** 862,870 ****
  	break;
        case T_READY:
  #ifndef PREEMPT
! 	if (!PP->sleep_nonempty)
! 	  make_timer_request_(CURR_PROCESSOR, CURR_TID,
! 			      CURR_TIME + ReadTimer(CURR_PROCESSOR));
  #endif
  	PP->sleep_nonempty = TRUE;
  	/* remove from ready list */
--- 877,884 ----
  	break;
        case T_READY:
  #ifndef PREEMPT
! 	CancelPendingTimerInterrupt(pptr);
! 	make_timer_request_(CURR_PROCESSOR, CURR_TID, wakeup_time);
  #endif
  	PP->sleep_nonempty = TRUE;
  	/* remove from ready list */
***************
*** 873,881 ****
  	/* falls through to T_INTERRUPTED */
        case T_INTERRUPTED:
  #ifndef PREEMPT
! 	if (!PP->sleep_nonempty)
! 	  make_timer_request_(CURR_PROCESSOR, CURR_TID,
! 			      CURR_TIME + ReadTimer(CURR_PROCESSOR));
  #endif
  	PP->sleep_nonempty = TRUE;
  	osptr->t_state = T_SLEEPING;
--- 887,894 ----
  	/* falls through to T_INTERRUPTED */
        case T_INTERRUPTED:
  #ifndef PREEMPT
! 	CancelPendingTimerInterrupt(pptr);
! 	make_timer_request_(CURR_PROCESSOR, CURR_TID, wakeup_time);
  #endif
  	PP->sleep_nonempty = TRUE;
  	osptr->t_state = T_SLEEPING;
***************
*** 893,911 ****
  
  /* clock interrupt handler */
  
! GLOBAL void _timer_handler()
  {
      int h;
      
!     /* Decrement remaining ticks in head of sleep queue. If they become zero,
!      * wakeup the threads
       */
      if (PP->sleep_nonempty ) {
! 	h = *PP->sleep_head;
! 	h--;
! 	*PP->sleep_head = h;
! 	if (h == 0 )
! 	  wakeup();
      }
      
      /* Decrement processor quantum.
--- 906,921 ----
  
  /* clock interrupt handler */
  
! GLOBAL void _timer_handler(int processor, int currtid, Time currenttime)
  {
      int h;
      
!     /* Check the head of sleep queue. If the current time has 
!      * advanced past its wakeup time, wakeup some threads.
       */
      if (PP->sleep_nonempty ) {
! 	   if (*(PP->sleep_head) <= currenttime)
! 		wakeup(currenttime);
      }
      
      /* Decrement processor quantum.
diff -rc old/rt_thread_def.h ./rt_thread_def.h
*** old/rt_thread_def.h	Sun Feb 28 11:03:02 1993
--- ./rt_thread_def.h	Sun Feb 28 11:19:50 1993
***************
*** 9,15 ****
   *
   * Description: Defines all core runtime thread routines
   *
!  * Last Modified:  $Date: 93/02/28 10:22:59 $ ($Author)
   *
   * Data Structures:
   *      Thread
--- 9,15 ----
   *
   * Description: Defines all core runtime thread routines
   *
!  * Last Modified:  $Date: 93/02/28 11:19:50 $ ($Author)
   *
   * Data Structures:
   *      Thread
***************
*** 44,51 ****
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.		
   ***************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/old/RCS/rt_thread_def.h,v 1.1 93/02/28 10:22:59 dfk Exp Locker: dfk $
   * $Log:	rt_thread_def.h,v $
   * Revision 1.1  93/02/28  10:22:59  dfk
   * Initial revision
   * 
--- 44,62 ----
   *   the suitability of this software for any purpose.  It is pro-
   *   vided "as is" without express or implied warranty.		
   ***************************************************************************
!  * $Header: /a/quimby.dartmouth.edu/usr/wildcat/dfk/research/parallel/proteus/proteus-V3.01/engine/RCS/rt_thread_def.h,v 1.2 93/02/28 11:19:50 dfk Exp $
   * $Log:	rt_thread_def.h,v $
+  * Revision 1.2  93/02/28  11:19:50  dfk
+  * >  * changed the sleeping-thread system to be much more efficient.
+  * >  * If a processor is idle, it will skip ahead to the wakeup time
+  * >  * for the first sleeping thread.
+  * >  * It runs MUCH faster than spinning on the TIMER_PERIOD method.
+  * >  * Questions:
+  * >  *   how does it interact with preemptive scheduling? It should work.
+  * >  *   how does it interact with semaphores, which also use timer requests
+  * >  *   does it work with multiple sleeping threads? it should
+  * >  *   does it work when a new thread is creating on a sleeping processor? should.
+  * 
   * Revision 1.1  93/02/28  10:22:59  dfk
   * Initial revision
   * 
***************
*** 119,124 ****
--- 130,137 ----
  
  #define T_PROCESSOR(t)      (OSBLOCK(t)->t_processor)
  #define T_PRIORITY(t)       (OSBLOCK(t)->t_priority)
+ #define T_STATE(t)	    		(OSBLOCK(t)->t_state) /* DFK */
+ #define NO_TID	 	    		(-1)	/* DFK; an invalid tid number */
  
  #define Invalidtid(t)       (( (t)<0 )||( (t)>=MAX_PROC_THREADS ))
  #define Invalidprio(p)      (0)
***************
*** 135,141 ****
    Thread thread_table[MAX_PROC_THREADS];   /* processor thread table      */
    int nextthread;                          /* possible next available tid */
    BOOL sleep_nonempty;                     /* is the sleep queue nonempty?*/
!   int *sleep_head;                         /* ptr to head of sleep queue  */
    int clockq;                              /* index of clock queue head   */
    int quantum;                             /* timer quantum               */
    /* Add here other fields private to each processor */
--- 148,154 ----
    Thread thread_table[MAX_PROC_THREADS];   /* processor thread table      */
    int nextthread;                          /* possible next available tid */
    BOOL sleep_nonempty;                     /* is the sleep queue nonempty?*/
!   Time *sleep_head;                        /* ptr to head of sleep queue  */
    int clockq;                              /* index of clock queue head   */
    int quantum;                             /* timer quantum               */
    /* Add here other fields private to each processor */
