You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@xalan.apache.org by db...@apache.org on 2001/11/06 05:39:46 UTC
cvs commit: xml-xalan/c/Tests/Threads ThreadTest.cpp
dbertoni 01/11/05 20:39:46
Modified: c/Tests/Threads ThreadTest.cpp
Log:
Added option for continuous processing.
Revision Changes Path
1.17 +276 -93 xml-xalan/c/Tests/Threads/ThreadTest.cpp
Index: ThreadTest.cpp
===================================================================
RCS file: /home/cvs/xml-xalan/c/Tests/Threads/ThreadTest.cpp,v
retrieving revision 1.16
retrieving revision 1.17
diff -u -r1.16 -r1.17
--- ThreadTest.cpp 2001/08/22 18:02:37 1.16
+++ ThreadTest.cpp 2001/11/06 04:39:45 1.17
@@ -30,14 +30,18 @@
#if defined(WIN32)
-//This is here for the threads.
-#include <process.h>
+#include <csignal>
+#include <process.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
+
#elif defined(XALAN_POSIX2_AVAILABLE)
+
+#include <csignal>
#include <pthread.h>
#include <unistd.h>
+
#else
#error Unsupported platform!
#endif
@@ -58,7 +62,7 @@
#endif
-
+
class SynchronizedCounter
{
public:
@@ -73,14 +77,14 @@
void
decrement();
- unsigned long
+ long
getCounter() const;
private:
mutable XMLMutex m_mutex;
- unsigned long m_counter;
+ long m_counter;
};
@@ -125,7 +129,7 @@
-unsigned long
+long
SynchronizedCounter::getCounter() const
{
return m_counter;
@@ -140,13 +144,16 @@
unsigned int theThreadNumber = 0,
SynchronizedCounter* theCounter = 0) :
m_threadNumber(theThreadNumber),
- m_counter(theCounter)
+ m_counter(theCounter),
+ m_done(false)
{
}
unsigned int m_threadNumber;
SynchronizedCounter* m_counter;
+
+ bool m_done;
};
@@ -154,6 +161,34 @@
// Used to hold compiled stylesheet and pre-parsed source...
const XalanCompiledStylesheet* glbCompiledStylesheet = 0;
const XalanParsedSource* glbParsedSource = 0;
+bool fContinue = true;
+
+
+#if defined(WIN32)
+static BOOL __stdcall
+signalHandler(DWORD theSignalType)
+{
+ if (theSignalType == CTRL_C_EVENT ||
+ theSignalType == CTRL_BREAK_EVENT)
+ {
+ fContinue = false;
+
+ return TRUE;
+ }
+ else
+ {
+ return FALSE;
+ }
+}
+#elif defined(XALAN_POSIX2_AVAILABLE)
+static void
+signalHandler(int)
+{
+ fContinue = false;
+}
+#else
+#error Unsupported platform!
+#endif
@@ -177,9 +212,9 @@
// process() method.
#if defined(XALAN_OLD_STYLE_CASTS)
- const ThreadInfo* const theInfo = (const ThreadInfo*)param;
+ ThreadInfo* const theInfo = (ThreadInfo*)param;
#else
- const ThreadInfo* const theInfo = reinterpret_cast<const ThreadInfo*>(param);
+ ThreadInfo* const theInfo = reinterpret_cast<ThreadInfo*>(param);
#endif
assert(theInfo != 0);
@@ -211,6 +246,8 @@
// Decrement the counter because we're done...
theInfo->m_counter->decrement();
+ theInfo->m_done = true;
+
#if defined(XALAN_POSIX2_AVAILABLE)
return 0;
#endif
@@ -232,57 +269,166 @@
-void
-doThreads(long theThreadCount)
+bool
+createThread(ThreadInfo& theThreadInfo)
{
- cout << endl << "Starting " << theThreadCount << " threads." << endl;
+ theThreadInfo.m_done = false;
- XalanArrayAutoPtr<ThreadInfo> theThreadInfo(new ThreadInfo[theThreadCount]);
+#if defined(WIN32)
- try
+ const unsigned long theThreadID =
+ _beginthread(theThreadRoutine, 4096, reinterpret_cast<LPVOID>(&theThreadInfo));
+
+ if (theThreadID == unsigned(-1))
{
- cout << endl << "Clock before starting threads: " << clock() << endl;
+ theThreadInfo.m_done = true;
- SynchronizedCounter theCounter;
+ return false;
+ }
+ else
+ {
+ return true;
+ }
- long i = 0;
+#elif defined(XALAN_POSIX2_AVAILABLE)
+
+ pthread_t theThread;
+
+ const int theResult = pthread_create(&theThread, 0, theThreadRoutine, (void*)&theThreadInfo);
- while (i < theThreadCount)
+ if (theResult != 0)
+ {
+ theThreadInfo.m_done = true;
+
+ return false;
+ }
+ else
+ {
+#if defined(OS390)
+ pthread_detach(&theThread);
+#else
+ pthread_detach(theThread);
+#endif
+
+ return true;
+ }
+#else
+#error Unsupported platform!
+#endif
+}
+
+
+
+void
+doCountedThreads(
+ const SynchronizedCounter& theCounter,
+ clock_t& theClock)
+{
+ cout << "Waiting for active threads to finish..." << endl;
+
+ unsigned int theCheckCount = 0;
+
+ do
+ {
+ doSleep(2000);
+
+ // Check a couple of times, just in case, since
+ // getCounter() is not synchronized...
+ if (theCounter.getCounter() == 0)
{
- theThreadInfo[i].m_threadNumber = i;
- theThreadInfo[i].m_counter = &theCounter;
+ if (theCheckCount == 0)
+ {
+ theClock = clock();
+ }
-#if defined(WIN32)
+ ++theCheckCount;
+ }
+ }
+ while(theCheckCount < 2);
+}
- const unsigned long theThreadID =
- _beginthread(theThreadRoutine, 4096, reinterpret_cast<LPVOID>(&theThreadInfo[i]));
- if (theThreadID == unsigned(-1))
+
+void
+doContinuousThreads(
+ const SynchronizedCounter& theCounter,
+ ThreadInfo theThreadInfo[],
+ long theThreadCount,
+ clock_t& theClock)
+{
+ while(fContinue == true)
+ {
+// doSleep(100);
+
+ if (theCounter.getCounter() < theThreadCount)
+ {
+ for (long i = 0; i < theThreadCount && fContinue == true; ++i)
{
- cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
+ if (theThreadInfo[i].m_done == true)
+ {
+ if (createThread(theThreadInfo[i]) == false)
+ {
+ cerr << endl << "Unable to create thread!" << endl;
+ }
+ else
+ {
+ cout << "Started thread number " << i << "." << endl;
+ }
+ }
}
+ }
+ }
+
+ doCountedThreads(theCounter, theClock);
+}
+
+
+void
+doThreads(
+ long theThreadCount,
+ bool fContinuous)
+{
+ if (fContinuous == true)
+ {
+#if defined(WIN32)
+ SetConsoleCtrlHandler(
+ signalHandler,
+ TRUE);
#elif defined(XALAN_POSIX2_AVAILABLE)
+ signal(SIGINT, signalHandler);
+#else
+#error Unsupported platform!
+#endif
+
+ cout << endl << "Running in continuous mode." << endl;
+ }
+
+ cout << endl << "Starting " << theThreadCount << " threads." << endl;
+
+ XalanArrayAutoPtr<ThreadInfo> theThreadInfo(new ThreadInfo[theThreadCount]);
- pthread_t theThread;
+ try
+ {
+ cout << endl << "Clock before starting threads: " << clock() << endl;
- const int theResult = pthread_create(&theThread, 0, theThreadRoutine, (void*)&theThreadInfo[i]);
+ SynchronizedCounter theCounter;
+
+ long i = 0;
- if (theResult != 0)
+ while (i < theThreadCount && fContinue == true)
+ {
+ theThreadInfo[i].m_threadNumber = i;
+ theThreadInfo[i].m_counter = &theCounter;
+
+ if (createThread(theThreadInfo[i]) == false)
{
- cerr << endl << "Unable to create thread number " << i + 1 << "." << endl;
+ cerr << endl << "Unable to create thread!" << endl;
}
else
{
-#if defined(OS390)
- pthread_detach(&theThread);
-#else
- pthread_detach(theThread);
-#endif
+ cout << "Started thread number " << i << "." << endl;
}
-#else
-#error Unsupported platform!
-#endif
++i;
}
@@ -295,25 +441,18 @@
}
else
{
- unsigned int theCheckCount = 0;
-
- do
+ if (fContinuous == true)
{
- doSleep(2000);
-
- // Check a couple of times, just in case, since
- // getCounter() is not synchronized...
- if (theCounter.getCounter() == 0)
- {
- if (theCheckCount == 0)
- {
- theClock = clock();
- }
-
- ++theCheckCount;
- }
+ doContinuousThreads(
+ theCounter,
+ theThreadInfo.get(),
+ theThreadCount,
+ theClock);
+ }
+ else
+ {
+ doCountedThreads(theCounter, theClock);
}
- while(theCheckCount < 2);
}
cout << endl << "Clock after threads: " << theClock << endl;
@@ -327,6 +466,17 @@
}
+
+void
+Usage()
+{
+ cerr << "Usage: ThreadTest [-c] [count]"
+ << endl
+ << endl;
+}
+
+
+
int
main(
int argc,
@@ -339,63 +489,96 @@
_CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR);
#endif
- if (argc > 2)
+ if (argc > 3)
{
- cerr << "Usage: ThreadTest"
- << endl
- << endl;
+ Usage();
}
else
{
- int threadCount = 60;
+ bool fContinuous = false;
+ int threadCount = 0;
- if (argc == 2)
+ if (argc == 1)
{
- threadCount = atoi(argv[1]);
+ threadCount = 60;
}
-
- try
+ else
{
- // Initialize Xerces...
- XMLPlatformUtils::Initialize();
-
- // Initialize Xalan...
- XalanTransformer::initialize();
+ if (strcmp(argv[1], "-c") == 0)
+ {
+ fContinuous = true;
+ }
+ if (argc == 2)
{
- // Create a XalanTransformer. We won't actually use this to transform --
- // it's just acting likely a factory for the compiled stylesheet and
- // pre-parsed source.
- XalanTransformer theXalanTransformer;
+ if (fContinuous == true)
+ {
+ threadCount = 60;
+ }
+ else
+ {
+ threadCount = atoi(argv[1]);
+ }
+ }
+ else if (argc == 3)
+ {
+ if (fContinuous == true)
+ {
+ threadCount = atoi(argv[2]);
+ }
+ else
+ {
+ Usage();
+ }
+ }
+ }
- const char* const theXSLFileName = "birds.xsl";
+ if (threadCount > 0)
+ {
+ try
+ {
+ // Initialize Xerces...
+ XMLPlatformUtils::Initialize();
- theXalanTransformer.compileStylesheet(theXSLFileName, glbCompiledStylesheet);
- assert(glbCompiledStylesheet != 0);
+ // Initialize Xalan...
+ XalanTransformer::initialize();
- // Compile the XML source document as well. All threads will use
- // this binary representation of the source tree.
- const char* const theXMLFileName = "birds.xml";
+ {
+ // Create a XalanTransformer. We won't actually use this to transform --
+ // it's just acting as a factory for the compiled stylesheet and
+ // pre-parsed source document. Note that we can't let the individual
+ // threads use this as a factory without serializing access to it, but
+ // we can share the stylesheet and source document.
+ XalanTransformer theXalanTransformer;
+
+ const char* const theXSLFileName = "birds.xsl";
+
+ theXalanTransformer.compileStylesheet(theXSLFileName, glbCompiledStylesheet);
+ assert(glbCompiledStylesheet != 0);
+
+ // Compile the XML source document as well. All threads will use
+ // this binary representation of the source tree.
+ const char* const theXMLFileName = "birds.xml";
- theXalanTransformer.parseSource(theXMLFileName, glbParsedSource);
- assert(glbParsedSource != 0);
+ theXalanTransformer.parseSource(theXMLFileName, glbParsedSource);
+ assert(glbParsedSource != 0);
- doThreads(threadCount);
- }
+ doThreads(threadCount, fContinuous);
+ }
- // Terminate Xalan...
- XalanTransformer::terminate();
+ // Terminate Xalan...
+ XalanTransformer::terminate();
- // Terminate Xerces...
- XMLPlatformUtils::Terminate();
- }
- catch(...)
- {
- cerr << "Exception caught!!!"
- << endl
- << endl;
+ // Terminate Xerces...
+ XMLPlatformUtils::Terminate();
+ }
+ catch(...)
+ {
+ cerr << "Exception caught!!!"
+ << endl
+ << endl;
+ }
}
-
}
return 0;
---------------------------------------------------------------------
To unsubscribe, e-mail: xalan-cvs-unsubscribe@xml.apache.org
For additional commands, e-mail: xalan-cvs-help@xml.apache.org