Index: /trunk/Ohana/src/opihi/include/pantasks.h
===================================================================
--- /trunk/Ohana/src/opihi/include/pantasks.h	(revision 8190)
+++ /trunk/Ohana/src/opihi/include/pantasks.h	(revision 8191)
@@ -52,4 +52,6 @@
   char type;
   char keep;
+  int Nmax;
+  int Nrun;
 } TimeRange;
 
Index: /trunk/Ohana/src/opihi/pantasks/CheckTasks.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/CheckTasks.c	(revision 8190)
+++ /trunk/Ohana/src/opihi/pantasks/CheckTasks.c	(revision 8191)
@@ -30,7 +30,10 @@
     SubmitJob (job);
 
-    /* reset timer on task (don't do this if Create/Submit fails)*/
+    /* reset timer on task (don't do this if Create/Submit fails) (why not??) */
     gettimeofday (&task[0].last, (void *) NULL);
     task[0].Njobs ++;
+
+    /* increment Nrun for inclusive ranges with Nmax */
+    BumpTimeRanges (task[0].ranges, task[0].Nranges);
 
     if (TestElapsedCheck()) return (TRUE);
Index: /trunk/Ohana/src/opihi/pantasks/CheckTimeRanges.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/CheckTimeRanges.c	(revision 8190)
+++ /trunk/Ohana/src/opihi/pantasks/CheckTimeRanges.c	(revision 8191)
@@ -1,35 +1,63 @@
 # include "pantasks.h"
 
+/* test if we meet all time range qualifications */
 int CheckTimeRanges (TimeRange *ranges, int Nranges) {
 
   int i, intime, valid;
-  time_t daytime, weektime, abstime;
+  time_t daytime, weektime, abstime, testtime;
   struct timeval now;
   struct tm Now;
 
+  /* get the current time */
   gettimeofday (&now, NULL);
   gmtime_r (&now.tv_sec, &Now);
-  daytime = Now.tm_sec + Now.tm_min*60 + Now.tm_hour*3600;
+  daytime  = Now.tm_sec + Now.tm_min*60 + Now.tm_hour*3600;
   weektime = Now.tm_sec + Now.tm_min*60 + Now.tm_hour*3600 + Now.tm_wday*86400;
-  abstime = now.tv_sec;
+  abstime  = now.tv_sec;
 
   valid = TRUE;
   for (i = 0; (i < Nranges) && valid; i++) {
     switch (ranges[i].type) {
+      /* set the testtime */
       case RANGE_ABS:
-	intime = (abstime >= ranges[i].start) && (abstime <= ranges[i].stop);
-	valid = ranges[i].keep ? intime : !intime;
+	testtime = abstime;
 	break;
       case RANGE_DAY:
-	intime = (daytime >= ranges[i].start) && (daytime <= ranges[i].stop);
-	valid = ranges[i].keep ? intime : !intime;
+	testtime = daytime;
 	break;
       case RANGE_WEEK:
-	intime = (weektime >= ranges[i].start) && (weektime <= ranges[i].stop);
-	valid = ranges[i].keep ? intime : !intime;
+	testtime = weektime;
 	break;
+      default:
+	abort ();
     }
-    if (!valid) return (FALSE);
+    intime = (testtime >= ranges[i].start) && (testtime <= ranges[i].stop);
+
+    /* check for more than max runs in time range */
+    if (ranges[i].keep && intime && ranges[i].Nmax) {
+      if (ranges[i].Nrun >= ranges[i].Nmax) return (FALSE);
+    }
+    /* reset Nrun if we are outside of intime */
+    if (ranges[i].keep && !intime && ranges[i].Nmax && ranges[i].Nrun) {
+      ranges[i].Nrun = 0;
+    }
+
+    /* is this a valid time? */
+    valid = ranges[i].keep ? intime : !intime;
   }
   return (valid);
 }  
+
+/* increment the number of runs for all inclusive time ranges with Nmax > 0
+   (only call when we execute a task -- after CheckTimeRanges) */
+int BumpTimeRanges (TimeRange *ranges, int Nranges) {
+
+  int i;
+
+  for (i = 0; i < Nranges; i++) {
+    if (ranges[i].keep && ranges[i].Nmax) {
+      ranges[i].Nrun ++;
+    }
+  }
+  return (TRUE);
+}  
Index: /trunk/Ohana/src/opihi/pantasks/task_trange.c
===================================================================
--- /trunk/Ohana/src/opihi/pantasks/task_trange.c	(revision 8190)
+++ /trunk/Ohana/src/opihi/pantasks/task_trange.c	(revision 8191)
@@ -12,4 +12,11 @@
   } */
 
+  range.Nmax = 0;
+  range.Nrun = 0;
+  if (N = get_argument (argc, argv, "-nmax")) {
+    remove_argument (N, &argc, argv);
+    range.Nmax = atoi (argv[N]);
+    remove_argument (N, &argc, argv);
+  }
 
   /* keep = true means the time range defines a valid time range
