00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 #include "P_EventSystem.h"
00025 #include "RegressionSM.h"
00026 
00027 #define REGRESSION_SM_RETRY (100*HRTIME_MSECOND)
00028 
00029 void RegressionSM::set_status(int astatus)
00030 {
00031   ink_assert(astatus != REGRESSION_TEST_INPROGRESS);
00032   
00033   if (status != REGRESSION_TEST_FAILED) {
00034     if (status == REGRESSION_TEST_PASSED) {
00035       if (astatus != REGRESSION_TEST_NOT_RUN)
00036         status = astatus;
00037     } else {
00038       
00039       status = astatus;
00040     }
00041   } 
00042 }
00043 
00044 void RegressionSM::done(int astatus)
00045 {
00046   if (pending_action) {
00047     pending_action->cancel();
00048     pending_action = 0;
00049   }
00050   set_status(astatus);
00051   if (pstatus) *pstatus = status;
00052   if (parent) parent->child_done(status);
00053 }
00054 
00055 void RegressionSM::run(int *apstatus)
00056 {
00057   pstatus = apstatus;
00058   run();
00059 }
00060 
00061 void RegressionSM::xrun(RegressionSM *aparent)
00062 {
00063   parent = aparent;
00064   parent->nwaiting++;
00065   run();
00066 }
00067 
00068 void RegressionSM::run_in(int *apstatus, ink_hrtime t)
00069 {
00070   pstatus = apstatus;
00071   SET_HANDLER(&RegressionSM::regression_sm_start);
00072   eventProcessor.schedule_in(this, t);
00073 }
00074 
00075 void RegressionSM::child_done(int astatus)
00076 {
00077   MUTEX_LOCK(l, mutex, this_ethread());
00078   ink_assert(nwaiting > 0);
00079   --nwaiting;
00080   set_status(astatus);
00081 }
00082 
00083 int RegressionSM::regression_sm_waiting(int  , void *data)
00084 {
00085   if (!nwaiting) {
00086     done(REGRESSION_TEST_NOT_RUN);
00087     delete this;
00088     return EVENT_DONE;
00089   }
00090   if (par || nwaiting > 1) {
00091     ((Event*)data)->schedule_in(REGRESSION_SM_RETRY);
00092     return EVENT_CONT;
00093   }
00094   run();
00095   return EVENT_DONE;
00096 }
00097 
00098 int RegressionSM::regression_sm_start(int , void * )
00099 {
00100   run();
00101   return EVENT_CONT;
00102 }
00103 
00104 RegressionSM *r_sequential(RegressionTest *t, RegressionSM* sm, ...)
00105 {
00106   RegressionSM *new_sm = new RegressionSM(t);
00107   va_list ap;
00108   va_start(ap, sm);
00109   new_sm->par = false;
00110   new_sm->rep = false;
00111   new_sm->ichild = 0;
00112   new_sm->nchildren = 0;
00113   new_sm->nwaiting = 0;
00114   while (0 != sm) {
00115     new_sm->children(new_sm->nchildren++) = sm;
00116     sm = va_arg(ap, RegressionSM*);
00117   }
00118   new_sm->n = new_sm->nchildren;
00119   va_end(ap);
00120   return new_sm;
00121 }
00122 
00123 RegressionSM *r_sequential(RegressionTest *t, int an, RegressionSM *sm)
00124 {
00125   RegressionSM *new_sm = new RegressionSM(t);
00126   new_sm->par = false;
00127   new_sm->rep = true;
00128   new_sm->ichild = 0;
00129   new_sm->nchildren = 1;
00130   new_sm->children(0) = sm;
00131   new_sm->nwaiting = 0;
00132   new_sm->n = an;
00133   return new_sm;
00134 }
00135 
00136 RegressionSM *r_parallel(RegressionTest *t, RegressionSM *sm, ...)
00137 {
00138   RegressionSM *new_sm = new RegressionSM(t);
00139   va_list ap;
00140   va_start(ap, sm);
00141   new_sm->par = true;
00142   new_sm->rep = false;
00143   new_sm->ichild = 0;
00144   new_sm->nchildren = 0;
00145   new_sm->nwaiting = 0;
00146   while (sm) {
00147     new_sm->children(new_sm->nchildren++) = sm;
00148     sm = va_arg(ap, RegressionSM*);
00149   }
00150   new_sm->n = new_sm->nchildren;
00151   va_end(ap);
00152   return new_sm;
00153 }
00154 
00155 RegressionSM *r_parallel(RegressionTest *t, int an, RegressionSM *sm)
00156 {
00157   RegressionSM *new_sm = new RegressionSM(t);
00158   new_sm->par = true;
00159   new_sm->rep = true;
00160   new_sm->ichild = 0;
00161   new_sm->nchildren = 1;
00162   new_sm->children(0) = sm;
00163   new_sm->nwaiting = 0;
00164   new_sm->n = an;
00165   return new_sm;
00166 }
00167 
00168 void RegressionSM::run()
00169 {
00170   
00171   {
00172     MUTEX_TRY_LOCK(l, mutex, this_ethread());
00173     if (!l || nwaiting > 1)
00174       goto Lretry;
00175     RegressionSM *x = 0;
00176     while (ichild < n) {
00177       if (!rep)
00178         x = children[ichild];
00179       else {
00180         if (ichild != n-1)
00181           x = children[(intptr_t)0]->clone();
00182         else
00183           x = children[(intptr_t)0];
00184       }
00185       if (!ichild) nwaiting++;
00186       x->xrun(this);
00187       ichild++;
00188       if (!par && nwaiting > 1)
00189         goto Lretry;
00190     }
00191   }
00192   nwaiting--;
00193   if (!nwaiting) {
00194     done(REGRESSION_TEST_NOT_RUN);
00195     delete this;
00196     return;
00197   }
00198 Lretry:
00199   SET_HANDLER(&RegressionSM::regression_sm_waiting);
00200   pending_action = eventProcessor.schedule_in(this, REGRESSION_SM_RETRY);
00201 }
00202 
00203 RegressionSM::RegressionSM(const RegressionSM &ao)
00204 {
00205   RegressionSM &o = *(RegressionSM*)&ao;
00206   t = o.t;
00207   status = o.status;
00208   pstatus = o.pstatus;
00209   parent = &o;
00210   nwaiting = o.nwaiting;
00211   nchildren = o.nchildren;
00212   for (intptr_t i = 0; i < nchildren; i++)
00213     children(i) = o.children[i]->clone();
00214   n = o.n;
00215   ichild = o.ichild;
00216   par = o.par;
00217   rep = o.rep;
00218   pending_action = o.pending_action;
00219   ink_assert(status == REGRESSION_TEST_INPROGRESS);
00220   ink_assert(nwaiting == 0);
00221   ink_assert(ichild == 0);
00222   mutex = new_ProxyMutex();
00223 }
00224 
00225 struct ReRegressionSM: public RegressionSM
00226 {
00227   virtual void run() {
00228     if (time(NULL) < 1) { 
00229       rprintf(t,"impossible");
00230       done(REGRESSION_TEST_FAILED);
00231     } else
00232       done(REGRESSION_TEST_PASSED);
00233   }
00234   ReRegressionSM(RegressionTest *at) : RegressionSM(at) {}
00235   virtual RegressionSM *clone() { return new ReRegressionSM(*this); }
00236   ReRegressionSM(const ReRegressionSM &o) {
00237     t = o.t;
00238   }
00239 };
00240 
00241 REGRESSION_TEST(RegressionSM)(RegressionTest *t, int , int *pstatus)
00242 {
00243   RegressionSM *top_sm = r_sequential(t, r_parallel(t, new ReRegressionSM(t), new ReRegressionSM(t), NULL_PTR),
00244                r_sequential(t, new ReRegressionSM(t), new ReRegressionSM(t), NULL_PTR),
00245                r_parallel(t, 3, new ReRegressionSM(t)), r_sequential(t, 3, new ReRegressionSM(t)),
00246                r_parallel(t, r_sequential(t, 2, new ReRegressionSM(t)),
00247                           r_parallel(t, 2, new ReRegressionSM(t)), NULL_PTR),
00248                NULL_PTR);
00249   top_sm->run(pstatus);
00250 }