0023880: Integration of grid "ncl" into the new testing system
[occt.git] / src / Draw / Draw_BasicCommands.cxx
old mode 100755 (executable)
new mode 100644 (file)
index 012af7f..500718a
@@ -1,22 +1,18 @@
 // Created on: 1995-02-23
 // Created by: Remi LEQUETTE
 // Copyright (c) 1995-1999 Matra Datavision
-// Copyright (c) 1999-2012 OPEN CASCADE SAS
+// Copyright (c) 1999-2014 OPEN CASCADE SAS
 //
-// The content of this file is subject to the Open CASCADE Technology Public
-// License Version 6.5 (the "License"). You may not use the content of this file
-// except in compliance with the License. Please obtain a copy of the License
-// at http://www.opencascade.org and read it completely before using this file.
+// This file is part of Open CASCADE Technology software library.
 //
-// The Initial Developer of the Original Code is Open CASCADE S.A.S., having its
-// main offices at: 1, place des Freres Montgolfier, 78280 Guyancourt, France.
+// This library is free software; you can redistribute it and/or modify it under
+// the terms of the GNU Lesser General Public License version 2.1 as published
+// by the Free Software Foundation, with special exception defined in the file
+// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT
+// distribution for complete text of the license and disclaimer of any warranty.
 //
-// The Original Code and all software distributed under the License is
-// distributed on an "AS IS" basis, without warranty of any kind, and the
-// Initial Developer hereby disclaims all such warranties, including without
-// limitation, any warranties of merchantability, fitness for a particular
-// purpose or non-infringement. Please see the License for the specific terms
-// and conditions governing the rights and limitations under the License.
+// Alternatively, this file may be used under the terms of Open CASCADE
+// commercial license or contractual agreement.
 
 #include <Standard_Macro.hxx>
 #include <Standard_Stream.hxx>
@@ -36,6 +32,7 @@
 #include <OSD_Chronometer.hxx>
 #include <OSD.hxx>
 #include <OSD_Exception_CTRL_BREAK.hxx>
+#include <OSD_PerfMeter.h>
 
 #ifdef _WIN32
 
 
 static clock_t CPU_CURRENT; // cpu time already used at last
                             // cpulimit call. (sec.) 
-
 #else /* _WIN32 */
 
 #include <sys/resource.h>
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#ifdef HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
-#if defined(HAVE_TIME_H)
-# include <time.h>
-#endif
-
-#ifdef HAVE_SIGNAL_H
-# include <signal.h>
-#endif
-
-#ifdef HAVE_SYS_SIGNAL_H
-# include <sys/signal.h>
-#endif
+#include <signal.h>
+#include <unistd.h>
 
 #if defined (__hpux) || defined ( HPUX )
 #define RLIM_INFINITY   0x7fffffff
@@ -86,6 +64,7 @@ static clock_t CPU_CURRENT; // cpu time already used at last
 extern Standard_Boolean Draw_Batch;
 
 static clock_t CPU_LIMIT;   // Cpu_limit in Sec.
+static OSD_Timer aTimer;
 
 //=======================================================================
 // chronom
