#include "sopnamsp.h" #include "machdefs.h" #include "JTC/JTC.h" #include #include #include // Include file pour PI #include "pisysdep.h" #include PIAPP_H #include PIMENU_H #include PISTDWDG_H #include PIWIN_H #include PIPERIODIC_H #include "picons.h" // Include file Sophya (TArray) #include "tarrinit.h" #include "array.h" #include "timing.h" using namespace std; // .......................................................... // Programme interactive de test des threads JThreadsC++ // avec les arrays de Sophya et PI // R. Ansari LAL-IN2P3/CNRS 05/2000 // .......................................................... // ................... MtxComputer ................... // A thread class for doing matrix computation class PIJTApp; class MtxComputer : public JTCThread // { public: MtxComputer(PIJTApp * japp, PIScale * sc, int id, int sz, int nloop); virtual void run(); protected: int id_; int sz_; int nloop_; PIJTApp * japp_; PIScale * sc_; }; // ................... CPUTimer ................... // Periodic class for CPU and elapsed time counting class CPUTimer : public PIPeriodic { public: CPUTimer(PIJTApp * app); virtual void DoPeriodic(); protected: PIJTApp * japp; int dt; }; // ................... PIJTApp ................... // La classe application class PIJTApp : public PIApplication , public JTCThread { // class PIJTApp : public PIApplication { // Pas oblige d'en faire un Thread public: PIJTApp(int narg, char* arg[]); ~PIJTApp(); virtual void Process(PIMessage msg, PIMsgHandler* sender, void* data=NULL); virtual void UpdateCPUTime(); virtual void run(); // // virtual void Run(); Si pas thread JTCMonitor & getMonitor(); // for synchronization protected: PIMenu * m[3]; PIScale *sc[2]; PILabel *tlab[2]; PILabel *cputlab; PIConsole* cons; // CPU and elapsed time CPUTimer tm; clock_t cput0; time_t t0; // The computing threads JTCThreadHandle thr[2]; // // for synchronization with other threads JTCMonitor amon; // int syn_cntrl; }; // ......................................................... // ............. PIJTApp implementation ................. // ......................................................... PIJTApp::PIJTApp(int narg, char* arg[]) : PIApplication(600, 400, narg, arg) , tm(this) // 200 ms timer { if (narg < 3) throw ParmError("PIJTApp::PIJTApp() narg<3 !"); m[0] = new PIMenu(Menubar(),"Fichier"); m[0]->AppendItem("Start", 10101); m[0]->AppendItem("Exit", 10110); AppendMenu(m[0]); m[1] = new PIMenu(Menubar(),"Thread-1"); m[1]->AppendItem("Suspend", 10201); m[1]->AppendItem("Resume", 10202); m[1]->AppendItem("Stop", 10203); AppendMenu(m[1]); m[2] = new PIMenu(Menubar(),"Thread-2"); m[2]->AppendItem("Suspend", 10301); m[2]->AppendItem("Resume", 10302); m[2]->AppendItem("Stop", 10303); AppendMenu(m[2]); cputlab = new PILabel(MainWin(), "CPUTime", 590, 30, 5, 5); cputlab->SetBorderWidth(1); tlab[0] = new PILabel(MainWin(), "Thr-1", 50, 30, 10, 40); sc[0] = new PIScale(MainWin(), "Sc-Thr-1", 510, kSDirLtoR, 220, 40, 70, 40); sc[0]->SetValue(0); tlab[1] = new PILabel(MainWin(), "Thr-2", 50, 30, 300, 40); sc[1] = new PIScale(MainWin(), "Sc-Thr-2", 520, kSDirLtoR, 220, 40, 360, 40); sc[1]->SetValue(0); // Creating the console and redirecting output cons = new PIConsole(MainWin(), "PIConsole", 700, 500, 80, 600, 315, 0, 85, true ); cons->SetBinding(PIBK_fixed, PIBK_fixed, PIBK_fixed, PIBK_fixed); RedirectOutStream(cons); //RedirectErrStream(cons); // Creating matrix Computing thread int nloop = atoi(arg[1]); int size = atoi(arg[2]); thr[0] = new MtxComputer(this, sc[0], 0, size, nloop); thr[1] = new MtxComputer(this, sc[1], 1, size, nloop); cput0 = clock(); t0 = time(NULL); tm.Start(); // We start our cpu timer syn_cntrl = 0; // Normal event loop } PIJTApp::~PIJTApp() { int k; for(k=0; k<3; k++) delete m; for(k=0; k<2; k++) { delete tlab[k]; delete sc[k]; } delete cputlab; delete cons; } void PIJTApp::UpdateCPUTime() { clock_t cput; time_t elt; time_t tm; struct tm * stm; elt = time(&tm); stm = localtime(&tm); cput = clock(); float tcal = ( (float)(cput) - (float)(cput0) ) / (float)(CLOCKS_PER_SEC); float etm = elt - t0; float percen = (elt > t0) ? (tcal*100.)/etm : 0.; char buff[192]; sprintf(buff, "%02d:%02d:%02d CPUTime= %g sec Elapsed= %g sec (%g %%)", stm->tm_hour, stm->tm_min, stm->tm_sec, tcal, etm, percen); string s = buff; cputlab->SetLabel(s); } JTCMonitor & PIJTApp::getMonitor() { syn_cntrl++; return amon; } void PIJTApp::run() // void PIJTApp::Run() Si pas thread { XEvent evt; int szx, szy, szf; XtAppContext * appctx = PIXtAppCtx(szx, szy, szf); // Pour appeler FinishCreate() des objets dans la fenetre principale if (mStop) { // C'est la premiere fois topwdg->SetSize(MBCont()->XSize(), MBCont()->YSize()); MBCont()->FinishCreate(); } else mStop = true; // On rerentre apres un stop cout << "DBG-PIJTApp::run/Run Starting event loop " << endl; try { JTCSynchronized sync(amon); // synchronized block while (mStop) { while (syn_cntrl > 0) { amon.wait(); // syn_cntrl = 0; } XtAppNextEvent(*appctx, &evt); XtDispatchEvent(&evt); } } catch (JTCException const & e) { // cerr << "PIJTApp::run() Catched JTCException Msg= " << e.getMessage() << endl; } catch (JTCThreadDeath const & e) { // cerr << "PIJTApp::run() Catched JTCThreadDeath exception ! " << endl; } catch (...) { cerr << "PIJTApp::run() Catched ... exception " << endl; } } void PIJTApp::Process(PIMessage msg, PIMsgHandler* sender, void* data) { int num; try { switch(UserMsg(msg)) { case 10101 : // starting computing threads thr[0]->start(); // thr[1]->start(); // break; case 10110 : // starting computing threads RedirectOutStream(NULL); RedirectErrStream(NULL); cout << " PIJTApp::Process() Waiting for threads to terminate ... " << endl; thr[0]->join(); // thr[1]->join(); // Stop(); break; case 10201 : case 10301 : num = (UserMsg(msg)-10201)/100; thr[num]->suspend(); // break; case 10202 : case 10302 : num = (UserMsg(msg)-10202)/100; thr[num]->resume(); // break; case 10203 : case 10303 : num = (UserMsg(msg)-10203)/100; thr[num]->stop(); // break; } } catch (JTCException const & e) { // cerr << "PIJTApp::Process() Catched JTCException Msg= " << e.getMessage() << endl; } catch (...) { cerr << "PIJTApp::Process() Catched ... exception " << endl; } } // ......................................................... // ............. CPUTimer implementation ................. // ......................................................... CPUTimer::CPUTimer(PIJTApp * app) : PIPeriodic(1) { japp = app; dt = -1; SetIntervalms(200); // 200 ms interval timer } void CPUTimer::DoPeriodic() { dt++; if ((dt == 0) || (dt >= 5)) { japp->UpdateCPUTime(); dt = 0; } } // ......................................................... // ............. MtxComputer implementation ............... // ......................................................... // A global monitor for print synchronisation JTCMonitor prtmon; // MtxComputer::MtxComputer(PIJTApp * japp, PIScale * sc, int id, int sz, int nloop) { id_ = id; sz_ = sz; nloop_ = nloop; japp_ = japp; sc_ = sc; } void MtxComputer::run() { int n = sz_; double seuil = 1.e-6; Matrix id; id = IdentityMatrix(1.,n); double gmax = -1.e99; double gmin = 1.e99; int npb = 0; // Loop creating a random matrix, inverting it // and checking the result for(int k=0; k max) max = diff(i,j); if (fabs(x) > seuil) nerr++; } if (min < gmin) gmin = min; if (max > gmax) gmax = max; if (nerr > 0) npb++; { // Synchronized writing to cout stream JTCSynchronized sync(prtmon); // cout << " ------- Thread[" << id_ << "] K= " << k << " NErr = " << nerr << endl; cout << " Min(Diff) = " << min << " Max(Diff) = " << max << endl; if (k == nloop_-1) { double frac = (double)npb*100./(double)nloop_; cout << " ...... Thread[" << id_ << "] End NPb= " << npb << " / NTot= " << nloop_ << " ( = " << frac << " %) " << endl; cout << " GMin(Diff) = " << gmin << " GMax(Diff) = " << gmax << endl; cout << " ..................................................... " << endl; } } { // Synchronized updating of Scale Widget JTCMonitor & amon = japp_->getMonitor(); JTCSynchronized sync(amon); // // The event loop should be stopped until the end of the block int percentage = 100*(k+1)/nloop_; sc_->SetValue(percentage); amon.notify(); // } } catch (PException const & e) { cerr << "MtxComputer Catched PException in Thread(" << (string)getName() << ") Msg= " << e.Msg() << endl; } catch (JTCException const & e) { // cerr << "MtxComputer Catched JTCException in Thread(" << (string)getName() << ") Msg= " << e.getMessage() << endl; } } } // ......................................................... // ................... The main program .................... // ......................................................... int main(int narg, char* arg[]) { if (narg < 3) { cout << " jtcpitarr - JThreadsC++/PI+Sophya::TArray Test \n " << " ... Usage jtcpitarr NLoop MtxSize [-JTCss ... \n" << " NLoop=10...10^4 MtxSize=10...10^3 \n" << endl; exit(0); } InitTim(); // Initializing the CPU timer int nloop = atoi(arg[1]); int size = atoi(arg[2]); cout << " ::::: jtcpitarr - JThreadsC++/PI+Sophya::TArray Test ::::: \n" << " NLoop= " << nloop << " MtxSize= " << size << endl; try { SophyaInit(); // Sophya Initialization JTCInitialize iniJTC(narg, arg); // Initialize library JTCThreadHandle t = new PIJTApp(narg, arg); // t->start(); // - starting event loop t->join(); // Waiting for thread to end // PIJTApp * t = new PIJTApp(narg, arg); Si pas thread // t->Run(); Si pas thread } catch (PThrowable const & e) { cerr << " Catched PThrowable in main Msg= " << e.Msg() << endl; } catch (JTCException const & e) { // cerr << " Catched JTCException in main Msg= " << e.getMessage() << endl; } catch(...) { cerr << " Catched ... exception in main " << endl; } PrtTim("End of jtcpitarr"); }