Index: configure
===================================================================
RCS file: /flux/CVS/emulab-rude/configure,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** configure	27 Jun 2006 17:50:14 -0000	1.1.1.1
--- configure	27 Jun 2006 18:26:14 -0000	1.2
***************
*** 2062,2068 ****
  ###################
  # Make it happen. #
  ###################
! CFLAGS="$CFLAGS -I../include"
  trap '' 1 2 15
  cat > confcache <<\EOF
  # This file is a shell script that caches the results of configure
--- 2062,2068 ----
  ###################
  # Make it happen. #
  ###################
! CFLAGS="$CFLAGS -I\$(srcdir)/../include -I../include"
  trap '' 1 2 15
  cat > confcache <<\EOF
  # This file is a shell script that caches the results of configure
Index: autoconf/configure.in
===================================================================
RCS file: /flux/CVS/emulab-rude/autoconf/configure.in,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** autoconf/configure.in	27 Jun 2006 17:50:15 -0000	1.1.1.1
--- autoconf/configure.in	27 Jun 2006 18:26:17 -0000	1.2
***************
*** 121,126 ****
  ###################
  # Make it happen. #
  ###################
! CFLAGS="$CFLAGS -I../include"
  AC_OUTPUT(Makefile:autoconf/Makefile.in rude/Makefile crude/Makefile, \
  	  echo timestamp > include/stamp.h)
--- 121,126 ----
  ###################
  # Make it happen. #
  ###################
! CFLAGS="$CFLAGS -I\$(srcdir)/../include -I../include"
  AC_OUTPUT(Makefile:autoconf/Makefile.in rude/Makefile crude/Makefile, \
  	  echo timestamp > include/stamp.h)
Index: crude/main.c
===================================================================
RCS file: /flux/CVS/emulab-rude/crude/main.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** crude/main.c	27 Jun 2006 17:50:15 -0000	1.1.1.1
--- crude/main.c	28 Jul 2006 23:55:12 -0000	1.3
***************
*** 35,42 ****
--- 35,44 ----
  #include <sys/stat.h>
  #include <sys/socket.h>
  #include <sys/time.h>
+ #ifndef __CYGWIN__
  #include <sched.h>
  #include <sys/mman.h>
+ #endif /* ifndef__CYGWIN__ */
  #include <arpa/inet.h>
  #include <netinet/in.h>
  #include <limits.h>
***************
*** 106,112 ****
--- 108,116 ----
    long temp1          = 0;
    int ps_flag         = 0;
    struct sigaction action;
+ #ifndef __CYGWIN__
    struct sched_param p;
+ #endif /* ifndef__CYGWIN__ */
    char *sptr, *eptr;
    struct flow_stat *newflows;
  
***************
*** 205,212 ****
--- 209,220 ----
        retval = -2;
     }
     if(user_id != 0){
+ #ifndef __CYGWIN__
        fprintf(stderr,"crude: must be root to set the priority level\n");
        retval = -2;
+ #else /* ifndef__CYGWIN__ */
+       fprintf(stderr,"crude: priority level is not supported on Cygwin\n");
+ #endif /* ifndef__CYGWIN__ */
     }
        } else {
     RUDEBUG1("crude: invalid commandline arguments!\n");
***************
*** 288,302 ****
--- 296,315 ----
    /* (if retval < 0 -> ERROR or/and EXIT IMMEDIATELY) */
    if(retval < 0){ goto crude_exit; }
   
+ #ifndef __CYGWIN__
    /*
     * If this process is owned by root we can do some tricks to
     * improve the performance... (the -P option)
     */
    if((user_id == 0) && (priority > 0)){
      /* Try to lock the memory to avoid paging delays */
+ #ifdef HAVE_MUNLOCKALL
      if(mlockall(MCL_CURRENT | MCL_FUTURE) < 0){
        RUDEBUG1("crude: memory lock failed: %s\n", strerror(errno));
      }
+ #else
+     RUDEBUG1("crude: memory lock unsupported\n");
+ #endif
  
      /* Switch to Round-Robin-Real-Time Scheduling */
      p.sched_priority = priority;
***************
*** 307,312 ****
--- 320,326 ----
      }
      RUDEBUG7("crude: program priority set to %d\n", p.sched_priority);
    }                                                                             
