From d1462bdac5f8178969eabd83e5445dd020996b00 Mon Sep 17 00:00:00 2001 From: prascle Date: Wed, 29 Sep 2004 05:55:27 +0000 Subject: [PATCH] PR: multithreaded trace, part 1 (without logger) --- src/Container/SALOME_Container.cxx | 4 + .../SALOME_DataTypeCatalog_Server.cxx | 3 + src/Loader/InquireServersQThread.cxx | 3 +- src/Loader/SALOME_Session_Loader.cxx | 5 +- src/MPIContainer/SALOME_MPIContainer.cxx | 4 + src/Makefile.in | 3 +- .../SALOME_ModuleCatalog_Server.cxx | 3 + src/Registry/SALOME_Registry_Server.cxx | 3 + .../SALOME_RessourcesCatalog_Server.cxx | 3 + src/SALOMELocalTrace/LocalTraceBufferPool.cxx | 203 ++++++++++++++++++ src/SALOMELocalTrace/LocalTraceBufferPool.hxx | 70 ++++++ src/SALOMELocalTrace/LocalTraceCollector.cxx | 161 ++++++++++++++ src/SALOMELocalTrace/LocalTraceCollector.hxx | 49 +++++ src/SALOMELocalTrace/Makefile.in | 7 +- src/SALOMELocalTrace/utilities.h | 124 +++++++++++ src/Session/SALOME_Session_Server.cxx | 3 + src/Utils/Makefile.in | 1 - src/Utils/duplicate.cxx | 9 +- src/Utils/utilities.h | 112 ---------- 19 files changed, 647 insertions(+), 123 deletions(-) create mode 100644 src/SALOMELocalTrace/LocalTraceBufferPool.cxx create mode 100644 src/SALOMELocalTrace/LocalTraceBufferPool.hxx create mode 100644 src/SALOMELocalTrace/LocalTraceCollector.cxx create mode 100644 src/SALOMELocalTrace/LocalTraceCollector.hxx create mode 100644 src/SALOMELocalTrace/utilities.h delete mode 100644 src/Utils/utilities.h diff --git a/src/Container/SALOME_Container.cxx b/src/Container/SALOME_Container.cxx index 921c3ce26..029b7ad09 100644 --- a/src/Container/SALOME_Container.cxx +++ b/src/Container/SALOME_Container.cxx @@ -35,6 +35,7 @@ #include #include #include "utilities.h" +#include "LocalTraceCollector.hxx" #include "Utils_CatchSignals.h" using namespace std; @@ -51,6 +52,7 @@ static PyMethodDef MethodPyVoidMethod[] = int main(int argc, char* argv[]) { + LocalTraceCollector *myThreadTrace = LocalTraceCollector::instance(); INFOS_COMPILATION; BEGIN_OF(argv[0]) @@ -228,5 +230,7 @@ int main(int argc, char* argv[]) INFOS("Caught unknown exception.") } END_OF(argv[0]); + delete myThreadTrace; + return 0 ; } diff --git a/src/DataTypeCatalog/SALOME_DataTypeCatalog_Server.cxx b/src/DataTypeCatalog/SALOME_DataTypeCatalog_Server.cxx index a29401c51..1cc8e9c31 100644 --- a/src/DataTypeCatalog/SALOME_DataTypeCatalog_Server.cxx +++ b/src/DataTypeCatalog/SALOME_DataTypeCatalog_Server.cxx @@ -30,11 +30,13 @@ #include "SALOME_NamingService.hxx" #include "SALOME_DataTypeCatalog_impl.hxx" #include "utilities.h" +#include "LocalTraceCollector.hxx" #include "Utils_SINGLETON.hxx" using namespace std; int main(int argc,char **argv) { + LocalTraceCollector *myThreadTrace = LocalTraceCollector::instance(); try { CosNaming::NamingContext_var _rootContext, catalogContext; @@ -153,5 +155,6 @@ int main(int argc,char **argv) INFOS("Caught CORBA::Exception.") } + delete myThreadTrace; return 0; } diff --git a/src/Loader/InquireServersQThread.cxx b/src/Loader/InquireServersQThread.cxx index ed5d276cd..dcf0fb2a3 100644 --- a/src/Loader/InquireServersQThread.cxx +++ b/src/Loader/InquireServersQThread.cxx @@ -8,6 +8,7 @@ // $Header$ using namespace std; +#include "utilities.h" #include "InquireServersQThread.h" #include @@ -34,7 +35,7 @@ using namespace std; #include "Utils_ORB_INIT.hxx" #include "Utils_SINGLETON.hxx" #include "SALOME_NamingService.hxx" -#include "utilities.h" +//#include "utilities.h" #include "OpUtil.hxx" #include CORBA_CLIENT_HEADER(SALOME_Session) diff --git a/src/Loader/SALOME_Session_Loader.cxx b/src/Loader/SALOME_Session_Loader.cxx index 3aff04564..dec6984f8 100644 --- a/src/Loader/SALOME_Session_Loader.cxx +++ b/src/Loader/SALOME_Session_Loader.cxx @@ -19,6 +19,7 @@ using namespace std; #include "Utils_SINGLETON.hxx" #include "SALOME_NamingService.hxx" #include "utilities.h" +#include "LocalTraceCollector.hxx" //! CORBA client for SALOME Session server : launch GUI /*! @@ -30,6 +31,7 @@ using namespace std; int main(int argc, char **argv) { + LocalTraceCollector *myThreadTrace = LocalTraceCollector::instance(); //VRV: T2.4 - Trace management improvement QApplication myQApp(argc, argv) ; InquireServersGUI myIS; @@ -85,8 +87,9 @@ int main(int argc, char **argv) { INFOS("Caught unknown exception."); } - return 0 ; } + delete myThreadTrace; + return 0 ; } diff --git a/src/MPIContainer/SALOME_MPIContainer.cxx b/src/MPIContainer/SALOME_MPIContainer.cxx index f11dbb26d..d6e19149e 100644 --- a/src/MPIContainer/SALOME_MPIContainer.cxx +++ b/src/MPIContainer/SALOME_MPIContainer.cxx @@ -28,10 +28,12 @@ using namespace std; #include #include "MPIContainer_i.hxx" #include "utilities.h" +#include "LocalTraceCollector.hxx" #include int main(int argc, char* argv[]) { + LocalTraceCollector *myThreadTrace = LocalTraceCollector::instance(); int nbproc, numproc; MPIContainer_i * myContainer; @@ -116,5 +118,7 @@ int main(int argc, char* argv[]) INFOS("Caught unknown exception.") } END_OF(argv[0]); + delete myThreadTrace; + return 0; } diff --git a/src/Makefile.in b/src/Makefile.in index 5c3530e4b..78eef6e73 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -32,7 +32,8 @@ VPATH=.:@srcdir@ @COMMENCE@ -SUBDIRS = MSG2QM SALOMELocalTrace Logger SALOMELogger Utils PatchQt \ +#SUBDIRS = MSG2QM SALOMELocalTrace Logger SALOMELogger Utils PatchQt +SUBDIRS = MSG2QM SALOMELocalTrace Logger Utils PatchQt \ GenericObj MEDWrapper NamingService Registry \ ModuleCatalog DataTypeCatalog RessourcesCatalog \ Notification NOTIFICATION_SWIG \ diff --git a/src/ModuleCatalog/SALOME_ModuleCatalog_Server.cxx b/src/ModuleCatalog/SALOME_ModuleCatalog_Server.cxx index a15d54759..f6ddd8c83 100644 --- a/src/ModuleCatalog/SALOME_ModuleCatalog_Server.cxx +++ b/src/ModuleCatalog/SALOME_ModuleCatalog_Server.cxx @@ -29,6 +29,7 @@ #include "SALOME_NamingService.hxx" #include "SALOME_ModuleCatalog_impl.hxx" #include "utilities.h" +#include "LocalTraceCollector.hxx" #include "Utils_SINGLETON.hxx" #ifdef CHECKTIME @@ -38,6 +39,7 @@ using namespace std; int main(int argc,char **argv) { + LocalTraceCollector *myThreadTrace = LocalTraceCollector::instance(); try { CosNaming::NamingContext_var _rootContext, catalogContext; @@ -166,5 +168,6 @@ int main(int argc,char **argv) INFOS("Caught CORBA::Exception.") } + delete myThreadTrace; return 0; } diff --git a/src/Registry/SALOME_Registry_Server.cxx b/src/Registry/SALOME_Registry_Server.cxx index 3e5a5b636..d973b2c97 100644 --- a/src/Registry/SALOME_Registry_Server.cxx +++ b/src/Registry/SALOME_Registry_Server.cxx @@ -36,6 +36,7 @@ extern "C" } #include "utilities.h" +#include "LocalTraceCollector.hxx" #include "Utils_ORB_INIT.hxx" #include "Utils_SINGLETON.hxx" #include "Utils_SALOME_Exception.hxx" @@ -51,6 +52,7 @@ using namespace std; int main( int argc , char **argv ) { + LocalTraceCollector *myThreadTrace = LocalTraceCollector::instance(); BEGIN_OF( argv[0] ) INFOS_COMPILATION SCRUTE(argc) @@ -210,5 +212,6 @@ int main( int argc , char **argv ) } END_OF( argv[0] ) ; + delete myThreadTrace; return 0 ; } diff --git a/src/RessourcesCatalog/SALOME_RessourcesCatalog_Server.cxx b/src/RessourcesCatalog/SALOME_RessourcesCatalog_Server.cxx index 4275a4924..0a4cb3b48 100644 --- a/src/RessourcesCatalog/SALOME_RessourcesCatalog_Server.cxx +++ b/src/RessourcesCatalog/SALOME_RessourcesCatalog_Server.cxx @@ -30,11 +30,13 @@ #include "SALOME_NamingService.hxx" #include "SALOME_RessourcesCatalog_impl.hxx" #include "utilities.h" +#include "LocalTraceCollector.hxx" #include "Utils_SINGLETON.hxx" using namespace std; int main(int argc,char **argv) { + LocalTraceCollector *myThreadTrace = LocalTraceCollector::instance(); try { CosNaming::NamingContext_var _rootContext, catalogContext; @@ -149,5 +151,6 @@ int main(int argc,char **argv) INFOS("Caught CORBA::Exception.") } + delete myThreadTrace; return 0; } diff --git a/src/SALOMELocalTrace/LocalTraceBufferPool.cxx b/src/SALOMELocalTrace/LocalTraceBufferPool.cxx new file mode 100644 index 000000000..67791553f --- /dev/null +++ b/src/SALOMELocalTrace/LocalTraceBufferPool.cxx @@ -0,0 +1,203 @@ +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : Paul RASCLE (EDF) +// Module : KERNEL +// $Header$ +// +// Cf. C++ Users Journal, June 2004, Tracing Application Execution, Tomer Abramson +// + +#include +#include + +#include "LocalTraceBufferPool.hxx" +#include "utilities.h" + +using namespace std; + +LocalTraceBufferPool* LocalTraceBufferPool::_singleton = 0; + +// ============================================================================ +/*! + * guarantees a unique object instance of the class (singleton) + * Must be done at first because not thread safe: + * _singleton is not protected by a mutex + */ +// ============================================================================ + +LocalTraceBufferPool* LocalTraceBufferPool::instance() +{ + if (_singleton == 0) _singleton = new LocalTraceBufferPool(); + return _singleton; +} + +// ============================================================================ +/*! + * Called by trace producers within their threads. The trace message is copied + * in specific buffer from a circular pool of buffers. + * Waits until there is a free buffer in the pool, gets the first available + * buffer, fills it with the message. + * Messages are printed in a separate thread (see retrieve method) + */ +// ============================================================================ + +int LocalTraceBufferPool::insert(int traceType, const char* msg) +{ + + // get immediately a message number to control sequence (mutex protected) + + unsigned long myMessageNumber = lockedIncrement(_position); + + // wait until there is a free buffer in the pool + + int ret = sem_wait(&_freeBufferSemaphore); + + // get the next free buffer available (mutex protected) + + unsigned long myInsertPos = lockedIncrement(_insertPos); + + // fill the buffer with message, thread id and type (normal or abort) + + strncpy(_myBuffer[myInsertPos%TRACE_BUFFER_SIZE].trace, + msg, + MAX_TRACE_LENGTH-1); // last char always 0 even if msg too long + _myBuffer[myInsertPos%TRACE_BUFFER_SIZE].threadId = pthread_self(); // thread id + _myBuffer[myInsertPos%TRACE_BUFFER_SIZE].traceType = traceType; + _myBuffer[myInsertPos%TRACE_BUFFER_SIZE].position = myMessageNumber; + + + // increment the full buffer semaphore + // (if previously 0, awake thread in charge of trace) + + ret = sem_post(&_fullBufferSemaphore); + + // returns the number of free buffers + + sem_getvalue(&_freeBufferSemaphore, &ret); + return ret; +} + +// ============================================================================ +/*! + * Called by the thread in charge of printing trace messages. + * Waits until there is a buffer with a message to print. + * Gets the first buffer to print, copies it int the provided buffer + */ +// ============================================================================ + +int LocalTraceBufferPool::retrieve(LocalTrace_TraceInfo& aTrace) +{ + + // wait until there is a buffer in the pool, with a message to print + + int ret = sem_wait(&_fullBufferSemaphore); + + // get the next buffer to print + + unsigned long myRetrievePos = lockedIncrement(_retrievePos); + + // copy the buffer from the pool to the provided buffer + + memcpy((void*)&aTrace, + (void*)&_myBuffer[myRetrievePos%TRACE_BUFFER_SIZE], + sizeof(aTrace)); + + // increment the free buffer semaphore + // (if previously 0, awake one of the threads waiting to put a trace, if any) + // there is no way to preserve the order of waiting threads if several threads + // are waiting to put a trace: the waken up thread is not necessarily the + // first thread to wait. + + ret = sem_post(&_freeBufferSemaphore); + + // returns the number of full buffers + + sem_getvalue(&_fullBufferSemaphore, &ret); + return ret; +} + +// ============================================================================ +/*! + * Gives the number of buffers to print. + * Usage : when the thread in charge of messages print id to be stopped, + * check if there is still something to print, before stop. + * There is no need of mutex here, provided there is only one thread to + * retrieve and print the buffers. + */ +// ============================================================================ + +unsigned long LocalTraceBufferPool::toCollect() +{ + return _insertPos - _retrievePos; +} + +// ============================================================================ +/*! + * Constructor : initialize pool of buffers, semaphores and mutex. + */ +// ============================================================================ + +LocalTraceBufferPool::LocalTraceBufferPool() +{ + cout << "LocalTraceBufferPool::LocalTraceBufferPool()" << endl; + + _insertPos = ULONG_MAX; // first increment will give 0 + _retrievePos = ULONG_MAX; + _position=0; // first message will have number = 1 + + memset(_myBuffer, 0, sizeof(_myBuffer)); // to guarantee end of strings = 0 + int ret; + ret=sem_init(&_freeBufferSemaphore, 0, TRACE_BUFFER_SIZE); // all buffer free + if (ret!=0) IMMEDIATE_ABORT(ret); + ret=sem_init(&_fullBufferSemaphore, 0, 0); // 0 buffer full + if (ret!=0) IMMEDIATE_ABORT(ret); + ret=pthread_mutex_init(&_incrementMutex,NULL); // default = fast mutex + if (ret!=0) IMMEDIATE_ABORT(ret); +} + +// ============================================================================ +/*! + * Destructor : release memory associated with semaphores and mutex + */ +// ============================================================================ + +LocalTraceBufferPool::~LocalTraceBufferPool() +{ + int ret; + ret=sem_destroy(&_freeBufferSemaphore); + ret=sem_destroy(&_fullBufferSemaphore); + ret=pthread_mutex_destroy(&_incrementMutex); +} + +// ============================================================================ +/*! + * pool counters are incremented under a mutex protection + */ +// ============================================================================ + +unsigned long LocalTraceBufferPool::lockedIncrement(unsigned long& pos) +{ + int ret; + ret = pthread_mutex_lock(&_incrementMutex); // lock access to counters + pos++; + ret = pthread_mutex_unlock(&_incrementMutex); // release lock + return pos; +} + diff --git a/src/SALOMELocalTrace/LocalTraceBufferPool.hxx b/src/SALOMELocalTrace/LocalTraceBufferPool.hxx new file mode 100644 index 000000000..847478005 --- /dev/null +++ b/src/SALOMELocalTrace/LocalTraceBufferPool.hxx @@ -0,0 +1,70 @@ +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// Author : Paul RASCLE (EDF) +// Module : KERNEL +// $Header$ + +#ifndef _LOCALTRACEBUFFERPOOL_HXX_ +#define _LOCALTRACEBUFFERPOOL_HXX_ + +#define TRACE_BUFFER_SIZE 256 // number of entries in circular buffer + // must be power of 2 +#define MAX_TRACE_LENGTH 256 // messages are truncated at this size + +#include +#include + +#define ABORT_MESS 1 // for traceType field in struct LocalTrace_TraceInfo +#define NORMAL_MESS 0 + +struct LocalTrace_TraceInfo +{ + char trace[MAX_TRACE_LENGTH]; + pthread_t threadId; + int traceType; // normal or abort + int position; // to check sequence +}; + +class LocalTraceBufferPool +{ + public: + static LocalTraceBufferPool* instance(); + int insert(int traceType, const char* msg); + int retrieve(LocalTrace_TraceInfo& aTrace); + unsigned long toCollect(); + ~LocalTraceBufferPool(); + + protected: + LocalTraceBufferPool(); + unsigned long lockedIncrement(unsigned long& pos); + + private: + static LocalTraceBufferPool* _singleton; + LocalTrace_TraceInfo _myBuffer[TRACE_BUFFER_SIZE]; + sem_t _freeBufferSemaphore; // to wait until there is a free buffer + sem_t _fullBufferSemaphore; // to wait until there is a buffer to print + pthread_mutex_t _incrementMutex; // to lock position variables for increment + unsigned long _position; + unsigned long _insertPos; + unsigned long _retrievePos; + pthread_t _threadId; +}; + +#endif diff --git a/src/SALOMELocalTrace/LocalTraceCollector.cxx b/src/SALOMELocalTrace/LocalTraceCollector.cxx new file mode 100644 index 000000000..119722643 --- /dev/null +++ b/src/SALOMELocalTrace/LocalTraceCollector.cxx @@ -0,0 +1,161 @@ +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : LocalTraceCollector.cxx +// Author : Paul RASCLE (EDF) +// Module : KERNEL +// $Header$ + +#include +#include + +#include "LocalTraceCollector.hxx" + +using namespace std; + +LocalTraceCollector* LocalTraceCollector::_singleton = 0; +int LocalTraceCollector::_threadToClose = 0; +pthread_t LocalTraceCollector::_threadId = 0; +int LocalTraceCollector::_toFile = 0; // public, set by user + +// ============================================================================ +/*! + * guarantees a unique object instance of the class (singleton) + * Must be done at first because not thread safe: + * _singleton is not protected by a mutex + * LocalTraceCollector instance is created, then LocalTraceBufferPool + * instance is created immediately in the same thread (not thread safe, too). + * After thet, a separate thread for loop to print traces is launched. + */ +// ============================================================================ + +LocalTraceCollector* LocalTraceCollector::instance() +{ + if (_singleton == 0) + { + _singleton = new LocalTraceCollector(); + LocalTraceBufferPool* initTraceBuffer = LocalTraceBufferPool::instance(); + pthread_t traceThread; + int bid; + int ret = pthread_create(&traceThread, NULL, + LocalTraceCollector::run, (void *)bid); + } + return _singleton; +} + +// ============================================================================ +/*! + * In a separate thread, loop to print traces. + * Loop until there is no more buffer to print, + * and no ask for end from destructor. + * Get a buffer. If type = ABORT then exit application with message. + */ +// ============================================================================ + +void* LocalTraceCollector::run(void *bid) +{ + if (! _threadId) // only one run + { + _threadId = pthread_self(); + LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance(); + LocalTrace_TraceInfo myTrace; + + // if trace in file requested, opens a file with append mode + // so, several processes can share the same file + + ofstream traceFile; + if (_toFile) + { + const char *fileName = "/tmp/tracetest.log"; + traceFile.open(fileName, ios::out | ios::app); + if (!traceFile) + { + cerr << "impossible to open trace file "<< fileName << endl; + exit (1); + } + } + + // Loop until there is no more buffer to print, + // and no ask for end from destructor. + + while ((!_threadToClose) || myTraceBuffer->toCollect() ) + { + int fullBuf = myTraceBuffer->retrieve(myTrace); + if (myTrace.traceType == ABORT_MESS) + { + cout << flush ; + cerr << "INTERRUPTION from thread " << myTrace.threadId + << " : " << myTrace.trace; + cerr << flush ; + exit(1); + } + else + { + if (_toFile) + traceFile << myTrace.position << " thread " << myTrace.threadId + << " full " << fullBuf <<" " << myTrace.trace; + else + cout << " th. " << myTrace.threadId + << " " << fullBuf <<" " << myTrace.trace; + } + } + + if (_toFile) traceFile.close(); + } + pthread_exit(NULL); + //return 0; // just for warning +} + +// ============================================================================ +/*! + * Destructor: wait until printing thread ends (LocalTraceCollector::run) + */ +// ============================================================================ + +LocalTraceCollector:: ~LocalTraceCollector() +{ + _threadToClose = 1; + if (_threadId) + { + int ret = pthread_join(_threadId, NULL); + if (ret) cout << "error close LocalTraceCollector : "<< ret << endl; + else cout << "LocalTraceCollector destruction OK" << endl; + } + LocalTraceBufferPool* myTraceBuffer = LocalTraceBufferPool::instance(); + delete myTraceBuffer; +} + +// ============================================================================ +/*! + * Constructor: need of LocalTraceBufferPool object initialization here, + * before creation of thread that access LocalTraceBufferPool: if done after, + * simutaneous call to LocalTraceBufferPool::instance() from different + * threads may lead to multiple instances (instance method not mutex protected) + */ +// ============================================================================ + +LocalTraceCollector::LocalTraceCollector() +{ + _threadId=0; + LocalTraceBufferPool *myTraceBuffer = LocalTraceBufferPool::instance(); +} + + diff --git a/src/SALOMELocalTrace/LocalTraceCollector.hxx b/src/SALOMELocalTrace/LocalTraceCollector.hxx new file mode 100644 index 000000000..5bcd75139 --- /dev/null +++ b/src/SALOMELocalTrace/LocalTraceCollector.hxx @@ -0,0 +1,49 @@ +// Copyright (C) 2004 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : LocalTraceCollector.hxx +// Author : Paul RASCLE (EDF) +// Module : KERNEL +// $Header$ + +#ifndef _LOCALTRACECOLLECTOR_HXX_ +#define _LOCALTRACECOLLECTOR_HXX_ + +#include "LocalTraceBufferPool.hxx" + +class LocalTraceCollector +{ + public: + static LocalTraceCollector* instance(); + static void *run(void *bid); + ~LocalTraceCollector(); + static int _threadToClose; + static int _toFile; + + protected: + LocalTraceCollector(); + + private: + static LocalTraceCollector* _singleton; + static pthread_t _threadId; +}; + +#endif diff --git a/src/SALOMELocalTrace/Makefile.in b/src/SALOMELocalTrace/Makefile.in index 6e3674a3e..8d2beb1d5 100644 --- a/src/SALOMELocalTrace/Makefile.in +++ b/src/SALOMELocalTrace/Makefile.in @@ -35,14 +35,17 @@ VPATH=.:@srcdir@:@top_srcdir@/idl @COMMENCE@ # header files -EXPORT_HEADERS= SALOME_Log.hxx +EXPORT_HEADERS= utilities.h \ + LocalTraceBufferPool.hxx \ + LocalTraceCollector.hxx EXPORT_PYSCRIPTS = # Libraries targets LIB = libSALOMELocalTrace.la -LIB_SRC = SALOME_Log.cxx +LIB_SRC = LocalTraceCollector.cxx \ + LocalTraceBufferPool.cxx LDFLAGS+= diff --git a/src/SALOMELocalTrace/utilities.h b/src/SALOMELocalTrace/utilities.h new file mode 100644 index 000000000..94543b9f2 --- /dev/null +++ b/src/SALOMELocalTrace/utilities.h @@ -0,0 +1,124 @@ +// SALOME Utils : general SALOME's definitions and tools +// +// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, +// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Lesser General Public +// License as published by the Free Software Foundation; either +// version 2.1 of the License. +// +// This library is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Lesser General Public License for more details. +// +// You should have received a copy of the GNU Lesser General Public +// License along with this library; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +// +// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org +// +// +// +// File : utilities.h +// Author : Antoine YESSAYAN, Paul RASCLE, EDF +// Module : SALOME +// $Header$ + +/* --- Definition macros file to print informations if _DEBUG_ is defined --- */ + +#ifndef UTILITIES_H +#define UTILITIES_H + +#include +#include +#include +#include + +using namespace std; + +#include "LocalTraceBufferPool.hxx" + +/*! + * For each message to put in the trace, a specific ostingstream object is + * created and destroyed automatically at the end of the message macro. + * The insert function of LocalTraceBufferPool class gets a buffer in a + * buffer pool (unique with the help of mutexes and semaphores) and copy the + * message in the buffer. + * This buffer is read later by a specific thread in charge of trace print. + * Order of trace entries is globally respected. Nevertheless, if there are + * several threads waiting for a free buffer to trace, the order of + * thread waken up is not garanteed (no fifo or priority rules in Linux Kernel) + */ + +#define MESS_INIT(deb) ostringstream os; os<insert(NORMAL_MESS, os.str().c_str()); +#define MESS_ABORT endl; LocalTraceBufferPool::instance()->insert(ABORT_MESS, os.str().c_str()); + +// --- Some macros are always defined (without _DEBUG_): for use with release version + +#define INFOS(msg) {MESS_BEGIN("- Trace ") << msg << MESS_END} +#define PYSCRIPT(msg) {MESS_INIT("---PYSCRIPT--- ") << msg << MESS_END} +#define INTERRUPTION(msg) {MESS_BEGIN("- INTERRUPTION: ")<< msg << MESS_ABORT} +#define IMMEDIATE_ABORT(code) {cout <::Instance() ; @@ -252,5 +254,6 @@ int main(int argc, char **argv) INFOS("Caught unknown exception."); } MESSAGE("End of SALOME_Session_Server"); + delete myThreadTrace; return 0 ; } diff --git a/src/Utils/Makefile.in b/src/Utils/Makefile.in index fbbd1527f..df6e8c5ef 100644 --- a/src/Utils/Makefile.in +++ b/src/Utils/Makefile.in @@ -36,7 +36,6 @@ VPATH=.:@srcdir@:@top_srcdir@/idl # header files EXPORT_HEADERS= \ - utilities.h \ OpUtil.hxx \ Utils_Timer.hxx \ Utils_CorbaException.hxx \ diff --git a/src/Utils/duplicate.cxx b/src/Utils/duplicate.cxx index fd4b95633..8633effbd 100644 --- a/src/Utils/duplicate.cxx +++ b/src/Utils/duplicate.cxx @@ -31,11 +31,10 @@ * It is strongly (and only) used in the Registry environment * (RegistryService, RegistryConnexion, Identity, ...) */ -extern "C" -{ -#include -#include -} + +#include +#include + #include "utilities.h" const char* duplicate( const char *const str ) diff --git a/src/Utils/utilities.h b/src/Utils/utilities.h deleted file mode 100644 index 1cf18d27a..000000000 --- a/src/Utils/utilities.h +++ /dev/null @@ -1,112 +0,0 @@ -// SALOME Utils : general SALOME's definitions and tools -// -// Copyright (C) 2003 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, -// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Lesser General Public -// License as published by the Free Software Foundation; either -// version 2.1 of the License. -// -// This library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public -// License along with this library; if not, write to the Free Software -// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -// -// See http://www.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org -// -// -// -// File : utilities.h -// Author : Antoine YESSAYAN, Paul RASCLE, EDF -// Module : SALOME -// $Header$ - -/* --- Definition macros file to print informations if _DEBUG_ is defined --- */ - -#ifndef UTILITIES_H -#define UTILITIES_H - -#include -#include -#include -#include "SALOME_Log.hxx" - -/* --- INFOS is always defined (without _DEBUG_): to be used for warnings, with release version --- */ - -#define INFOS(msg) {SLog->putMessage(*SLog<<__FILE__<<" ["<<__LINE__<<"] : "<putMessage(*SLog<<"---PYSCRIPT--- "<putMessage(\ - *SLog<<__FILE__<<" ["<< __LINE__<<"] : "\ - << "COMPILED with " << COMPILER \ - << ", " << __DATE__ \ - << " at " << __TIME__ <putMessage( MYTRACE <putMessage( MYTRACE << #var << "=" << var <