/* **************************************************** * Thread-Test Prototype * * By Arash Partow * * Copyright Arash Partow 2002-2003 * * All Right Reserved * **************************************************** */ #include #include #include #include #include #include #include #include #include "StringTokenizer.h" #include "Thread.h" #include "Mutex.h" const int MAX_THREADS = 700; unsigned int MAX_THREAD_CREATE = 999999999; Mutex* printlnMutex = NULL; void sigproc(int sig); string formatUInt(int val, unsigned int len); bool println(string str); class TestThread: public Thread { public: TestThread(int _id):Thread() { id = _id; }; ~TestThread() { }; string reverseString(string str) { char tempch; /* Reverse the string */ for(unsigned int i=0; i < (str.length()/2); i++) { tempch = str[i]; str[i] = str[str.length()-i-1]; str[str.length()-i-1] = tempch; } return str; }; string palindrome(string str) { string tempStr = str; char tempch; /* Reverse the string */ for(unsigned int i=0; i < (str.length()/2); i++) { tempch = str[i]; str[i] = str[str.length()-i-1]; str[str.length()-i-1] = tempch; } /* Produce palindrome */ str = tempStr + str; return str; }; void execute() { string data = "aaaa:bbbb:ccc:dddd:eee:"; /* Build a really large string */ for (int i=0; i < 100; i++) data += "aaaa:bbbb:ccc:dddd:eee:"; StringTokenizer strtok = StringTokenizer(data,":"); /* Get each token in the string */ while (strtok.hasMoreTokens()) { string token = strtok.nextToken(); token = reverseString(token); token = palindrome(token); } println("Thread ["+formatUInt(id,7)+"] Completed."); }; private: int id; }; typedef vector ThreadList; ThreadList threadList; class GarbageCollector: public Thread { public: GarbageCollector() { keepRunning = true; cleanupComplete = false; }; ~GarbageCollector() { }; void terminate() { keepRunning = false; }; bool terminateState() { return (!keepRunning); }; bool isCleanupComplete() { return cleanupComplete; }; void execute() { unsigned int count = MAX_THREADS; while(keepRunning && (count <= MAX_THREAD_CREATE)) { vector delPos; /* Find all the current dead threads */ for(unsigned int i=0; i < threadList.size(); i++) { if (threadList[i]->getThreadState() == THREAD_DEAD) delPos.push_back(i); } /* Recalibrate deletion positions */ for (unsigned int i=1; i < delPos.size(); i++) { delPos[i]-=i; } for (unsigned int i=0; /*keepRunning &&*/ i < delPos.size(); i++) { count++; /* Erase thread and free-up memory */ if(threadList[delPos[i]] != NULL) delete threadList[delPos[i]]; threadList.erase(threadList.begin()+delPos[i]); /* Create a new thread to take up the just earsed thread */ TestThread* tempThread = new TestThread(count); if (tempThread != NULL) { /* Add new thread to list and print out info about current thread count */ int result = tempThread->start(); if (result) { delete tempThread; } else { //cout << "Created new thread! [" << formatUInt(count,9) << "] Result: " << result << endl; println("Created new thread! ("+formatUInt(keepRunning,1)+") [" + formatUInt(count,9) + "] Result: "+ formatUInt(result,1)); threadList.push_back(tempThread); } } } delPos.clear(); } cout << "*********************************** thread loop terminated, keepRunning = " << keepRunning << "\n"; cout.flush (); /* clean up any remaining threads */ while(threadList.size() > 0) { vector delPos; for(unsigned int i=0; i < threadList.size(); i++) { if (threadList[i]->getThreadState() == THREAD_DEAD) delPos.push_back(i); } /* Recalibrate deletion positions */ for (unsigned int i=1; i < delPos.size(); i++) { delPos[i]-=i; } for (unsigned int i=0; i < delPos.size(); i++) { /* Erase thread and free-up memory */ delete threadList[delPos[i]]; threadList.erase(threadList.begin()+delPos[i]); } delPos.clear(); } if (threadList.size() == 0) cleanupComplete = true; } bool keepRunning; private: bool cleanupComplete; }; GarbageCollector* gc; int main(int argc, char *argv[]) { signal(SIGINT, sigproc); printf ("PID %u\n", GetCurrentProcessId ()); //sleep (10); /* Create Println mutex */ printlnMutex = new Mutex(); /* Setup the garbage thread collector */ gc = new GarbageCollector(); if (argc == 2) { MAX_THREAD_CREATE = atoi(argv[1]); cout << "Maximum threads to be created: " << MAX_THREAD_CREATE << endl; } cout <<"Creating threads" << endl; //sleep (2); /* create the initial MAX_THREAD threads and add them to the thread list */ for(int i=0; /*gc->keepRunning &&*/ i < MAX_THREADS; i++) { TestThread* tempThread = new TestThread(i); threadList.push_back(tempThread); } cout <<"Starting threads" << endl; //sleep (2); /* Have all the newly created threads start. */ for(unsigned int i=0; gc->keepRunning && i < threadList.size(); i++) { threadList[i]->start(); println("Created new thread! [" + formatUInt(i,9) + "]~"); } cout << "Initialize garbage collector" << endl; cout.flush (); //sleep (5); /* Initialise garbage collector */ gc->start(); /* put main thread to sleep */ while(!gc->isCleanupComplete()) sleep(1); cout << endl << "Thread-Test has been completed." << endl; cout << "Have a nice day...." << endl; exit(EXIT_SUCCESS); return 1; } void sigproc(int sig) { signal(SIGINT, sigproc); if (gc != NULL) { /* Don't call terminate if already in terminate state */ if (gc->terminateState()) return; cout << endl << endl << endl << endl << endl << ">>>>>>>>>>>>>>>> Processing shutdown procedure..." << endl << endl << endl << endl << endl; cout.flush(); gc->terminate(); cout << ">>>>>>>>>>>>>>>> Done." << endl; } } string formatUInt(int val, unsigned int len) { string tempStr = ""; char buf[100]; sprintf(buf,"%d",val); tempStr = buf; while(tempStr.length() < len) { tempStr = "0" + tempStr; } return tempStr; } bool println(string str) { printlnMutex->lock(); cout << str << endl; cout.flush(); printlnMutex->unlock(); return true; }