+ #endif /* ifndef__CYGWIN__ */
   
    /* Activate the signal handler(s) */
    memset(&action, 0, sizeof(struct sigaction));
***************
*** 332,337 ****
--- 346,352 ----
  
   crude_exit:
    if (retval >= 0 && nflows > 0) { ps_flag = 1; }
+ #ifndef __CYGWIN__
    /*
     * Restore the tweaked settings...
     */
***************
*** 346,354 ****
        RUDEBUG7("crude: program priority restored\n");
      }
  
      /* Release the locked memory */
      munlockall();
!   }                                                                             
  
    if(ps_flag){ print_stats(); }
    if(main_file > 0){ close(main_file); }
--- 361,372 ----
        RUDEBUG7("crude: program priority restored\n");
      }
  
+ #ifdef HAVE_MUNLOCKALL
      /* Release the locked memory */
      munlockall();
! #endif
!   }
! #endif /* ifndef__CYGWIN__ */
  
    if(ps_flag){ print_stats(); }
    if(main_file > 0){ close(main_file); }
***************
*** 384,392 ****
--- 402,413 ----
   */
  void crude_handler(int value)
  {
+ #ifndef __CYGWIN__
    struct sched_param pri;
+ #endif /* ifndef__CYGWIN__ */
    RUDEBUG7("\ncrude: SIGNAL caught - exiting...\n");
   
+ #ifndef __CYGWIN__
    /* Check & restore process priority */
    if((getuid() == 0) && (sched_getscheduler(0) != SCHED_OTHER)){
      pri.sched_priority = 0;
***************
*** 396,401 ****
--- 417,423 ----
        RUDEBUG7("crude_handler: crude priority restored\n");
      }
    }                                                                             
+ #endif /* ifndef__CYGWIN__ */
  
    if(nflows > 0){ print_stats(); }
    if(main_file > 0){ close(main_file); }
