// 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>
#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
extern Standard_Boolean Draw_Batch;
static clock_t CPU_LIMIT; // Cpu_limit in Sec.
+static OSD_Timer aTimer;
//=======================================================================
// chronom
{
// 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
#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
#ifdef _WIN32
static unsigned int __stdcall CpuFunc (void * /*param*/)
{
+ clock_t anElapCurrent;
clock_t aCurrent;
+
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;
}
}
}
#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& 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;
}
#else
-
// Unix & Linux
-
rlimit rlp;
rlp.rlim_max = RLIM_INFINITY;
if (n <= 1)
// 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 :
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;
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",
"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.)",