Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages

EchoTestThread.cxx

00001 // Multi-threaded version of a test program to send a single ECHO primitive
00002 
00003 #include <iostream>
00004 using namespace std;
00005 
00006 #include <ctype.h>
00007 
00008 #include "RodModule.h"
00009 
00010 #include "primParams.h"
00011 #include "RCCVmeInterface.h"
00012 #include "parameters.h"
00013 #include "PPBuffer.h"
00014 #include "PPThread.h"
00015 #include "PPThreadAttr.h"
00016 #include "PPMutex.h"
00017 #include "PPCondition.h"
00018 
00038 using namespace SctPixelRod;
00039  
00040 class ParamList
00041 {
00042 public:
00043   ParamList(){m_finished = false;};
00044   ParamList(RodModule* rod, PPBuffer<unsigned long>* replyBuffer, PPBuffer<char>* textBuffer,
00045              PPBuffer<char>* errBuffer, PPMutex* coutMutex){
00046     m_rod = rod;
00047     m_replyBuffer = replyBuffer;
00048     m_textBuffer = textBuffer;
00049     m_errBuffer = errBuffer;
00050     m_coutMutex = coutMutex;
00051     m_finished = false;
00052   };
00053   ParamList( const ParamList&){};
00054   ParamList& operator=(const ParamList&){};
00055   ~ParamList(){};
00056   
00057   void setRod(RodModule* rod) {m_rod = rod; return;};
00058   void setReplyBuffer(PPBuffer<unsigned long>* replyBuffer)
00059                          {m_replyBuffer=replyBuffer; return;};
00060   void setTextBuffer(PPBuffer<char>* textBuffer)
00061                          {m_textBuffer=textBuffer; return;};
00062   void setErrBuffer(PPBuffer<char>* errBuffer)
00063                          {m_errBuffer=errBuffer; return;};
00064   void setCoutMutex(PPMutex* coutMutex) {m_coutMutex = coutMutex; return;};
00065   void setFinished(bool finished) {m_finished = finished; return;};
00066   RodModule* getRod() {return m_rod;};
00067   PPBuffer<unsigned long>* getReplyBuffer() {return m_replyBuffer;}
00068   PPBuffer<char>* getTextBuffer() {return m_textBuffer;}
00069   PPBuffer<char>* getErrBuffer() {return m_errBuffer;}
00070   PPMutex* getCoutMutex() {return m_coutMutex;}
00071   bool getFinished() {return m_finished;};
00072   
00073 private:
00074   RodModule* m_rod;
00075   PPBuffer<unsigned long>* m_replyBuffer;
00076   PPBuffer<char>* m_textBuffer;
00077   PPBuffer<char>* m_errBuffer;
00078   PPMutex* m_coutMutex;
00079   bool m_finished;
00080 };
00081 
00082 void *bkgStart(void *arg) {
00083 
00089   long myTextLength;                            // Actual length of text message
00090   TEXT_BUFFER_TYPE myTextType;                  // Buffer type for latest message
00091   
00092 // Create a buffer for temporary storage of text messages
00093   char * myTextBuffer = new char[TEXT_BUFF_SIZE];
00094   PrimState returnPState;
00095   TextBuffState returnTState;
00096   
00097 // Get buffer addresses
00098   ParamList* myParamList;
00099   myParamList = static_cast<ParamList*>(arg);
00100   RodModule* rod0 = myParamList->getRod();
00101   PPBuffer<unsigned long>* userBuffer = myParamList->getReplyBuffer();
00102   PPBuffer<char>* textBuffer = myParamList->getTextBuffer();
00103 
00104 // Start of idle loop
00105   while (1) {
00106     do {
00107       if (myParamList->getFinished()) break;
00108       returnPState = rod0->primHandler();
00109       returnTState = rod0->textHandler();
00110       if (returnTState == TEXT_RQ_SET) {
00111         do {
00112           returnTState = rod0->textHandler();
00113         } while (returnTState != TEXT_READOUT);
00114         rod0->getTextBuffer(myTextBuffer, myTextLength, myTextType);
00115         rod0->clearTextBuffer();
00116         rod0->sleep(50);
00117         textBuffer->fillBuffer(myTextBuffer, myTextLength);
00118       }
00119     } while (returnPState != PRIM_EXECUTING); 
00120     do {
00121       try {
00122         returnPState = rod0->primHandler();
00123       }
00124       catch (RodException &r) {
00125       cerr << r.getDescriptor() <<", " << r.getData1() << ", " << r.getData2()
00126                << '\n';
00127       }
00128     } while (returnPState != PRIM_WAITING); 
00129   
00130 // Retrieve output buffer
00131     RodOutList* outList = rod0->getOutList();
00132     UINT32 outLength = UINT32(outList->getLength());
00133     unsigned long* outBody = outList->getBody();
00134   
00135 // Copy to user buffer
00136     userBuffer->fillBuffer(outBody, outLength);
00137      
00138 // end of idle loop
00139     if (!myParamList->getFinished()) break;
00140   };
00141   
00142   delete [] myTextBuffer;
00143   return 0;
00144   
00145 }
00146 
00147 void* errStart(void *arg) {
00148 
00155 using namespace SctPixelRod;
00156 
00157 // Get buffer address
00158   ParamList* myParamList;
00159   myParamList = static_cast<ParamList*>(arg);
00160   PPBuffer<char>* errBuffer = myParamList->getErrBuffer();
00161 
00162 // loop waiting for buffer to be filled, then print it out
00163   while (1) {
00164     errBuffer->waitForFilled();
00165     long totItems = errBuffer->getTotItems();
00166     if (totItems > 0) {
00167       char* errArray = new char[totItems];
00168       errBuffer->dumpBuffer(errArray, totItems);
00169       for (int i=0; i<totItems; i++) cerr << errArray[i];
00170       delete [] errArray;
00171     }
00172     if (myParamList->getFinished()) break;
00173   } 
00174   return 0;
00175 }
00176 
00177 void* textStart(void *arg) {
00178 
00186 using namespace SctPixelRod;
00187 
00188 // Get buffer address
00189   ParamList* myParamList;
00190   myParamList = static_cast<ParamList*>(arg);
00191   PPBuffer<char>* textBuffer = myParamList->getTextBuffer();
00192   PPMutex* coutMutex = myParamList->getCoutMutex();
00193   
00194 // loop waiting for buffer to be filled, then print it out
00195   while (1) {
00196     textBuffer->waitForFilled();
00197     long totItems = textBuffer->getTotItems();
00198     if (totItems > 0) {
00199       char* textArray = new char[totItems];
00200       textBuffer->dumpBuffer(textArray, totItems);
00201       coutMutex->lock();
00202       for (int i=0; i<totItems; i++) cout << textArray[i];
00203       coutMutex->unlock();
00204       delete [] textArray;
00205     }
00206     if (!myParamList->getFinished()) break;
00207   }
00208   return 0;
00209 }
00210 
00211 void* userStart(void *arg) {
00212 
00218 using namespace SctPixelRod;
00219 
00220 // Get buffer addresses
00221   ParamList* myParamList;
00222   myParamList = static_cast<ParamList*>(arg);
00223   PPBuffer<unsigned long>* userBuffer = myParamList->getReplyBuffer();
00224   PPMutex* coutMutex = myParamList->getCoutMutex();
00225 
00226 // loop waiting for buffer to be filled, then fetch it
00227   while (1) {
00228     userBuffer->waitForFilled();
00229     UINT32 outLength = userBuffer->getTotItems();
00230     if (outLength > 0) {
00231       unsigned long* outBody = new unsigned long[outLength];
00232       userBuffer->dumpBuffer(outBody, outLength);
00233 
00234 // Print results (User processing of outList)
00235       UINT32 outIndex = UINT32(outBody[1]);
00236       UINT32 outNumPrims = outBody[2];
00237       UINT32 outPrimVersion = outBody[3];
00238       coutMutex->lock();
00239       cout << "outLength = " << outLength << ", outIndex = " << outIndex << 
00240           ", outNumPrims = " << outNumPrims << ", outPrimVersion = " << 
00241           outPrimVersion <<'\n';
00242       int outPtr = 4;
00243       for (unsigned int j=0; j<outNumPrims; j++) {
00244         UINT32 primLength = outBody[outPtr++];
00245         UINT32 primIndex = outBody[outPtr++];
00246         UINT32 primId = outBody[outPtr++];
00247         UINT32 primVersion = outBody[outPtr++];
00248         cout << "primLength = " << primLength << ", primIndex = " << primIndex << 
00249             ", primId = " << primId << ", primVersion = " << primVersion << '\n';
00250         cout << "ECHO data: ";
00251         hex(cout);
00252         for (unsigned int i=0; i<primLength-4; i++) {
00253           cout.width(8);
00254           cout << outBody[i+outPtr] <<" ";
00255           if (0 == (i+1)%8) cout << endl; 
00256         };
00257         if (0 != (primLength-4)%8) cout << endl;
00258         dec(cout);
00259       };
00260       coutMutex->unlock();
00261     }
00262     if (!myParamList->getFinished()) break;
00263   }
00264   return 0;
00265 }
00266 
00267 int main(int argc, char *argv[]) {
00268 
00281 using namespace SctPixelRod;
00282 
00283   const unsigned long mapSize=0xc00040;         // VME map size 
00284   RodPrimList primList(1);                      // Primitive List
00285   long numSlaves = 4;
00286 
00287   std::string fileName(""), option;
00288   int slot = -1;
00289   unsigned long baseAddress;
00290 
00291   if (argc > 1) {
00292     for (int i=1; i<argc; i++) {
00293       option = argv[i];
00294       if (option[0] != '-') break;
00295       switch (option[1]) {
00296         case 's': {
00297           slot = atoi(option.substr(2).c_str());
00298           break;
00299         }
00300         default: {
00301           break;
00302         }
00303       }
00304     }
00305   }
00306 
00307 // Prompt for slot number
00308   if (slot < 0 ) {
00309     cout << "Enter slot number (decimal):"; 
00310     cin >> slot;
00311     while ((slot < 1) || (slot > 21)) {
00312       cout << "Slot number out or range [1:21], re-enter: ";
00313       cin >> slot;
00314     }
00315   }
00316   baseAddress = slot << 24;
00317 
00318 // Create VME interface
00319   RCCVmeInterface *vme1 = new RCCVmeInterface();
00320   
00321 // Create RodModule and initialize it
00322   RodModule* rod0 = new RodModule(baseAddress, mapSize, *vme1, numSlaves);
00323   try{
00324     rod0->initialize();
00325   }
00326   catch (HpiException &h) {
00327     hex(cout);
00328     cerr << h.getDescriptor() << '\n';
00329     cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " << 
00330             h.getReadAddr() << '\n';
00331     dec(cout);
00332   };
00333 
00334 // Create shared buffers and buffer list
00335   PPBuffer<char> textBuffer(1024);
00336   PPBuffer<unsigned long> userBuffer(1024);
00337   PPBuffer<char> errBuffer(1025);
00338   PPMutex bkgMutex, errMutex, textMutex, userMutex;
00339   PPMutex coutMutex;
00340   ParamList myParamList;
00341   myParamList.setRod(rod0);
00342   myParamList.setTextBuffer(&textBuffer);
00343   myParamList.setReplyBuffer(&userBuffer);
00344   myParamList.setErrBuffer(&errBuffer);
00345   myParamList.setCoutMutex(&coutMutex);
00346   
00347 // Start background, error, text, and user threads, waiting for them to start before proceeding
00348   PPThreadAttr defaultAttr;
00349 
00350   PPThread bkgThread(&defaultAttr, bkgStart, &myParamList);
00351 
00352   PPThread errThread(&defaultAttr, errStart, &myParamList);
00353 
00354   PPThread textThread(&defaultAttr, textStart, &myParamList);
00355 
00356   PPThread userThread(&defaultAttr, userStart, &myParamList);
00357 
00358 // Create and Send a simple ECHO primitive
00359   long dataLength;
00360   coutMutex.lock();
00361   cout << "Enter number of data words: ";
00362   cin >> dataLength;
00363   coutMutex.unlock();
00364   long* echoData = new long[dataLength];
00365   for (long i=0; i<dataLength; i++) {
00366     echoData[i] = 0xbeef0000 | i;
00367   }
00368   RodPrimitive* echo = new RodPrimitive(dataLength+4, 1, ECHO, R_ECHO, echoData);
00369   primList.insert(primList.begin(), *echo);
00370   try {
00371     primList.bufferBuild();
00372   }
00373   catch (PrimListException &p) {
00374     cerr << p.getDescriptor() << " ";
00375     cerr << p.getData1() << ", " << p.getData2() << "\n";
00376   };
00377   try {
00378     rod0->sendPrimList(&primList);
00379   }
00380   catch (HpiException &h) {
00381     hex(cout);
00382     cerr << h.getDescriptor() << '\n';
00383     cerr << "calcAddr: " << h.getCalcAddr() << ", readAddr: " << 
00384             h.getReadAddr() << '\n';
00385     dec(cout);
00386   };
00387   delete [] echoData;
00388   
00389   
00390   char reply;
00391   coutMutex.lock();
00392   cout << "Press any key followed by <enter> to finish: ";
00393   cin >> reply;
00394   coutMutex.unlock();
00395  
00396 // Clean up: clear primList, delete primitive, and the outList
00397   primList.clear();
00398   delete echo;
00399   rod0->deleteOutList();
00400 
00401 // Flush buffers, which sets BUFFER_FILLED condition variable  
00402   myParamList.setFinished(true);
00403   userBuffer.close();
00404   textBuffer.close();
00405   errBuffer.close();
00406    
00407 // Delete the ROD and VME objects before exiting
00408   delete rod0;
00409   delete vme1;
00410 
00411   return 0;  
00412 }

Generated on Thu Dec 15 21:14:26 2005 for SCT DAQ/DCS Software - C++ by doxygen 1.3.5