source: Sophya/trunk/AddOn/TAcq/tmtacq.cc@ 3633

Last change on this file since 3633 was 3633, checked in by ansari, 16 years ago

Ajout gestion DMA avec deux cartes , Reza 25/05/2009

File size: 17.7 KB
RevLine 
[3537]1#include <iostream>
2
[3623]3#include "tmtacq.h"
[3537]4#include "racqumem.h"
5#include "racqurw.h"
[3623]6#ifndef NOPCIECARD
7#include "racquwbin.h"
[3629]8#include "dmamgrv3.h"
[3623]9#endif
[3537]10#include "racquproc.h"
11
[3623]12
[3537]13#include "pciewrap.h"
14#include "brpaqu.h"
15#include "minifits.h"
16
17#include "resusage.h"
18#include "ctimer.h"
19#include "timing.h"
20
21#include "tarrinit.h"
22#include "fiosinit.h"
23
24using namespace std;
25using namespace SOPHYA;
[3633]26
27
[3537]28//--------------------------------------------------------
[3623]29// Programme test acquisition BAORadio multi-thread
[3537]30// LAL - R. Ansari Juillet - 2008
[3633]31// M.Taurigna 2009
[3537]32//--------------------------------------------------------
[3633]33
34
35/* Fonction d'arret par Ctl<C> et ses pointeurs globaux */
36static DataSaver *pDs = NULL;
37static DataSaver *pDs2 = NULL;
38static PCIEReaderChecker *pPcierc = NULL;
39static PCIEReaderChecker *pPcierc2 = NULL;
40static PCIEReader *pPcier = NULL;
41static PCIEReader *pPcier2 = NULL;
42static DataProc2C *pPr = NULL;
43static DataProc2C *pPr2 = NULL;
44static DataProcFFT2C *pPrfft = NULL;
45static DataProcFFT2C *pPrfft2 = NULL;
46static RAcqMemZoneMgr *pMmgr = NULL;
47static RAcqMemZoneMgr *pMmgr2 = NULL;
48
[3623]49void Stop(int s)
50{
[3633]51 if (s == 9765) cout << " Stop after exception ..." << endl;
52 else printf("............. MAIN ... receive signal %d \n",s);
[3623]53 if (pPcierc != NULL) pPcierc->Stop();
[3633]54 if (pPcierc2 != NULL) pPcierc2->Stop();
[3623]55 if (pPcier != NULL) pPcier->Stop();
[3633]56 if (pPcier2 != NULL) pPcier2->Stop();
[3623]57 if (pPr !=NULL) pPr->Stop();
[3633]58 if (pPr2 !=NULL) pPr2->Stop();
[3623]59 if (pPrfft !=NULL) pPrfft->Stop();
[3633]60 if (pPrfft2 !=NULL) pPrfft2->Stop();
[3623]61 if (pDs != NULL) pDs->Stop();
[3633]62 if (pDs2 != NULL) pDs2->Stop();
[3623]63 if (pMmgr !=NULL) pMmgr->Stop();
[3633]64 if (pMmgr2 !=NULL) pMmgr2->Stop();
[3623]65
66}
[3633]67/* -------------------------------------------------------- */
[3537]68
[3633]69// Fonctions appelees par le main
70void Usage();
71int DecodeArgs(int narg, char* arg[]);
72void DecodeAcqMode();
73
74int MonoCardAcq();
75int MultiCardAcq();
76
77//------------------ Parametres de controle ----------------------------
78static string acqmode;
79static bool savesigfits = true;
80static BRDataFmtConv swapall = BR_Copy;
81static bool monothr = false;
82static string OutPathName;
83static bool singlecard = true;
84static int cardlist[4] = {1,1,1,1};
85static int card = 1;
86static unsigned int sizeFrame = 4096;
87static unsigned int nbFrameDMA = 32;
88static int NbFiles=1;
89static int NBlocPerFile=10;
90static int NMaxProc = 0; // Nombre de blocs traites par le thread de calcul
91static uint_4 nZones = 4; // Nombre de zones memoires
92static uint_4 nPaqZone = 128; // 128 Paquets / zone memoire - valeur par defaut
93static bool fg_hard_ctrlc = false;
94static uint_4 PaqSZ = 4096; // Taille de paquets
95 // uint_4 dmaSize = nbFrameDMA*PaqSZ ; // plantage
96static uint_4 dmaSize = 32*1024 ;
97static uint_4 patternSZ=0x400; // pas utilise avec la fibre
98static uint_4 NMaxBloc = 10;
99//---------------------------- FIN parametres de controle -----------------
100
101//-----------------------------------------------------------------------
102//-------------------- le programme principal ---------------------------
103//-----------------------------------------------------------------------
[3537]104int main(int narg, char* arg[])
[3623]105{
106
[3537]107 int rc = 0;
[3633]108 cout << " ============ BAORadio / Acquisition : tmtacq =================" << endl;
109 cout << " ===============================================================" << endl;
[3623]110 cout << " ========= " <<BAOR_ACQ_VER_STR <<BAOR_ACQ_VER <<" ===========" << endl;
111 cout << " ===============================================================" << endl;
112
[3633]113 int rcda = DecodeArgs(narg, arg);
114 if (rcda != 0) return 1;
115 InitTim();
116
117 // Initialisation
118 TArrayInitiator _arri;
119 FitsIOServerInitiator _fiosi;
120
121 try {
122 if (singlecard) rc = MonoCardAcq();
123 else rc = MultiCardAcq();
124 }
125 catch (MiniFITSException& exc) {
126 cerr << " tmtacq.cc catched MiniFITSException " << exc.Msg() << endl;
127 Stop(9765);
128 rc = 77;
129 }
130 catch (PCIEWException& exc) {
131 cerr << " tmtacq.cc catched MiniFITSException " << exc.Msg() << endl;
132 Stop(9765);
133 rc = 75;
134 }
135 catch (PThrowable& exc) {
136 cerr << " tmtacq.cc catched Exception " << exc.Msg() << endl;
137 Stop(9765);
138 rc = 76;
139 }
140 catch (std::exception& sex) {
141 cerr << "\n tmtacq.cc std::exception :"
142 << (string)typeid(sex).name() << "\n msg= "
143 << sex.what() << endl;
144 Stop(9765);
145 rc = 78;
146 }
147 catch (...) {
148 cerr << " tmtacq.cc : Catched ... exception " << endl;
149 Stop(9765);
150 rc = 79;
151 }
152 cout << "tmtacq[9] ----- END --- stopping acq program " << endl;
153 return rc;
154}
155
156
157/* --Nouvelle-Fonction-- */
158void Usage()
159{
160 cout << "\n Usage: tmtacq CardNum PaquetSize NFrameDMA NFiles NBlocPerFile \n"
161 << " NMaxProc DataDirPath [AcqMode] [MemZoneMgr][HardCtlC]" << endl;
162 cout << " - CardNum : PCI-Express card number (=1 OR 2 OR 1,2)" << endl;
[3623]163 cout << " - PaquetSize or FrameSize (=DATA+HDR+TRL_Size) " << endl;
164 cout << " - NFrameDMA = DMASize= NFrameDMA*1024 , 4KO<=MaxDMASize<=64 ko " << endl;
165 cout << " - NFiles = Number of data files produced " << endl;
166 cout << " - NBlocPerFile = Number of memory data bloc in one file " << endl;
167 cout << " - NMaxProc = Max number of memory data blocs processed (FFT ...) " << endl;
168 cout << " NMaxProc=0 -> No Processing " << endl;
169 cout << " - DataDirPath : Subdirectory of /Raid " << endl;
170 cout << " Pour la version du firmware qui ne swappe pas les paquets" << endl;
171 cout << " - AcqMode: = swapall , fft1c , fft2c, swh , nof , mxs , mono , monosw (default=std)" << endl;
172 cout << " swapall -> SwapAll+SaveData , swh->swap header only " << endl;
173 cout << " fft1c , ff2c -> reorder data for 1 channel/2channel FFT " << endl;
174 cout << " fft1cnof , ff2cnof -> reorder FFT data, but DONT write files " << endl;
175 cout << endl;
176 cout << " Pour la version du firmware qui swappe partiellement " << endl;
177 cout << " -AcqMode : swap32 ,fft1c32 , fft2c32,fft1cnof32 , fft2cnof32 " <<endl;
178 cout << " fft1c32 , fft2c32 -> reorder data for 1 channel/2channel FFT " << endl;
179 cout << " fft1cnof32 , ff2cnof32 -> reorder FFT data, but DONT write files " << endl << endl;
180 cout << endl;
181 cout << " Pour la version du firmware qui ne swappe plus " << endl;
182 cout << " -AcqMode : nosw,fft1cnosw , fft2cnosw" <<endl;
183 cout << " fft1cnosw , fft2cnosw -> reorder data for 1 channel/2channel FFT " << endl;
184 cout << " fft1cnofnosw , ff2cnofnosw -> reorder FFT data, but DONT write files " << endl << endl;
185
186
187 cout << " Option pour debug ou test performance swapp initial (std)" << endl ;
188 cout << " nof->Don't write signal fits files , mxs->swh+nof: swap header only + no fits " << endl;
189 cout << " mono->Test with a single thread PCIEReaderChecker " << endl;
190 cout << " monosw->Test with a single thread PCIEReaderChecker, But swap all packet " << endl;
191 cout << endl;
192 cout << " mononsw->Test with a single thread PCIEReaderChecker, But no swap paquet " << endl;
193 cout << endl;
[3633]194 cout << " - MemZoneMgr: nZones,NPaq =Number of Zones and number of paquet in each zone (Default=8,128) "
195 << endl;
[3623]196 cout << " -HardCtlC : Y y (direct interrpution by CtrlC ) default (no) " << endl;
[3633]197}
198
199/* --Nouvelle-Fonction-- */
200int DecodeArgs(int narg, char* arg[])
201{
202 if (narg < 8) {
203 Usage();
204 return 1;
[3623]205 }
[3633]206 acqmode = "std";
207 acqmode = arg[8];
208 savesigfits = true;
209 // BRDataFmtConv swapall = BR_SwapAll;
210 swapall = BR_Copy;
211 monothr = false;
212 DecodeAcqMode();
[3623]213
[3633]214 if (index(arg[1],',') != NULL) {
215 sscanf(arg[1],"%d,%d", cardlist, cardlist+1);
216 cout << " tmtacq[1]/MultiPCICard acquisition ... Cards= " << cardlist[0] << " ," << cardlist[1]
217 << " FrameSize=PaqSize=" << sizeFrame << endl;
218 singlecard = false;
219 }
220 else {
221 card = atoi(arg[1]);
222 cardlist[0] = cardlist[1] = card;
223 singlecard = true;
224 cout << "tmtacq[1]/MonoPCICard acquisition ... Card= " << card << " FrameSize=PaqSize=" << sizeFrame << endl;
225 }
226 sizeFrame = atoi(arg[2]);
227 nbFrameDMA = atoi(arg[3]);
228
229
230 NbFiles = atoi(arg[4]);
231 NBlocPerFile = atoi(arg[5]);
232 NMaxProc = atoi(arg[6]); // Nombre de blocs traites par le thread de calcul
233
234#ifdef NOPCIECARD
235 string OutPathName = string(arg[7])+"/";
236#else
237 string OutPathName =string("/Raid/")+arg[7]+"/";
238#endif
239 cout << " DataDirpath=" << OutPathName << " SwapMode=" << BRPaquet::FmtConvToString(swapall)
240 << " DataSaveMode=" << ((savesigfits)?"Yes/FitsFile":"NO") << endl;
241
242 char cmd[512];
243 if (singlecard) {
244 sprintf(cmd,"mkdir %s",OutPathName.c_str());
245 if (system(cmd) < 0) {
246 cout << "tmtacq/Error: Can not create subdirectory " << OutPathName << " -> exit" << endl;
247 return 2;
248 }
249 else cout << " tmtacq[1] - Executed command " << cmd << endl;
250 }
251 else {
252 sprintf(cmd,"mkdir %s",OutPathName.c_str());
253 if (system(cmd) < 0) {
254 cout << "tmtacq/Error: Can not create subdirectory " << OutPathName << " -> exit" << endl;
255 return 2;
256 }
257 else cout << " tmtacq[1] - Executed command " << cmd << endl;
258 sprintf(cmd,"mkdir %s/Card1",OutPathName.c_str());
259 if (system(cmd) < 0) {
260 cout << "tmtacq/Error: Can not create subdirectory " << OutPathName << " -> exit" << endl;
261 return 2;
262 }
263 else cout << " tmtacq[1] - Executed command " << cmd << endl;
264 sprintf(cmd,"mkdir %s/Card2",OutPathName.c_str());
265 if (system(cmd) < 0) {
266 cout << "tmtacq/Error: Can not create subdirectory " << OutPathName << " -> exit" << endl;
267 return 2;
268 }
269 else cout << " tmtacq[1] - Executed command " << cmd << endl;
270 }
271 nZones = 8; // Nombre de zones memoires
272 nPaqZone = 128; // 128 Paquets / zone memoire - valeur par defaut
273 if (narg > 9) {
274 int ia1, ia2;
275 sscanf(arg[9],"%d,%d", &ia1, &ia2);
276 nZones = ia1; nPaqZone = ia2;
277 }
278
279 fg_hard_ctrlc = false;
280
281 struct sigaction act;
[3537]282
[3633]283 if (narg > 10) // pour traiter eventuellement un arret brutal par CtlC mettre le 10eme arg a Y
284 if ((*arg[10]=='y')||(*arg[10]=='Y')) fg_hard_ctrlc=true;
285 if (!fg_hard_ctrlc) {
286 act.sa_handler=Stop;
287 sigaction(SIGINT,&act,NULL);
288 }
289
290 PaqSZ =sizeFrame; // Taille de paquets
291 // uint_4 dmaSize = nbFrameDMA*PaqSZ ; // plantage
292 dmaSize = nbFrameDMA*1024 ;
293 patternSZ=0x400; // pas utilise avec la fibre
294 NMaxBloc = NbFiles*NBlocPerFile;
295 cout << "tmtacq[2] - PaqSize = " << PaqSZ << " NbPaq/Zone=" << nPaqZone << " NZones=" << nZones << endl;
296 cout << " NbFiles=" << NbFiles << " NBloc/File=" << NBlocPerFile << " -> NMaxBloc=" << NMaxBloc << endl;
297 cout << "tmtacq[2] NbFrameDMA=" << nbFrameDMA << " DMASize=" << dmaSize << " bytes" << endl;
298 cout << "tmtacq[2] NMaxProc=" << NMaxProc << endl;
299
300 return 0;
301}
302
303/* --Nouvelle-Fonction-- */
304void DecodeAcqMode()
305{
[3623]306 if (acqmode == "swapall") swapall = BR_SwapAll;
307 if (acqmode == "fft1c") swapall = BR_FFTOneChan;
308 if (acqmode == "fft2c") swapall = BR_FFTTwoChan;
309 if (acqmode == "fft1cnof") { swapall = BR_FFTOneChan; savesigfits = false; }
310 if (acqmode == "fft2cnof") { swapall = BR_FFTTwoChan; savesigfits = false; }
311 if ((acqmode == "swh") || (acqmode == "mxs") || (acqmode == "mono") ) swapall = BR_SwapHDR;
312 if ((acqmode == "nof") || (acqmode == "mxs") || (acqmode == "mono")) savesigfits = false;
313 if (acqmode == "mono") { monothr = true; swapall = BR_SwapHDR;; }
314 if (acqmode == "monosw") { monothr = true; swapall = BR_SwapAll; }
315 if (acqmode == "mononsw") { monothr = true; swapall = BR_Copy; }
316
317 if (acqmode == "swap32") swapall = BR_Swap32 ;
318 if (acqmode == "fft1c32") swapall = BR_FFTOneChan32;
319 if (acqmode == "fft2c32") swapall = BR_FFTTwoChan32;
320 if (acqmode == "fft1cnof32") { swapall = BR_FFTOneChan32; savesigfits = false; }
321 if (acqmode == "fft2cnof32") { swapall = BR_FFTTwoChan32; savesigfits = false; }
322
323 if (acqmode == "nosw") swapall = BR_Copy ;
324 if (acqmode == "fft1cnosw") swapall = BR_FFTOneChanNoSwap;
325 if (acqmode == "fft2cnosw") swapall = BR_FFTTwoChanNoSwap;
326 if (acqmode == "fft1cnofnosw") { swapall = BR_FFTOneChanNoSwap; savesigfits = false; }
327 if (acqmode == "fft2cnofnosw") { swapall = BR_FFTTwoChanNoSwap; savesigfits = false; }
[3633]328}
[3623]329
[3633]330
331/* --Nouvelle-Fonction-- */
332int MonoCardAcq()
333{
334 Timer tm("tmtacq/MonoCard");
335
336 cout << " ---- tmtacq/ MonoCardAcq() ------------- " << endl;
[3623]337#ifdef NOPCIECARD
[3633]338 TestPCIWrapperNODMA pciw(PaqSZ);
339#else
340 DMAMgr dma1(card,patternSZ,dmaSize );
341 if (! dma1.StatusFibre() ) {
342 cout << " tmtacq[3] - fibre non accrochee -> exit " << endl;
343 throw PCIEWException(" Fibre non accrochee ");
[3623]344 }
[3633]345 else cout << " tmtacq[3] - fibre accrochee OK " << endl;
346 PCIEWrapper pciw(dma1);
347#endif
348 RAcqMemZoneMgr mmgr(nZones, nPaqZone, PaqSZ);
349 pMmgr =&mmgr;
[3623]350
[3633]351 if (monothr) {
352 cout << "tmtacq[4] single thread PCIE test PCIEReaderChecker ... ";
353 PCIEReaderChecker pcirc(pciw,dmaSize,PaqSZ ,mmgr, NMaxBloc, swapall);
354 pPcierc=&pcirc;
355 pcirc.start();
356 sleep(1);
357 pcirc.join();
358 cout << "tmtacq[5] - single thread PCIEReaderChecker finished " << endl;
359 tm.Split("Single Thread Finished");
360 mmgr.Print(cout);
361 return 0;
[3627]362 }
[3633]363 PCIEReader pcir(pciw,dmaSize,PaqSZ ,mmgr, NMaxBloc, swapall);
364 pPcier= &pcir;
365 DataSaver ds(mmgr, OutPathName, NbFiles, NBlocPerFile, savesigfits);
366 pDs= &ds;
367 //DataBinSaver ds(mmgr, OutPathName, NbFiles ,NBlocPerFile);
368 // DataProc1C pr(mmgr, OutPathName, nmean, stepproc, 100); Pour processer un canal
369 int stepproc = 2;
370 int nmean = nPaqZone*NBlocPerFile/stepproc;
371 DataProc2C pr(mmgr, OutPathName, nmean, stepproc, NMaxProc);
372 DataProcFFT2C prfft(mmgr, OutPathName, nmean, stepproc, NMaxProc);
373 tm.Split("Threads created");
374 cout << "tmtacq[4] - starting 3 threads pcir, ds, pr ... " << endl;
375 /*
376 char test[100];
377 cout << " <CR> to continue, x to exit ..." << endl;
378 gets(test); if (test[0] == 'x') return 9;
379 */
380 pcir.start();
381 ds.start();
382 if (NMaxProc>0) { // On ne demarre que si au moins NMaxProc>0
383 if (acqmode.substr(0,5)=="fft2c") { prfft.start(); pPrfft=&prfft;}
384 else { pr.start(); pPr=&pr;}
[3623]385 }
[3633]386 cout << "tmtacq[5] - waiting for threads to finish ... " << endl;
387 sleep(1);
388 pcir.join();
389 ds.join();
390 sleep(1);
391 mmgr.Stop();
392 if (NMaxProc>0) if ( pPr != NULL) pr.join();
393 if (NMaxProc>0) if ( pPrfft != NULL) prfft.join();
394 cout << "tmtacq[6] - threads finished " << endl;
395 tm.Split("Threads Finished");
396 mmgr.Print(cout);
397 return 0;
398}
[3627]399
[3623]400
[3633]401/* --Nouvelle-Fonction-- */
402int MultiCardAcq()
403{
404 Timer tm("tmtacq/MultiCard");
405
406 cout << " ---- tmtacq/ MultiCardAcq() ------------- " << endl;
407
[3623]408#ifdef NOPCIECARD
[3633]409 TestPCIWrapperNODMA pciw1(PaqSZ);
410 TestPCIWrapperNODMA pciw2(PaqSZ);
[3623]411#else
[3633]412 DMAMgr dma1(cardlist[0],patternSZ,dmaSize );
413 if (! dma1.StatusFibre() ) {
414 cout << " tmtacq[3] - fibre non accrochee Card" << cardlist[0] << " -> exit " << endl;
415 throw PCIEWException(" Fibre non accrochee 1");
416 }
417 else cout << " tmtacq[3] - fibre accrochee OK Card " << cardlist[0] << endl;
418
419 DMAMgr dma2(cardlist[1],patternSZ,dmaSize );
420 if (! dma1.StatusFibre() ) {
421 cout << " tmtacq[3] - fibre non accrochee Card" << cardlist[1] << " -> exit " << endl;
422 throw PCIEWException(" Fibre non accrochee 2");
423 }
424 else cout << " tmtacq[3] - fibre accrochee OK Card " << cardlist[1] << endl;
425
426 PCIEWrapper pciw1(dma1);
427 PCIEWrapper pciw2(dma2);
[3623]428#endif
[3633]429 RAcqMemZoneMgr mmgr1(nZones, nPaqZone, PaqSZ);
430 RAcqMemZoneMgr mmgr2(nZones, nPaqZone, PaqSZ);
431 pMmgr =&mmgr1;
432 pMmgr2 =&mmgr2;
[3623]433
[3633]434 if (monothr) {
435 cout << "tmtacq[4] single thread/Card PCIE test PCIEReaderChecker ... ";
436 PCIEReaderChecker pcirc1(pciw1,dmaSize,PaqSZ ,mmgr1, NMaxBloc, swapall);
437 PCIEReaderChecker pcirc2(pciw1,dmaSize,PaqSZ ,mmgr1, NMaxBloc, swapall);
438 pPcierc=&pcirc1;
439 pPcierc2=&pcirc2;
440 pcirc1.start();
441
442 sleep(1);
443 pcirc1.join();
444 pcirc2.join();
445
446 cout << "tmtacq[5] - single thread/Card PCIEReaderChecker finished " << endl;
447 tm.Split("Single Thread Finished");
448 mmgr1.Print(cout);
449 mmgr2.Print(cout);
450 return 0;
451 }
452 PCIEReader pcir1(pciw1,dmaSize,PaqSZ ,mmgr1, NMaxBloc, swapall);
453 pPcier= &pcir1;
454 PCIEReader pcir2(pciw2,dmaSize,PaqSZ ,mmgr2, NMaxBloc, swapall);
455 pPcier2= &pcir2;
456 char buff[32];
457 sprintf(buff, "Card%d", cardlist[0]);
458 string path1 = OutPathName + buff;
459 DataSaver ds1(mmgr1, path1, NbFiles, NBlocPerFile, savesigfits);
460 pDs= &ds1;
461 sprintf(buff, "Card%d", cardlist[1]);
462 string path2 = OutPathName + buff;
463 DataSaver ds2(mmgr2, path2, NbFiles, NBlocPerFile, savesigfits);
464 pDs2= &ds2;
465 //DataBinSaver ds(mmgr, OutPathName, NbFiles ,NBlocPerFile);
466 // DataProc1C pr(mmgr, OutPathName, nmean, stepproc, 100); Pour processer un canal
467 int stepproc = 2;
468 int nmean = nPaqZone*NBlocPerFile/stepproc;
469 DataProc2C pr1(mmgr1, path1, nmean, stepproc, NMaxProc);
470 DataProcFFT2C prfft1(mmgr1, path1, nmean, stepproc, NMaxProc);
471 DataProc2C pr2(mmgr2, path2, nmean, stepproc, NMaxProc);
472 DataProcFFT2C prfft2(mmgr2, path2, nmean, stepproc, NMaxProc);
473
474 tm.Split("Threads created");
475 cout << "tmtacq[4] - starting 3 threads pcir, ds, pr ... " << endl;
476 /*
477 char test[100];
478 cout << " <CR> to continue, x to exit ..." << endl;
479 gets(test); if (test[0] == 'x') return 9;
480 */
481 pcir1.start();
482 ds1.start();
483 pcir2.start();
484 ds2.start();
485 if (NMaxProc>0) { // On ne demarre que si au moins NMaxProc>0
486 if (acqmode.substr(0,5)=="fft2c") {
487 prfft1.start(); pPrfft=&prfft1;
488 prfft2.start(); pPrfft2=&prfft2;
[3623]489 }
[3633]490 else {
491 pr1.start(); pPr=&pr1;
492 pr2.start(); pPr2=&pr2;
[3623]493 }
[3537]494 }
[3633]495 cout << "tmtacq[5] - waiting for threads to finish ... " << endl;
496 sleep(1);
497 pcir1.join();
498 ds1.join();
499 sleep(1);
500 mmgr1.Stop();
501 mmgr2.Stop();
502 if (NMaxProc>0) {
503 if ( pPr != NULL) pr1.join();
504 if ( pPr2 != NULL) pr2.join();
505 if ( pPrfft != NULL) prfft1.join();
506 if ( pPrfft2 != NULL) prfft2.join();
[3537]507 }
[3633]508
509 cout << "tmtacq[6] - threads finished " << endl;
510 tm.Split("Threads Finished");
511 mmgr1.Print(cout);
512 mmgr2.Print(cout);
513 return 0;
[3537]514}
Note: See TracBrowser for help on using the repository browser.