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

Last change on this file since 3640 was 3639, checked in by cmv, 16 years ago

ajout des #include C pour compil sur dernieres versions gcc/g++, cmv 27/05/2009

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