***************
*** 663,670 ****
  
      /* print average delay as sign and absolute value */
      if ( (sec < 0) || (usec < 0) ) {
!       sec  = llabs( sec );
!       usec = llabs( usec );
        printf("Delay: average = -%lld.%06llu   ", sec, usec);
      } else {
        printf("Delay: average = %lld.%06llu   ", sec, usec);
--- 685,692 ----
  
      /* print average delay as sign and absolute value */
      if ( (sec < 0) || (usec < 0) ) {
!       if (sec < 0) sec *= -1;
!       if (usec < 0) usec *= -1;
        printf("Delay: average = -%lld.%06llu   ", sec, usec);
      } else {
        printf("Delay: average = %lld.%06llu   ", sec, usec);
Index: include/rude.h
===================================================================
RCS file: /flux/CVS/emulab-rude/include/rude.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** include/rude.h	27 Jun 2006 17:50:15 -0000	1.1.1.1
--- include/rude.h	27 Jun 2006 18:22:18 -0000	1.2
***************
*** 24,29 ****
--- 24,30 ----
  #ifndef _RUDE_H
  #define _RUDE_H
  
+ #include <sys/types.h>
  #include <netinet/in.h>  /* for struct sockaddr_in */
  #include <sys/time.h>    /* for struct timeval     */
  
***************
*** 107,117 ****
   * Wrapper structure that helps filling the "header" to the buffer
   */
  struct udp_data{
!   unsigned long sequence_number;
!   unsigned long tx_time_seconds; 
!   unsigned long tx_time_useconds; 
!   unsigned long flow_id;
!   unsigned long dest_addr;
  }__attribute__ ((packed));
  
  
--- 108,118 ----
   * Wrapper structure that helps filling the "header" to the buffer
   */
  struct udp_data{
!   uint32_t sequence_number;
!   uint32_t tx_time_seconds; 
!   uint32_t tx_time_useconds; 
!   uint32_t flow_id;
!   uint32_t dest_addr;
  }__attribute__ ((packed));
  
  
Index: rude/flow_txmit.c
===================================================================
RCS file: /flux/CVS/emulab-rude/rude/flow_txmit.c,v
retrieving revision 1.1.1.1
retrieving revision 1.4
diff -c -r1.1.1.1 -r1.4
*** rude/flow_txmit.c	27 Jun 2006 17:50:14 -0000	1.1.1.1
--- rude/flow_txmit.c	28 Jul 2006 23:55:13 -0000	1.4
***************
*** 29,36 ****
--- 29,38 ----
  #include <string.h>
  #include <unistd.h>
  #include <errno.h>
+ #ifndef __CYGWIN__
  #include <sched.h>
  #include <sys/mman.h>
+ #endif /* ifndef__CYGWIN__ */
  #include <sys/time.h>
  #include <sys/types.h>
  #include <sys/socket.h>
***************
*** 43,58 ****
  extern struct udp_data *data;
  extern char            *buffer;
  
  
  /*
!  * wait_for_xmit(): Wait for certain period of time in busy-loop
   */
! __inline__ void wait_for_xmit(struct timeval *target, struct timeval *now)
  {
    while(1){
-     gettimeofday(now,NULL);
      if(timercmp(now,target,<)){
!       /* FIXME: check if the timegap is large => use [u | nano]sleep() */
        continue;
      }
      return;
--- 45,119 ----
  extern struct udp_data *data;
  extern char            *buffer;
  
+ static int usecpertick = 0;
  
  /*
!  * init_wait(): set the resolution of the clock.
!  * We use this in wait_for_xmit(), if the desired sleep time is at least
!  * twice the clock resolution, we sleep rather than spin.
!  * XXX this could be determined dynamically.
!  */
! void wait_init(int tickspersec)
! {
!   if (tickspersec < 1000000)
!     usecpertick = 1000000 / tickspersec;
! }
! 
! #ifdef WAITSTATS
! static unsigned int calls;
! static unsigned int toolong;
! static unsigned long long toolongby;
! #endif
! 
! void wait_finish(void)
! {
! #ifdef WAITSTATS
!   printf("%d calls, %d slept too long (by %dusec ave)\n",
! 	 calls, toolong, toolongby/toolong);
! #endif
! }
! 
! /*
!  * wait_for_xmit(): Wait for certain period of time
   */
! static __inline__ void wait_for_xmit(struct timeval *target, struct timeval *now)
  {
+   gettimeofday(now,NULL);
+   if (usecpertick) {
+     struct timeval dtv;
+     int usec;
+ 
+     timersub(target,now,&dtv);
+     usec = dtv.tv_sec * 1000000 + dtv.tv_usec;
+     if (usec >= usecpertick*2) {
+       int res = usec % usecpertick;
+ 
+       /* empirical voodoo */
+       if (res == 0) res = 1;
+ 
+       usec -= res;
+       dtv.tv_sec = usec / 1000000;
+       dtv.tv_usec = usec % 1000000;
+       select(0,NULL,NULL,NULL,&dtv);
+       gettimeofday(now,NULL);
+ 
+ #ifdef WAITSTATS
+       /* XXX fernow stats */
+       calls++;
+       if (timercmp(now,target,>)) {
+         toolong++;
+         timersub(now,target,&dtv);
+         usec = dtv.tv_sec * 1000000 + dtv.tv_usec;
+         toolongby += usec;
+         return;
+       }
+ #endif
+     }
+   }
+ 
    while(1){
      if(timercmp(now,target,<)){
!       gettimeofday(now,NULL);
        continue;
      }
      return;
***************
*** 78,83 ****
--- 139,148 ----
    data->sequence_number = htonl(flow->sequence_nmbr);
    wait_for_xmit(&flow->next_tx, &now);
  
+   /* Emulab hack: this can happen for a final zero transmission */
+   if (p->rate == 0)
+     return;
+ 
    /* ...and fill in the rest of the data */
    data->tx_time_seconds  = htonl(now.tv_sec);
    data->tx_time_useconds = htonl(now.tv_usec);
Index: rude/main.c
===================================================================
RCS file: /flux/CVS/emulab-rude/rude/main.c,v
retrieving revision 1.1.1.1
retrieving revision 1.3
diff -c -r1.1.1.1 -r1.3
*** rude/main.c	27 Jun 2006 17:50:14 -0000	1.1.1.1
--- rude/main.c	28 Jul 2006 23:55:13 -0000	1.3
***************
*** 31,42 ****
  #include <string.h>
  #include <unistd.h>
  #include <fcntl.h>
- #include <sys/mman.h>
  #include <sys/time.h>
  #include <sys/wait.h>
  #include <sys/types.h>
  #include <sys/socket.h>
  #include <sched.h>
  #include <arpa/inet.h>
  #include <netinet/in.h>
  
--- 31,44 ----
  #include <string.h>
  #include <unistd.h>
  #include <fcntl.h>
  #include <sys/time.h>
  #include <sys/wait.h>
  #include <sys/types.h>
  #include <sys/socket.h>
+ #ifndef __CYGWIN__
  #include <sched.h>
+ #include <sys/mman.h>
+ #endif /* ifndef__CYGWIN__ */
  #include <arpa/inet.h>
  #include <netinet/in.h>
  
***************
*** 82,88 ****
--- 84,92 ----
    int retval            = 0;
    uid_t user_id         = getuid();
    struct sigaction action;
+ #ifndef __CYGWIN__
    struct sched_param p;
+ #endif /* ifndef__CYGWIN__ */
  
    printf("rude version %s, Copyright (C) 1999 Juha Laine and Sampo Saaristo\n"
  	 "rude comes with ABSOLUTELY NO WARRANTY!\n"
***************
*** 95,101 ****
      exit(1);
    }
  
!   while(((opt_ret=getopt(argc,argv,"s:P:hv")) != EOF) && (retval == 0)){
      switch(opt_ret){
      case 'v':
        if((optind == 2) && (argc == 2)){
--- 99,105 ----
      exit(1);
    }
  
!   while(((opt_ret=getopt(argc,argv,"s:P:hvC:")) != EOF) && (retval == 0)){
      switch(opt_ret){
      case 'v':
        if((optind == 2) && (argc == 2)){
***************
*** 138,145 ****
--- 142,153 ----
  	  retval = -2;
  	}
  	if(user_id != 0){
+ #ifndef __CYGWIN__
  	  fprintf(stderr,"rude: must be root to set the priority level\n");
  	  retval = -2;
+ #else /* ifndef__CYGWIN__ */
+ 	  fprintf(stderr,"rude: priority level is not supported on Cygwin\n");
+ #endif /* ifndef__CYGWIN__ */
  	}
        } else {
  	RUDEBUG1("rude: invalid commandline arguments!\n");
***************
*** 147,152 ****
--- 155,164 ----
        }
        break;
  
+     case 'C':
+       wait_init(atoi(optarg));
+       break;
+ 
      default:
        usage(argv[0]);
        retval = -2;
***************
*** 198,212 ****
--- 210,229 ----
      goto rude_exit1;
    }
  
+ #ifndef __CYGWIN__
    /*
     * If this process is owned by root we can do some tricks to
     * improve the performance... (the -P option)
     */
    if((user_id == 0) && (priority > 0)){
      /* Try to lock the memory to avoid paging delays */
+ #ifdef HAVE_MUNLOCKALL
      if(mlockall(MCL_CURRENT | MCL_FUTURE) < 0){
        RUDEBUG1("rude: memory lock failed: %s\n", strerror(errno));
      }
+ #else
+     RUDEBUG1("rude: memory lock unsupported\n");
+ #endif
  
      /* Switch to Round-Robin-Real-Time Scheduling */
      p.sched_priority = priority;
***************
*** 217,222 ****
--- 234,240 ----
      }
      RUDEBUG7("rude: program priority set to %d\n", p.sched_priority);
    }
+ #endif /* ifndef__CYGWIN__ */
  
    /*
     * All is fine - start looping & transmitting
***************
*** 229,234 ****
--- 247,253 ----
  
   rude_exit:
  
+ #ifndef __CYGWIN__
    /*
     * Restore the tweaked settings...
     */
***************
*** 242,250 ****
--- 261,272 ----
        RUDEBUG7("rude: program priority restored\n");
      }
  
+ #ifdef HAVE_MUNLOCKALL
      /* Release the locked memory */
      munlockall();
+ #endif
    }
+ #endif /* ifndef__CYGWIN__ */
  
   rude_exit1:
  
***************
*** 262,270 ****
--- 284,295 ----
  void rude_handler(int value)
  {
    int ret_val = (value * (-1));
+ #ifndef __CYGWIN__
    struct sched_param pri;
+ #endif /* ifndef__CYGWIN__ */
    RUDEBUG7("\nrude_handler(): receiver SIGNAL %d - clean-up & exit\n",value);
  
+ #ifndef __CYGWIN__
    /* Check & restore process priority */
    if((getuid() == 0) && (sched_getscheduler(0) != SCHED_OTHER)){
      pri.sched_priority = 0;
***************
*** 275,281 ****
--- 300,309 ----
      }
    }
  
+ #ifdef HAVE_MUNLOCKALL
    munlockall();
+ #endif
+ #endif /* ifndef__CYGWIN__ */
    clean_up();
    exit(ret_val);
  } /* main() */
***************
*** 414,419 ****
--- 442,448 ----
      }
      flow = flow->next;
    }
+   wait_finish();
    return;
  } /* print_results() */
  
Index: rude/parse.c
===================================================================
RCS file: /flux/CVS/emulab-rude/rude/parse.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** rude/parse.c	27 Jun 2006 17:50:14 -0000	1.1.1.1
--- rude/parse.c	27 Jun 2006 18:28:48 -0000	1.2
***************
*** 309,315 ****
    new->tos = -1;  /* By default, don't set the TOS */
  
    /* Do sanity check to the given parameters */
!   if((time < 0) || (sport < 1024) || ((typenum=check_type(type)) < 0) || 
       (check_dst(dst,&new->dst) != 0)){
      free(new);
      RUDEBUG1("flow_on() - illegal argument values\n");
--- 309,316 ----
    new->tos = -1;  /* By default, don't set the TOS */
  
    /* Do sanity check to the given parameters */
!   if((time < 0) || (sport > 0 && sport < 1024) || 
!      ((typenum=check_type(type)) < 0) || 
       (check_dst(dst,&new->dst) != 0)){
      free(new);
      RUDEBUG1("flow_on() - illegal argument values\n");
***************
*** 688,694 ****
--- 688,696 ----
        /* NEW in 0.50: Enable flow "stop" - ZERO transmission rate... */
        if(temp->params.cbr.rate == 0){
  	temp->next_tx = temp->flow_stop;
+ 	/* Emulab hack: make final zero transmission actually happen
  	temp->next_tx.tv_sec++;
+ 	*/
        }
        break;
      case(TRACE):
Index: rude/rude.8
===================================================================
RCS file: /flux/CVS/emulab-rude/rude/rude.8,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -c -r1.1.1.1 -r1.2
*** rude/rude.8	27 Jun 2006 17:50:15 -0000	1.1.1.1
--- rude/rude.8	28 Jul 2006 23:55:13 -0000	1.2
***************
*** 35,41 ****
  The script 
  .IB file 
  describing the flows to be sent by the rude program. 
! See ../rude/DOC/example.cfg, for an example. 
  .IP \fB\-h 
  Print a short help.
  .IP \fB\-v
--- 35,41 ----
  The script 
  .IB file 
  describing the flows to be sent by the rude program. 
! See /usr/share/doc/rude/DOC/example.cfg, for an example. 
  .IP \fB\-h 
  Print a short help.
  .IP \fB\-v
