1 // Created on: 1995-02-23
2 // Created by: Remi LEQUETTE
3 // Copyright (c) 1995-1999 Matra Datavision
4 // Copyright (c) 1999-2012 OPEN CASCADE SAS
6 // The content of this file is subject to the Open CASCADE Technology Public
7 // License Version 6.5 (the "License"). You may not use the content of this file
8 // except in compliance with the License. Please obtain a copy of the License
9 // at http://www.opencascade.org and read it completely before using this file.
11 // The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
12 // main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
14 // The Original Code and all software distributed under the License is
15 // distributed on an "AS IS" basis, without warranty of any kind, and the
16 // Initial Developer hereby disclaims all such warranties, including without
17 // limitation, any warranties of merchantability, fitness for a particular
18 // purpose or non-infringement. Please see the License for the specific terms
19 // and conditions governing the rights and limitations under the License.
22 #include <Standard_Macro.hxx>
23 #include <Standard_Stream.hxx>
24 #include <Standard_SStream.hxx>
27 #include <Draw_Appli.hxx>
28 #include <Draw_Printer.hxx>
30 #include <Message.hxx>
31 #include <Message_Messenger.hxx>
32 #include <OSD_MemInfo.hxx>
38 #if defined(HAVE_TIME_H) || defined(WNT)
47 # include <sys/resource.h>
48 # ifdef HAVE_STRINGS_H
53 extern Standard_Boolean Draw_Batch;
61 #elif defined (HAVE_LIMITS_H)
69 static clock_t MDTV_CPU_LIMIT; // Cpu_limit in Sec.
70 static clock_t MDTV_CPU_CURRENT; // cpu time already used at last
71 // cpulimit call. (sec.)
72 //#define strcasecmp strcmp Already defined
73 #define RLIM_INFINITY 0x7fffffff
76 #include <Draw_Chronometer.hxx>
77 #include <OSD_MAllocHook.hxx>
78 #include <OSD_Chronometer.hxx>
80 #if defined (__hpux) || defined ( HPUX )
81 #define RLIM_INFINITY 0x7fffffff
87 //=======================================================================
89 //=======================================================================
91 extern Standard_Boolean Draw_Chrono;
93 static Standard_Integer chronom(Draw_Interpretor& di,
94 Standard_Integer n,const char** a)
96 if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) {
98 Draw_Chrono = !Draw_Chrono;
100 Draw_Chrono = (*a[1] == '1');
102 if (Draw_Chrono) di << "Chronometers activated."<<"\n";
103 else di << "Chronometers desactivated."<<"\n";
106 Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
107 Handle(Draw_Chronometer) C;
109 C = Handle(Draw_Chronometer)::DownCast(D);
112 C = new Draw_Chronometer();
113 Draw::Set(a[1],C,Standard_False);
119 if (!strcasecmp(a[2],"reset"))
121 if (!strcasecmp(a[2],"start"))
123 if (!strcasecmp(a[2],"stop"))
125 if (!strcasecmp(a[2],"show"))
132 static Standard_Integer dchronom(Draw_Interpretor& I,
133 Standard_Integer n,const char** a)
135 if ((n == 1) || (*a[1] == '0') || (*a[1] == '1')) {
137 Draw_Chrono = !Draw_Chrono;
139 Draw_Chrono = (*a[1] == '1');
141 if (Draw_Chrono) I << "Chronometers activated."<<"\n";
142 else I << "Chronometers desactivated."<<"\n";
145 Handle(Draw_Drawable3D) D = Draw::Get(a[1]);
146 Handle(Draw_Chronometer) C;
148 C = Handle(Draw_Chronometer)::DownCast(D);
151 C = new Draw_Chronometer();
152 Draw::Set(a[1],C,Standard_False);
158 if (!strcasecmp(a[2],"reset"))
160 if (!strcasecmp(a[2],"start"))
162 if (!strcasecmp(a[2],"stop"))
164 if (!strcasecmp(a[2],"show")) {
176 //=======================================================================
179 //=======================================================================
181 static Standard_Integer ifbatch(Draw_Interpretor& DI, Standard_Integer , const char** )
191 //=======================================================================
194 //=======================================================================
196 extern Standard_Boolean Draw_Spying;
197 extern filebuf Draw_Spyfile;
199 static Standard_Integer spy(Draw_Interpretor& di, Standard_Integer n, const char** a)
202 Draw_Spyfile.close();
203 Draw_Spying = Standard_False;
205 if (!Draw_Spyfile.open(a[1],ios::out)) {
206 di << "Cannot open "<<a[1]<<" for writing"<<"\n";
209 Draw_Spying = Standard_True;
214 //=======================================================================
217 //=======================================================================
219 static Standard_Integer Draw_wait(Draw_Interpretor& , Standard_Integer n, const char** a)
221 Standard_Integer w = 10;
224 time_t ct = time(NULL) + w;
225 while (time(NULL) < ct) {};
229 //=======================================================================
230 //function : cpulimit
232 //=======================================================================
234 static unsigned int __stdcall CpuFunc (void * param)
240 Standard_Real anUserSeconds, aSystemSeconds;
241 OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
242 aCurrent = clock_t(anUserSeconds + aSystemSeconds);
244 if ((aCurrent - MDTV_CPU_CURRENT) >= MDTV_CPU_LIMIT)
246 printf ("CpuFunc : Fin sur Cpu Limit \n");
255 static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a)
259 rlp.rlim_max = RLIM_INFINITY;
261 rlp.rlim_cur = RLIM_INFINITY;
263 rlp.rlim_cur = atoi(a[1]);
266 status=setrlimit(RLIMIT_CPU,&rlp);
268 di << "status cpulimit setrlimit : " << status << "\n";
272 static int aFirst = 1;
274 unsigned int __stdcall CpuFunc (void *);
278 MDTV_CPU_LIMIT = RLIM_INFINITY;
281 MDTV_CPU_LIMIT = atoi (a[1]);
282 Standard_Real anUserSeconds, aSystemSeconds;
283 OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
284 MDTV_CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds);
286 if (aFirst) // Launch the thread only at the 1st call.
289 _beginthreadex (NULL, 0, CpuFunc, NULL, 0, &aThreadID);
298 //=======================================================================
299 //function : mallochook
301 //=======================================================================
303 static Standard_Integer mallochook(Draw_Interpretor& di, Standard_Integer n,
309 usage: mallochook cmd\n\
310 where cmd is one of:\n\
311 set [<op>] - set callback to malloc/free; op is one of the following:\n\
312 0 - set callback to NULL,\n\
313 1 - set callback OSD_MAllocHook::CollectBySize (default)\n\
314 2 - set callback OSD_MAllocHook::LogFileHandler\n\
315 reset - reset the CollectBySize handler\n\
316 report1 [<outfile>]\n\
317 - write report from CollectBySize handler in <outfile>\n\
319 - open file for writing the log with LogFileHandler\n\
320 close - close the log file with LogFileHandler\n\
321 report2 [<flag>] [<logfile>] [<outfile>]\n\
322 - scan <logfile> written with LogFileHandler\n\
323 and make synthesized report in <outfile>; <flag> can be:\n\
324 0 - simple stats by sizes (default),\n\
325 1 - with alive allocation numbers\n\
326 By default <logfile> is \"mem-log.txt\", <outfile> is \"mem-stat.txt\""
330 if (strcmp(a[1], "set") == 0)
332 int aType = (n > 2 ? atoi(a[2]) : 1);
333 if (aType < 0 || aType > 2)
335 di << "unknown op of the command set" << "\n";
340 OSD_MAllocHook::SetCallback(NULL);
341 di << "callback is unset" << "\n";
345 OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetCollectBySize());
346 di << "callback is set to CollectBySize" << "\n";
348 else //if (aType == 2)
350 OSD_MAllocHook::SetCallback(OSD_MAllocHook::GetLogFileHandler());
351 di << "callback is set to LogFileHandler" << "\n";
354 else if (strcmp(a[1], "reset") == 0)
356 OSD_MAllocHook::GetCollectBySize()->Reset();
357 di << "CollectBySize handler is reset" << "\n";
359 else if (strcmp(a[1], "open") == 0)
361 const char* aFileName = (n > 2 ? a[2] : "mem-log.txt");
362 if (!OSD_MAllocHook::GetLogFileHandler()->Open(aFileName))
364 di << "cannot create file " << aFileName << " for writing" << "\n";
367 di << "log file " << aFileName << " is opened for writing" << "\n";
369 else if (strcmp(a[1], "close") == 0)
371 OSD_MAllocHook::GetLogFileHandler()->Close();
372 di << "log file is closed" << "\n";
374 else if (strcmp(a[1], "report1") == 0)
376 const char* aOutFile = "mem-stat.txt";
379 if (OSD_MAllocHook::GetCollectBySize()->MakeReport(aOutFile))
381 di << "report " << aOutFile << " has been created" << "\n";
385 di << "cannot create report " << aOutFile << "\n";
389 else if (strcmp(a[1], "report2") == 0)
391 Standard_Boolean includeAlive = Standard_False;
392 const char* aLogFile = "mem-log.txt";
393 const char* aOutFile = "mem-stat.txt";
396 includeAlive = (atoi(a[2]) != 0);
404 if (OSD_MAllocHook::LogFileHandler::MakeReport(aLogFile, aOutFile, includeAlive))
406 di << "report " << aOutFile << " has been created" << "\n";
410 di << "cannot create report " << aOutFile << " from the log file "
417 di << "unrecognized command " << a[1] << "\n";
423 //==============================================================================
424 //function : dmeminfo
426 //==============================================================================
428 static int dmeminfo (Draw_Interpretor& theDI,
429 Standard_Integer theArgNb,
430 const char** theArgVec)
432 OSD_MemInfo aMemInfo;
435 theDI << aMemInfo.ToString();
439 for (Standard_Integer anIter = 1; anIter < theArgNb; ++anIter)
441 TCollection_AsciiString anArg (theArgVec[anIter]);
443 if (anArg == "virt" || anArg == "v")
445 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemVirtual)) << " ";
447 else if (anArg == "wset" || anArg == "w")
449 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSet)) << " ";
451 else if (anArg == "wsetpeak")
453 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSetPeak)) << " ";
455 else if (anArg == "swap")
457 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsage)) << " ";
459 else if (anArg == "swappeak")
461 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemSwapUsagePeak)) << " ";
463 else if (anArg == "private")
465 theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemPrivate)) << " ";
469 std::cerr << "Unknown argument '" << theArgVec[anIter] << "'!\n";
476 void Draw::BasicCommands(Draw_Interpretor& theCommands)
478 static Standard_Boolean Done = Standard_False;
480 Done = Standard_True;
482 const char* g = "DRAW General Commands";
484 theCommands.Add("batch", "returns 1 in batch mode",
486 theCommands.Add("spy","spy [file], Save commands in file. no file close",
488 theCommands.Add("wait","wait [time(10)], wait time seconds",
489 __FILE__,Draw_wait,g);
490 theCommands.Add("cpulimit","cpulimit [nbseconds], no args remove limits",
491 __FILE__,cpulimit,g);
492 theCommands.Add("chrono","chrono [ name start/stop/reset/show]",
494 theCommands.Add("dchrono","dchrono [ name start/stop/reset/show]",
495 __FILE__,dchronom,g);
496 theCommands.Add("mallochook",
497 "debug memory allocation/deallocation, w/o args for help",
498 __FILE__, mallochook, g);
499 theCommands.Add ("meminfo",
500 "meminfo [virt|v] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
501 " : memory counters for this process",
502 __FILE__, dmeminfo, g);