@@ -292,7 +271,9 @@ static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const c
 {
   // print OCCT version and OCCTY-specific macros used
   di << "Open CASCADE Technology " << OCC_VERSION_STRING_EXT << "\n";
-#if defined(DEB) || defined(_DEBUG)
+#ifdef OCCT_DEBUG
+  di << "Extended debug mode\n";
+#elif defined(_DEBUG)
   di << "Debug mode\n";
 #endif
 #ifdef HAVE_TBB
@@ -310,6 +291,16 @@ static Standard_Integer dversion(Draw_Interpretor& di, Standard_Integer, const c
 #else
   di << "FreeImage disabled\n";
 #endif
+#ifdef HAVE_OPENCL
+  di << "OpenCL enabled (HAVE_OPENCL)\n";
+#else
+  di << "OpenCL disabled\n";
+#endif
+#ifdef HAVE_VTK
+  di << "VTK enabled (HAVE_VTK)\n";
+#else
+  di << "VTK disabled\n";
+#endif
 #ifdef No_Exception
   di << "Exceptions disabled (No_Exception)\n";
 #else
@@ -402,52 +393,79 @@ static Standard_Integer Draw_wait(Draw_Interpretor& , Standard_Integer n, const
 //purpose  : 
 //=======================================================================
 #ifdef _WIN32
-static unsigned int __stdcall CpuFunc (void * param)
+static unsigned int __stdcall CpuFunc (void * /*param*/)
 {
+  clock_t anElapCurrent;
   clock_t aCurrent;
-  while (1)
+
+  for(;;)
   {
     Sleep (5);
     Standard_Real anUserSeconds, aSystemSeconds;
     OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
     aCurrent = clock_t(anUserSeconds + aSystemSeconds);
+    anElapCurrent = clock_t(aTimer.ElapsedTime());
     
     if ((aCurrent - CPU_CURRENT) >= CPU_LIMIT)
     {
       cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << endl;
+      aTimer.Stop();
+      ExitProcess (2);
+    }
+    if ((anElapCurrent) >= CPU_LIMIT)
+    {
+      cout << "Process killed by elapsed limit (" << CPU_LIMIT << " sec)" << endl;
+      aTimer.Stop();
       ExitProcess (2);
-      return 0;
     }
   }
-  return 0;
 }
 #else
-static void CpuFunc (int)
+static void cpulimitSignalHandler (int)
 {
-  cout << "Process killed by CPU limit (" << CPU_LIMIT << " sec)" << endl;
+  cout << "Process killed by CPU limit  (" << CPU_LIMIT << " sec)" << endl;
   exit(2);
 }
+static void *CpuFunc(void* /*threadarg*/)
+{
+  clock_t anElapCurrent;
+  for(;;)
+  {
+    sleep (5);
+    anElapCurrent = clock_t(aTimer.ElapsedTime());
+    if ( CPU_LIMIT < 0 )
+      return NULL;
+    if ((anElapCurrent) >= CPU_LIMIT) {
+      cout << "Process killed by elapsed limit  (" << CPU_LIMIT << " sec)" << endl;
+      exit(2);
+    }
+  }
+  return NULL;
+}
 #endif
 
+#ifdef _WIN32
+static Standard_Integer cpulimit(Draw_Interpretor&, Standard_Integer n, const char** a)
+{
+#else
 static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const char** a)
 {
+#endif
+  static int aFirst = 1;
 #ifdef _WIN32
   // Windows specific code
-
-  static int aFirst = 1;
-
   unsigned int __stdcall CpuFunc (void *);
   unsigned aThreadID;
 
-  if (n <= 1)
+  if (n <= 1){
     CPU_LIMIT = RLIM_INFINITY;
-  else
-  {
+  } else {
     CPU_LIMIT = Draw::Atoi (a[1]);
     Standard_Real anUserSeconds, aSystemSeconds;
     OSD_Chronometer::GetProcessCPU (anUserSeconds, aSystemSeconds);
     CPU_CURRENT = clock_t(anUserSeconds + aSystemSeconds);
-
+    aTimer.Reset();
+    aTimer.Start();
     if (aFirst) // Launch the thread only at the 1st call.
     {
       aFirst = 0;
@@ -456,9 +474,7 @@ static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const
   }
 
 #else 
-
   // Unix & Linux
-
   rlimit rlp;
   rlp.rlim_max = RLIM_INFINITY;
   if (n <= 1)
@@ -475,14 +491,23 @@ static Standard_Integer cpulimit(Draw_Interpretor& di, Standard_Integer n, const
   // set signal handler to print a message before death
   struct sigaction act, oact;
   memset (&act, 0, sizeof(act));
-  act.sa_handler = CpuFunc;
+  act.sa_handler = cpulimitSignalHandler;
   sigaction (SIGXCPU, &act, &oact);
 
+  // cpulimit for elapsed time
+  aTimer.Reset();
+  aTimer.Start();
+  pthread_t cpulimitThread;
+  if (aFirst) // Launch the thread only at the 1st call.
+  {
+    aFirst = 0;
+    pthread_create(&cpulimitThread, NULL, CpuFunc, NULL);
+  }
 #endif
-
   return 0;
 }
 
+
 //=======================================================================
 //function : mallochook
 //purpose  : 
@@ -664,6 +689,10 @@ static int dmeminfo (Draw_Interpretor& theDI,
     {
       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemVirtual)) << " ";
     }
+    else if (anArg == "heap" || anArg == "h")
+    {
+      theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemHeapUsage)) << " ";
+    }
     else if (anArg == "wset" || anArg == "w")
     {
       theDI << Standard_Real (aMemInfo.Value (OSD_MemInfo::MemWorkingSet)) << " ";
@@ -693,6 +722,114 @@ static int dmeminfo (Draw_Interpretor& theDI,
   return 0;
 }
 
+//==============================================================================
+//function : dperf
+//purpose  :
+//==============================================================================
+
+static int dperf (Draw_Interpretor& theDI, Standard_Integer theArgNb, const char** theArgVec)
+{
+  // reset if argument is provided and it is not '0'
+  int reset = (theArgNb > 1 ? theArgVec[1][0] != '0' && theArgVec[1][0] != '\0' : 0);
+  char buffer[25600];
+  perf_sprint_all_meters (buffer, 25600 - 1, reset);
+  theDI << buffer;
+  return 0;
+}
+
+//==============================================================================
+//function : dtracelevel
+//purpose  :
+//==============================================================================
+
+static int dtracelevel (Draw_Interpretor& theDI,
+                        Standard_Integer  theArgNb,
+                        const char**      theArgVec)
+{
+  Message_Gravity aLevel = Message_Info;
+  if (theArgNb < 1 || theArgNb > 2)
+  {
+    std::cout << "Error: wrong number of arguments! See usage:\n";
+    theDI.PrintHelp (theArgVec[0]);
+    return 1;
+  }
+  else if (theArgNb == 2)
+  {
+    TCollection_AsciiString aVal (theArgVec[1]);
+    aVal.LowerCase();
+    if (aVal == "trace")
+    {
+      aLevel = Message_Trace;
+    }
+    else if (aVal == "info")
+    {
+      aLevel = Message_Info;
+    }
+    else if (aVal == "warn"
+          || aVal == "warning")
+    {
+      aLevel = Message_Warning;
+    }
+    else if (aVal == "alarm")
+    {
+      aLevel = Message_Alarm;
+    }
+    else if (aVal == "fail")
+    {
+      aLevel = Message_Fail;
+    }
+    else
+    {
+      std::cout << "Error: unknown gravity '" << theArgVec[1] << "'!\n";
+      return 1;
+    }
+  }
+
+  Handle(Message_Messenger) aMessenger = Message::DefaultMessenger();
+  if (aMessenger.IsNull())
+  {
+    std::cout << "Error: default messenger is unavailable!\n";
+    return 1;
+  }
+
+  Message_SequenceOfPrinters& aPrinters = aMessenger->ChangePrinters();
+  if (aPrinters.Length() < 1)
+  {
+    std::cout << "Error: no printers registered in default Messenger!\n";
+    return 0;
+  }
+
+  for (Standard_Integer aPrinterIter = 1; aPrinterIter <= aPrinters.Length(); ++aPrinterIter)
+  {
+    Handle(Message_Printer)& aPrinter = aPrinters.ChangeValue (aPrinterIter);
+    if (theArgNb == 1)
+    {
+      if (aPrinterIter == 1)
+      {
+        aLevel = aPrinter->GetTraceLevel();
+      }
+      else if (aLevel == aPrinter->GetTraceLevel())
+      {
+        continue;
+      }
+
+      switch (aPrinter->GetTraceLevel())
+      {
+        case Message_Trace:   theDI << "trace"; break;
+        case Message_Info:    theDI << "info";  break;
+        case Message_Warning: theDI << "warn";  break;
+        case Message_Alarm:   theDI << "alarm"; break;
+        case Message_Fail:    theDI << "fail";  break;
+      }
+      continue;
+    }
+
+    aPrinter->SetTraceLevel (aLevel);
+  }
+
+  return 0;
+}
+
 void Draw::BasicCommands(Draw_Interpretor& theCommands)
 {
   static Standard_Boolean Done = Standard_False;
@@ -702,7 +839,7 @@ void Draw::BasicCommands(Draw_Interpretor& theCommands)
   ios::sync_with_stdio();
 
   const char* g = "DRAW General Commands";
-  
+
   theCommands.Add("batch", "returns 1 in batch mode",
                  __FILE__,ifbatch,g);
   theCommands.Add("spy","spy [file], Save commands in file. no file close",
@@ -719,17 +856,21 @@ void Draw::BasicCommands(Draw_Interpretor& theCommands)
                   "debug memory allocation/deallocation, w/o args for help",
                   __FILE__, mallochook, g);
   theCommands.Add ("meminfo",
-    "meminfo [virt|v] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
+    "meminfo [virt|v] [heap|h] [wset|w] [wsetpeak] [swap] [swappeak] [private]"
     " : memory counters for this process",
          __FILE__, dmeminfo, g);
+  theCommands.Add("dperf","dperf [reset] -- show performance counters, reset if argument is provided",
+                 __FILE__,dperf,g);
 
-  // Logging commands; note that their names are hard-coded in the code 
+  // Logging commands; note that their names are hard-coded in the code
   // of Draw_Interpretor, thus should not be changed without update of that code!
   theCommands.Add("dlog", "manage logging of commands and output; run without args to get help",
                  __FILE__,dlog,g);
   theCommands.Add("decho", "switch on / off echo of commands to cout; run without args to get help",
                  __FILE__,decho,g);
-  
+  theCommands.Add("dtracelevel", "dtracelevel [trace|info|warn|alarm|fail]",
+                  __FILE__, dtracelevel, g);
+
   theCommands.Add("dbreak", "raises Tcl exception if user has pressed Control-Break key",
                  __FILE__,dbreak,g);
   theCommands.Add("dversion", "provides information on OCCT build configuration (version, compiler, OS, C library, etc.)",